summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ADPF_OWNERS5
-rw-r--r--AconfigFlags.bp5
-rw-r--r--Android.bp1
-rw-r--r--MEMORY_OWNERS1
-rw-r--r--OWNERS3
-rw-r--r--PREUPLOAD_OWNERS2
-rw-r--r--apct-tests/perftests/aconfig/Android.bp (renamed from nfc/tests/Android.bp)39
-rw-r--r--apct-tests/perftests/aconfig/AndroidManifest.xml (renamed from nfc/tests/AndroidManifest.xml)14
-rw-r--r--apct-tests/perftests/aconfig/AndroidTest.xml63
-rw-r--r--apct-tests/perftests/aconfig/OWNERS1
-rw-r--r--apct-tests/perftests/aconfig/src/android/os/flagging/AconfigPackagePerfTest.java138
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java8
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java198
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ConscryptParams.java (renamed from core/tests/coretests/src/android/os/MessageQueueTest.java)31
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java6
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java13
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java17
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java97
-rw-r--r--apct-tests/perftests/core/src/android/content/pm/SystemFeaturesMetadataPerfTest.java67
-rw-r--r--apct-tests/perftests/core/src/android/content/pm/SystemFeaturesPerfTest.java96
-rw-r--r--apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java22
-rw-r--r--apct-tests/perftests/healthconnect/OWNERS2
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java14
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java7
-rw-r--r--api/ApiDocs.bp32
-rw-r--r--api/OWNERS3
-rw-r--r--api/StubLibraries.bp7
-rw-r--r--api/api.go5
-rw-r--r--boot/Android.bp4
-rw-r--r--boot/preloaded-classes3
-rw-r--r--cmds/idmap2/OWNERS1
-rw-r--r--cmds/incidentd/OWNERS1
-rw-r--r--cmds/svc/src/com/android/commands/svc/OWNERS2
-rw-r--r--config/preloaded-classes3
-rw-r--r--config/preloaded-classes-denylist2
-rw-r--r--core/api/current.txt21
-rw-r--r--core/api/module-lib-current.txt13
-rw-r--r--core/api/system-current.txt4
-rw-r--r--core/api/test-current.txt6
-rw-r--r--core/java/android/accessibilityservice/OWNERS5
-rw-r--r--core/java/android/app/ActivityManager.java40
-rw-r--r--core/java/android/app/ActivityThread.java2
-rw-r--r--core/java/android/app/Instrumentation.java1
-rw-r--r--core/java/android/app/KeyguardManager.java3
-rw-r--r--core/java/android/app/LoadedApk.java4
-rw-r--r--core/java/android/app/OWNERS1
-rw-r--r--core/java/android/app/UiModeManager.java4
-rw-r--r--core/java/android/app/admin/flags/flags.aconfig10
-rw-r--r--core/java/android/app/contentsuggestions/OWNERS1
-rw-r--r--core/java/android/app/people/OWNERS3
-rw-r--r--core/java/android/app/wearable/OWNERS1
-rw-r--r--core/java/android/appwidget/OWNERS1
-rw-r--r--core/java/android/content/BroadcastReceiver.java3
-rw-r--r--core/java/android/content/Context.java5
-rw-r--r--core/java/android/content/EventLogTags.logtags2
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/content/integrity/OWNERS1
-rw-r--r--core/java/android/content/pm/PackageManager.java39
-rw-r--r--core/java/android/content/pm/SigningInfo.java16
-rw-r--r--core/java/android/content/pm/SigningInfoException.java4
-rw-r--r--core/java/android/content/pm/SystemFeaturesCache.aidl19
-rw-r--r--core/java/android/content/pm/SystemFeaturesCache.java133
-rw-r--r--core/java/android/content/pm/flags.aconfig14
-rw-r--r--core/java/android/content/pm/parsing/OWNERS2
-rw-r--r--core/java/android/content/pm/permission/OWNERS1
-rw-r--r--core/java/android/gesture/OWNERS1
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java1
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java2
-rw-r--r--core/java/android/hardware/biometrics/flags.aconfig8
-rw-r--r--core/java/android/hardware/usb/OWNERS6
-rw-r--r--core/java/android/metrics/OWNERS1
-rw-r--r--core/java/android/net/flags.aconfig8
-rw-r--r--core/java/android/net/thread/flags.aconfig2
-rw-r--r--core/java/android/os/Debug.java8
-rw-r--r--core/java/android/os/EventLogTags.logtags2
-rw-r--r--core/java/android/os/GraphicsEnvironment.java49
-rw-r--r--core/java/android/os/Handler.java4
-rw-r--r--core/java/android/os/Looper.java85
-rw-r--r--core/java/android/os/OWNERS11
-rw-r--r--core/java/android/os/Process.java16
-rw-r--r--core/java/android/os/ServiceManager.java2
-rw-r--r--core/java/android/os/ServiceManagerNative.java18
-rw-r--r--core/java/android/os/SharedMemory.java18
-rw-r--r--core/java/android/os/flags.aconfig7
-rw-r--r--core/java/android/os/health/OWNERS3
-rw-r--r--core/java/android/permission/PermissionManager.java18
-rw-r--r--core/java/android/preference/OWNERS3
-rw-r--r--core/java/android/print/OWNERS1
-rw-r--r--core/java/android/printservice/OWNERS1
-rw-r--r--core/java/android/security/flags.aconfig10
-rw-r--r--core/java/android/security/net/config/NetworkSecurityTrustManager.java22
-rw-r--r--core/java/android/security/net/config/OWNERS7
-rw-r--r--core/java/android/security/net/config/RootTrustManager.java18
-rw-r--r--core/java/android/speech/OWNERS1
-rw-r--r--core/java/android/text/OWNERS1
-rw-r--r--core/java/android/text/TextUtils.java2
-rw-r--r--core/java/android/util/apk/OWNERS1
-rw-r--r--core/java/android/view/EventLogTags.logtags4
-rw-r--r--core/java/android/view/InsetsSourceControl.java2
-rw-r--r--core/java/android/view/OWNERS1
-rw-r--r--core/java/android/view/PointerIcon.java12
-rw-r--r--core/java/android/view/SurfaceControl.java4
-rw-r--r--core/java/android/view/SurfaceView.java2
-rw-r--r--core/java/android/view/accessibility/OWNERS5
-rw-r--r--core/java/android/view/contentcapture/OWNERS5
-rw-r--r--core/java/android/view/inspector/OWNERS1
-rw-r--r--core/java/android/view/textclassifier/intent/OWNERS2
-rw-r--r--core/java/android/window/OWNERS1
-rw-r--r--core/java/com/android/internal/accessibility/OWNERS5
-rw-r--r--core/java/com/android/internal/app/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/app/IntentForwarderActivity.java15
-rw-r--r--core/java/com/android/internal/app/NfcResolverActivity.java4
-rw-r--r--core/java/com/android/internal/app/OWNERS3
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java7
-rw-r--r--core/java/com/android/internal/config/appcloning/OWNERS1
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java2
-rw-r--r--core/java/com/android/internal/graphics/palette/OWNERS5
-rw-r--r--core/java/com/android/internal/infra/OWNERS6
-rw-r--r--core/java/com/android/internal/logging/EventLogTags.logtags2
-rw-r--r--core/java/com/android/internal/os/BaseCommand.java10
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java4
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java21
-rw-r--r--core/java/com/android/internal/os/flags.aconfig7
-rw-r--r--core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java13
-rw-r--r--core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS2
-rw-r--r--core/java/com/android/internal/util/OWNERS4
-rw-r--r--core/java/com/android/internal/util/function/pooled/OWNERS1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java56
-rw-r--r--core/java/com/android/internal/widget/LockscreenCredential.java25
-rw-r--r--core/java/com/android/internal/widget/remotecompose/OWNERS2
-rw-r--r--core/java/com/android/server/servicewatcher/ServiceWatcher.java6
-rw-r--r--core/java/org/chromium/arc/EventLogTags.logtags2
-rw-r--r--core/jni/Android.bp3
-rw-r--r--core/jni/AndroidRuntime.cpp11
-rw-r--r--core/jni/android_content_res_ObbScanner.cpp1
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp1
-rw-r--r--core/jni/android_graphics_GraphicBuffer.cpp1
-rw-r--r--core/jni/android_graphics_SurfaceTexture.cpp1
-rw-r--r--core/jni/android_hardware_Camera.cpp1
-rw-r--r--core/jni/android_hardware_HardwareBuffer.cpp1
-rw-r--r--core/jni/android_hardware_SensorManager.cpp1
-rw-r--r--core/jni/android_hardware_UsbDeviceConnection.cpp22
-rw-r--r--core/jni/android_hardware_camera2_CameraMetadata.cpp1
-rw-r--r--core/jni/android_hardware_camera2_DngCreator.cpp1
-rw-r--r--core/jni/android_hardware_input_InputWindowHandle.cpp1
-rw-r--r--core/jni/android_media_AudioRecord.cpp1
-rw-r--r--core/jni/android_media_AudioSystem.cpp1
-rw-r--r--core/jni/android_media_AudioTrack.cpp1
-rw-r--r--core/jni/android_media_AudioVolumeGroupCallback.cpp1
-rw-r--r--core/jni/android_media_RemoteDisplay.cpp1
-rw-r--r--core/jni/android_media_ToneGenerator.cpp1
-rw-r--r--core/jni/android_opengl_EGL14.cpp2
-rw-r--r--core/jni/android_os_Debug.cpp12
-rw-r--r--core/jni/android_os_HwBinder.cpp1
-rw-r--r--core/jni/android_os_HwBlob.cpp1
-rw-r--r--core/jni/android_os_HwParcel.cpp1
-rw-r--r--core/jni/android_os_HwRemoteBinder.cpp1
-rw-r--r--core/jni/android_os_MessageQueue.cpp1
-rw-r--r--core/jni/android_tracing_PerfettoDataSource.cpp3
-rw-r--r--core/jni/android_util_Binder.cpp31
-rw-r--r--core/jni/android_util_Process.cpp27
-rw-r--r--core/jni/android_view_CompositionSamplingListener.cpp1
-rw-r--r--core/jni/android_view_DisplayEventReceiver.cpp1
-rw-r--r--core/jni/android_view_InputEventReceiver.cpp1
-rw-r--r--core/jni/android_view_InputEventSender.cpp1
-rw-r--r--core/jni/android_view_InputQueue.cpp1
-rw-r--r--core/jni/android_view_MotionEvent.cpp3
-rw-r--r--core/jni/android_view_Surface.cpp1
-rw-r--r--core/jni/android_view_SurfaceControl.cpp1
-rw-r--r--core/jni/android_view_SurfaceControlActivePictureListener.cpp2
-rw-r--r--core/jni/android_view_SurfaceControlHdrLayerInfoListener.cpp1
-rw-r--r--core/jni/android_view_SurfaceSession.cpp1
-rw-r--r--core/jni/android_view_TextureView.cpp1
-rw-r--r--core/jni/android_view_TunnelModeEnabledListener.cpp1
-rw-r--r--core/jni/android_window_InputTransferToken.cpp3
-rw-r--r--core/jni/android_window_ScreenCapture.cpp1
-rw-r--r--core/jni/android_window_WindowInfosListener.cpp1
-rw-r--r--core/jni/com_android_internal_content_FileSystemUtils.cpp16
-rw-r--r--core/jni/com_android_internal_content_NativeLibraryHelper.cpp5
-rw-r--r--core/jni/com_android_internal_os_Zygote.cpp2
-rw-r--r--core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp18
-rw-r--r--core/jni/com_google_android_gles_jni_EGLImpl.cpp1
-rw-r--r--core/proto/OWNERS2
-rw-r--r--core/proto/android/net/OWNERS1
-rw-r--r--core/proto/android/nfc/OWNERS2
-rw-r--r--core/res/AndroidManifest.xml12
-rw-r--r--core/res/OWNERS1
-rw-r--r--core/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/config.xml12
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/values/symbols.xml5
-rw-r--r--core/res/res/xml/sms_short_codes.xml54
-rw-r--r--core/tests/coretests/src/android/content/pm/OWNERS1
-rw-r--r--core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java116
-rw-r--r--core/tests/coretests/src/android/net/http/OWNERS1
-rw-r--r--core/tests/coretests/src/android/os/BinderProxyTest.java2
-rw-r--r--core/tests/coretests/src/android/os/OWNERS3
-rw-r--r--core/tests/coretests/src/android/security/advancedprotection/OWNERS1
-rw-r--r--core/tests/coretests/src/android/view/MotionEventTest.java25
-rw-r--r--core/tests/featureflagtests/OWNERS3
-rw-r--r--core/tests/overlaytests/host/Android.bp18
-rw-r--r--data/etc/OWNERS2
-rw-r--r--data/etc/platform.xml1
-rw-r--r--data/etc/preinstalled-packages-platform.xml2
-rwxr-xr-xdata/fonts/script/test/test_commandline.py14
-rwxr-xr-xdata/fonts/script/test/test_xml_builder.py20
-rw-r--r--drm/java/android/drm/OWNERS1
-rw-r--r--framework-jarjar-rules.txt3
-rw-r--r--graphics/java/android/graphics/OWNERS4
-rw-r--r--graphics/java/android/graphics/pdf/OWNERS1
-rw-r--r--keystore/java/android/security/GateKeeper.java2
-rw-r--r--keystore/java/android/security/keystore/ArrayUtils.java2
-rw-r--r--keystore/java/android/security/keystore/KeyStoreManager.java6
-rw-r--r--keystore/java/android/security/keystore/Utils.java2
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java11
-rw-r--r--keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java4
-rw-r--r--keystore/java/android/security/keystore2/KeymasterUtils.java46
-rw-r--r--libs/WindowManager/Shell/OWNERS4
-rw-r--r--libs/WindowManager/Shell/multivalentTests/Android.bp1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java19
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS1
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS1
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/OWNERS3
-rw-r--r--libs/androidfw/Android.bp3
-rw-r--r--libs/androidfw/LocaleData.cpp58
-rw-r--r--libs/androidfw/LocaleDataLookup.cpp14964
-rw-r--r--libs/androidfw/LocaleDataTables.cpp2461
-rw-r--r--libs/androidfw/OWNERS2
-rw-r--r--libs/androidfw/include/androidfw/LocaleDataLookup.h73
-rw-r--r--libs/androidfw/tests/LocaleDataLookup_bench.cpp57
-rw-r--r--libs/androidfw/tests/LocaleDataLookup_test.cpp108
-rw-r--r--libs/hwui/Android.bp11
-rw-r--r--libs/hwui/OWNERS3
-rw-r--r--libs/hwui/framework-graphics-ravenwood-policies.txt1
-rw-r--r--libs/hwui/renderthread/CanvasContext.h2
-rw-r--r--libs/hwui/renderthread/HintSessionWrapper.h1
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp5
-rw-r--r--libs/hwui/renderthread/VulkanManager.cpp4
-rw-r--r--libs/protoutil/Android.bp1
-rw-r--r--location/Android.bp1
-rw-r--r--location/java/android/location/Geocoder.java7
-rw-r--r--media/OWNERS1
-rw-r--r--media/TEST_MAPPING5
-rw-r--r--media/java/android/media/ExifInterface.java7
-rw-r--r--media/java/android/media/FadeManagerConfiguration.java1
-rw-r--r--media/java/android/media/Image.java9
-rw-r--r--media/java/android/media/ImageUtils.java9
-rw-r--r--media/java/android/media/MediaCodec.java54
-rw-r--r--media/java/android/media/MediaCodecInfo.java8
-rw-r--r--media/java/android/media/MediaExtractor.java7
-rw-r--r--media/java/android/media/OWNERS4
-rw-r--r--media/java/android/media/musicrecognition/OWNERS1
-rw-r--r--media/java/android/media/session/MediaSessionManager.java65
-rw-r--r--media/java/android/mtp/OWNERS6
-rw-r--r--media/jni/OWNERS6
-rw-r--r--media/jni/android_media_MediaCodec.cpp139
-rw-r--r--media/jni/android_media_Utils.cpp139
-rw-r--r--media/jni/android_mtp_MtpDatabase.cpp4
-rw-r--r--media/tests/MediaRouter/Android.bp2
-rw-r--r--media/tests/MtpTests/OWNERS6
-rw-r--r--mime/Android.bp37
-rw-r--r--mime/jarjar-rules-alt.txt1
-rw-r--r--mime/jarjar-rules.txt2
-rw-r--r--native/android/OWNERS6
-rw-r--r--native/android/tests/system_health/OWNERS1
-rw-r--r--native/graphics/jni/Android.bp7
-rw-r--r--nfc-extras/OWNERS2
-rw-r--r--nfc-non-updatable/Android.bp23
-rw-r--r--nfc-non-updatable/OWNERS2
-rw-r--r--nfc-non-updatable/flags/flags.aconfig (renamed from nfc/java/android/nfc/flags.aconfig)12
-rw-r--r--nfc-non-updatable/java/android/nfc/NfcServiceManager.java (renamed from nfc/java/android/nfc/NfcServiceManager.java)0
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl (renamed from nfc/java/android/nfc/cardemulation/AidGroup.aidl)0
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java (renamed from nfc/java/android/nfc/cardemulation/AidGroup.java)0
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl (renamed from nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl)0
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java (renamed from nfc/java/android/nfc/cardemulation/ApduServiceInfo.java)81
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl (renamed from nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl)0
-rw-r--r--nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java (renamed from nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java)0
-rw-r--r--nfc/Android.bp91
-rw-r--r--nfc/OWNERS2
-rw-r--r--nfc/TEST_MAPPING13
-rw-r--r--nfc/api/current.txt495
-rw-r--r--nfc/api/lint-baseline.txt95
-rw-r--r--nfc/api/module-lib-current.txt10
-rw-r--r--nfc/api/module-lib-lint-baseline.txt93
-rw-r--r--nfc/api/module-lib-removed.txt1
-rw-r--r--nfc/api/removed.txt17
-rw-r--r--nfc/api/system-current.txt261
-rw-r--r--nfc/api/system-lint-baseline.txt119
-rw-r--r--nfc/api/system-removed.txt12
-rw-r--r--nfc/api/test-current.txt1
-rw-r--r--nfc/api/test-removed.txt1
-rw-r--r--nfc/jarjar-rules.txt38
-rw-r--r--nfc/java/android/nfc/ApduList.aidl19
-rw-r--r--nfc/java/android/nfc/ApduList.java68
-rw-r--r--nfc/java/android/nfc/AvailableNfcAntenna.aidl19
-rw-r--r--nfc/java/android/nfc/AvailableNfcAntenna.java121
-rw-r--r--nfc/java/android/nfc/ComponentNameAndUser.aidl19
-rw-r--r--nfc/java/android/nfc/ComponentNameAndUser.java100
-rw-r--r--nfc/java/android/nfc/Constants.java42
-rw-r--r--nfc/java/android/nfc/Entry.aidl18
-rw-r--r--nfc/java/android/nfc/Entry.java85
-rw-r--r--nfc/java/android/nfc/ErrorCodes.java114
-rw-r--r--nfc/java/android/nfc/FormatException.java31
-rw-r--r--nfc/java/android/nfc/INfcAdapter.aidl128
-rw-r--r--nfc/java/android/nfc/INfcAdapterExtras.aidl40
-rw-r--r--nfc/java/android/nfc/INfcCardEmulation.aidl65
-rw-r--r--nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl29
-rw-r--r--nfc/java/android/nfc/INfcDta.aidl34
-rw-r--r--nfc/java/android/nfc/INfcEventListener.aidl16
-rw-r--r--nfc/java/android/nfc/INfcFCardEmulation.aidl36
-rw-r--r--nfc/java/android/nfc/INfcOemExtensionCallback.aidl59
-rw-r--r--nfc/java/android/nfc/INfcTag.aidl50
-rw-r--r--nfc/java/android/nfc/INfcUnlockHandler.aidl12
-rw-r--r--nfc/java/android/nfc/INfcVendorNciCallback.aidl24
-rw-r--r--nfc/java/android/nfc/INfcWlcStateListener.aidl30
-rw-r--r--nfc/java/android/nfc/IT4tNdefNfcee.aidl33
-rw-r--r--nfc/java/android/nfc/ITagRemovedCallback.aidl8
-rw-r--r--nfc/java/android/nfc/NdefMessage.aidl19
-rw-r--r--nfc/java/android/nfc/NdefMessage.java272
-rw-r--r--nfc/java/android/nfc/NdefRecord.aidl19
-rw-r--r--nfc/java/android/nfc/NdefRecord.java1080
-rw-r--r--nfc/java/android/nfc/NfcActivityManager.java403
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java2944
-rw-r--r--nfc/java/android/nfc/NfcAntennaInfo.aidl19
-rw-r--r--nfc/java/android/nfc/NfcAntennaInfo.java117
-rw-r--r--nfc/java/android/nfc/NfcControllerAlwaysOnListener.java136
-rw-r--r--nfc/java/android/nfc/NfcEvent.java56
-rw-r--r--nfc/java/android/nfc/NfcFrameworkInitializer.java71
-rw-r--r--nfc/java/android/nfc/NfcManager.java73
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java1248
-rw-r--r--nfc/java/android/nfc/NfcRoutingTableEntry.java105
-rw-r--r--nfc/java/android/nfc/NfcVendorNciCallbackListener.java115
-rw-r--r--nfc/java/android/nfc/NfcWlcStateListener.java122
-rw-r--r--nfc/java/android/nfc/OemLogItems.aidl19
-rw-r--r--nfc/java/android/nfc/OemLogItems.java333
-rw-r--r--nfc/java/android/nfc/RoutingStatus.java79
-rw-r--r--nfc/java/android/nfc/RoutingTableAidEntry.java48
-rw-r--r--nfc/java/android/nfc/RoutingTableProtocolEntry.java131
-rw-r--r--nfc/java/android/nfc/RoutingTableSystemCodeEntry.java50
-rw-r--r--nfc/java/android/nfc/RoutingTableTechnologyEntry.java108
-rw-r--r--nfc/java/android/nfc/T4tNdefNfcee.java258
-rw-r--r--nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java293
-rw-r--r--nfc/java/android/nfc/Tag.aidl19
-rw-r--r--nfc/java/android/nfc/Tag.java508
-rw-r--r--nfc/java/android/nfc/TagLostException.java29
-rw-r--r--nfc/java/android/nfc/TechListParcel.aidl19
-rw-r--r--nfc/java/android/nfc/TechListParcel.java66
-rw-r--r--nfc/java/android/nfc/TransceiveResult.aidl19
-rw-r--r--nfc/java/android/nfc/TransceiveResult.java93
-rw-r--r--nfc/java/android/nfc/WlcListenerDeviceInfo.aidl19
-rw-r--r--nfc/java/android/nfc/WlcListenerDeviceInfo.java145
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java1494
-rw-r--r--nfc/java/android/nfc/cardemulation/HostApduService.java446
-rw-r--r--nfc/java/android/nfc/cardemulation/HostNfcFService.java279
-rw-r--r--nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java473
-rw-r--r--nfc/java/android/nfc/cardemulation/OWNERS2
-rw-r--r--nfc/java/android/nfc/cardemulation/OffHostApduService.java170
-rw-r--r--nfc/java/android/nfc/cardemulation/PollingFrame.aidl19
-rw-r--r--nfc/java/android/nfc/cardemulation/PollingFrame.java283
-rw-r--r--nfc/java/android/nfc/cardemulation/Utils.java37
-rw-r--r--nfc/java/android/nfc/dta/NfcDta.java167
-rw-r--r--nfc/java/android/nfc/dta/OWNERS2
-rw-r--r--nfc/java/android/nfc/package.html33
-rw-r--r--nfc/java/android/nfc/tech/BasicTagTechnology.java161
-rw-r--r--nfc/java/android/nfc/tech/IsoDep.java209
-rw-r--r--nfc/java/android/nfc/tech/MifareClassic.java655
-rw-r--r--nfc/java/android/nfc/tech/MifareUltralight.java280
-rw-r--r--nfc/java/android/nfc/tech/Ndef.java408
-rw-r--r--nfc/java/android/nfc/tech/NdefFormatable.java182
-rw-r--r--nfc/java/android/nfc/tech/NfcA.java173
-rw-r--r--nfc/java/android/nfc/tech/NfcB.java125
-rw-r--r--nfc/java/android/nfc/tech/NfcBarcode.java130
-rw-r--r--nfc/java/android/nfc/tech/NfcF.java177
-rw-r--r--nfc/java/android/nfc/tech/NfcV.java126
-rw-r--r--nfc/java/android/nfc/tech/OWNERS2
-rw-r--r--nfc/java/android/nfc/tech/TagTechnology.java224
-rw-r--r--nfc/java/android/nfc/tech/package.html13
-rw-r--r--nfc/lint-baseline.xml81
-rw-r--r--nfc/tests/AndroidTest.xml32
-rw-r--r--nfc/tests/src/android/nfc/NdefMessageTest.java59
-rw-r--r--nfc/tests/src/android/nfc/NdefRecordTest.java77
-rw-r--r--nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java199
-rw-r--r--nfc/tests/src/android/nfc/TechListParcelTest.java82
-rw-r--r--omapi/OWNERS2
-rw-r--r--omapi/java/android/se/OWNERS2
-rw-r--r--omapi/java/android/se/omapi/OWNERS2
-rw-r--r--opengl/java/android/opengl/OWNERS1
-rw-r--r--packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java49
-rw-r--r--packages/CredentialManager/tests/robotests/Android.bp1
-rw-r--r--packages/CredentialManager/wear/robotests/Android.bp1
-rw-r--r--packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt2
-rw-r--r--packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt3
-rw-r--r--packages/EasterEgg/src/com/android/egg/landroid/Namer.kt2
-rw-r--r--packages/ExtShared/Android.bp1
-rw-r--r--packages/ExtShared/proguard.proguard4
-rw-r--r--packages/NeuralNetworks/OWNERS3
-rw-r--r--packages/SettingsLib/DataStore/tests/Android.bp1
-rw-r--r--packages/SettingsLib/Ipc/Android.bp2
-rw-r--r--packages/SettingsLib/OWNERS2
-rw-r--r--packages/SettingsLib/Spa/screenshot/robotests/Android.bp1
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/OWNERS3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/qrcode/OWNERS1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS1
-rw-r--r--packages/SettingsLib/tests/robotests/Android.bp6
-rw-r--r--packages/SettingsLib/tests/robotests/fragment/Android.bp4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java23
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java205
-rw-r--r--packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java215
-rw-r--r--packages/Shell/OWNERS7
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java16
-rw-r--r--packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java55
-rw-r--r--packages/Shell/tests/src/com/android/shell/UiBot.java26
-rw-r--r--packages/SystemUI/Android.bp12
-rw-r--r--packages/SystemUI/OWNERS5
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp2
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig2
-rw-r--r--packages/SystemUI/compose/core/tests/AndroidManifest.xml4
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/OWNERS1
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt49
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt2
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt2
-rw-r--r--packages/SystemUI/plugin_core/processor/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt12
-rw-r--r--packages/SystemUI/plugin_core/proguard.flags5
-rw-r--r--packages/SystemUI/proguard_common.flags28
-rw-r--r--packages/SystemUI/res-product/values/strings.xml4
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/OWNERS8
-rw-r--r--packages/SystemUI/src/com/android/systemui/ailabs/OWNERS2
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/OWNERS2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/OWNERS3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/OWNERS3
-rw-r--r--packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/EventLogModule.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt7
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt29
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt43
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/SceneDataSourceKosmos.kt5
-rw-r--r--packages/Vcn/TEST_MAPPING8
-rw-r--r--packages/Vcn/flags/Android.bp14
-rw-r--r--packages/Vcn/framework-b/Android.bp98
-rw-r--r--packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt2
-rw-r--r--packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt5
-rw-r--r--packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java24
-rw-r--r--packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java9
-rw-r--r--packages/Vcn/service-b/Android.bp61
-rw-r--r--packages/Vcn/service-b/service-utils/android/util/LocalLog.java148
-rw-r--r--packages/Vcn/service-b/service-utils/com/android/internal/util/WakeupMessage.java142
-rw-r--r--packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt2
-rw-r--r--packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java4
-rw-r--r--packages/Vcn/service-b/src/com/android/server/VcnManagementService.java9
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java4
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java6
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java9
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java12
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java35
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java6
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java4
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java4
-rw-r--r--packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java4
-rw-r--r--proto/src/metrics_constants/OWNERS2
-rw-r--r--ravenwood/Android.bp52
-rw-r--r--ravenwood/CleanSpec.mk45
-rw-r--r--ravenwood/Framework.bp54
-rw-r--r--ravenwood/TEST_MAPPING1
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java17
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java10
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java229
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java39
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java7
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java329
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java83
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java138
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java68
-rw-r--r--ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java3
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java19
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java2
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java198
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java8
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java63
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java66
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/libcore/util/NonNull.java12
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/libcore/util/Nullable.java12
-rw-r--r--ravenwood/runtime-jni/ravenwood_initializer.cpp77
-rw-r--r--ravenwood/runtime-jni/ravenwood_runtime.cpp6
-rwxr-xr-xravenwood/scripts/add-annotations.sh84
-rwxr-xr-xravenwood/scripts/extract-last-soong-commands.py16
-rwxr-xr-xravenwood/scripts/pta-framework.sh92
-rwxr-xr-xravenwood/scripts/run-ravenwood-tests.sh2
-rw-r--r--ravenwood/tests/bivalenttest/Android.bp1
-rw-r--r--ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt31
-rw-r--r--ravenwood/tests/coretest/Android.bp31
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java82
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java63
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java65
-rw-r--r--ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java13
-rw-r--r--ravenwood/texts/ravenwood-annotation-allowed-classes.txt240
-rw-r--r--ravenwood/texts/ravenwood-build.prop38
-rw-r--r--ravenwood/texts/ravenwood-common-policies.txt11
-rw-r--r--ravenwood/texts/ravenwood-framework-policies.txt98
-rw-r--r--ravenwood/texts/ravenwood-services-jarjar-rules.txt4
-rw-r--r--ravenwood/texts/ravenwood-services-policies.txt21
-rw-r--r--ravenwood/texts/ravenwood-standard-options.txt12
-rw-r--r--ravenwood/tools/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestPartiallyAllowlisted.java (renamed from nfc/java/android/nfc/Placeholder.java)18
-rw-r--r--ravenwood/tools/hoststubgen/framework-policy-override.txt105
-rw-r--r--ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java43
-rw-r--r--ravenwood/tools/hoststubgen/hoststubgen-standard-options.txt5
-rwxr-xr-xravenwood/tools/hoststubgen/invoketest/hoststubgen-invoke-test.sh127
-rwxr-xr-xravenwood/tools/hoststubgen/scripts/dump-jar29
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt26
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt17
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt38
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt143
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt51
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt47
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt15
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt21
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt454
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt10
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt (renamed from ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt)18
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt35
-rw-r--r--ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt104
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt27
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh10
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt533
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt361
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt530
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt533
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt361
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt530
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt10
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/run-test-manually.sh17
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py23
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java8
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java17
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.java67
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java5
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java4
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java17
-rw-r--r--ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java11
-rw-r--r--ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt (renamed from ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt)18
-rw-r--r--ravenwood/tools/ravenhelper/Android.bp37
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt77
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt68
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt225
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt106
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt457
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt66
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt95
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt197
-rw-r--r--ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt419
-rw-r--r--ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt (renamed from nfc/java/android/nfc/IAppCallback.aidl)22
-rw-r--r--ravenwood/tools/ravenizer/Android.bp2
-rw-r--r--services/Android.bp6
-rw-r--r--services/accessibility/OWNERS5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java16
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/OWNERS8
-rw-r--r--services/art-wear-profile2
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java13
-rw-r--r--services/core/Android.bp14
-rw-r--r--services/core/java/com/android/server/BinaryTransparencyService.java2
-rw-r--r--services/core/java/com/android/server/BootReceiver.java7
-rw-r--r--services/core/java/com/android/server/OWNERS1
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java39
-rw-r--r--services/core/java/com/android/server/SystemTimeZone.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java44
-rw-r--r--services/core/java/com/android/server/am/AppBatteryTracker.java12
-rw-r--r--services/core/java/com/android/server/am/ContentProviderHelper.java2
-rw-r--r--services/core/java/com/android/server/am/OWNERS5
-rw-r--r--services/core/java/com/android/server/am/PhantomProcessList.java35
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java1
-rw-r--r--services/core/java/com/android/server/am/UidObserverController.java56
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java18
-rw-r--r--services/core/java/com/android/server/app/GameManagerSettings.java8
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java2
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java31
-rw-r--r--services/core/java/com/android/server/audio/FadeOutManager.java6
-rw-r--r--services/core/java/com/android/server/biometrics/AuthService.java7
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java7
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java21
-rw-r--r--services/core/java/com/android/server/connectivity/Vpn.java12
-rw-r--r--services/core/java/com/android/server/crashrecovery/OWNERS1
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java29
-rw-r--r--services/core/java/com/android/server/display/color/OWNERS3
-rw-r--r--services/core/java/com/android/server/infra/OWNERS1
-rw-r--r--services/core/java/com/android/server/inputmethod/OWNERS1
-rw-r--r--services/core/java/com/android/server/integrity/OWNERS1
-rw-r--r--services/core/java/com/android/server/locales/LocaleManagerService.java2
-rw-r--r--services/core/java/com/android/server/location/fudger/LocationFudger.java11
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java60
-rw-r--r--services/core/java/com/android/server/locksettings/UnifiedProfilePasswordCache.java5
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java4
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS1
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java2
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySessionStorage.java7
-rw-r--r--services/core/java/com/android/server/logcat/OWNERS1
-rw-r--r--services/core/java/com/android/server/media/TEST_MAPPING5
-rw-r--r--services/core/java/com/android/server/memory/OWNERS3
-rw-r--r--services/core/java/com/android/server/memory/ZramMaintenance.java172
-rw-r--r--services/core/java/com/android/server/notification/OWNERS3
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java11
-rw-r--r--services/core/java/com/android/server/pm/OWNERS1
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java8
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java37
-rw-r--r--services/core/java/com/android/server/pm/dex/OWNERS1
-rw-r--r--services/core/java/com/android/server/policy/AppOpsPolicy.java4
-rw-r--r--services/core/java/com/android/server/power/OWNERS2
-rw-r--r--services/core/java/com/android/server/power/ShutdownCheckPoints.java11
-rw-r--r--services/core/java/com/android/server/power/stats/BatteryStatsImpl.java33
-rw-r--r--services/core/java/com/android/server/power/stats/OWNERS3
-rw-r--r--services/core/java/com/android/server/powerstats/PowerStatsLogger.java10
-rw-r--r--services/core/java/com/android/server/rollback/RollbackStore.java8
-rw-r--r--services/core/java/com/android/server/security/OWNERS1
-rw-r--r--services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java13
-rw-r--r--services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java88
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java2
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java11
-rw-r--r--services/core/java/com/android/server/uri/OWNERS1
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java3
-rw-r--r--services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java6
-rw-r--r--services/core/java/com/android/server/wm/CameraStateMonitor.java6
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java24
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java6
-rw-r--r--services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java6
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java2
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java2
-rw-r--r--services/core/java/com/android/server/wm/OWNERS2
-rw-r--r--services/core/java/com/android/server/wm/PinnedTaskController.java31
-rw-r--r--services/core/java/com/android/server/wm/RecentTasks.java6
-rw-r--r--services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java5
-rw-r--r--services/core/java/com/android/server/wm/SnapshotPersistQueue.java8
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskPersister.java6
-rw-r--r--services/core/java/com/android/server/wm/Transition.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java17
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java3
-rw-r--r--services/core/jni/Android.bp9
-rw-r--r--services/core/jni/BroadcastRadio/OWNERS1
-rw-r--r--services/core/jni/com_android_server_am_PhantomProcessList.cpp49
-rw-r--r--services/core/jni/onload.cpp2
-rw-r--r--services/core/jni/stats/OWNERS2
-rw-r--r--services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp2
-rw-r--r--services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig2
-rw-r--r--services/incremental/IncrementalService.cpp2
-rw-r--r--services/java/com/android/server/SystemServer.java63
-rw-r--r--services/java/com/android/server/flags.aconfig7
-rw-r--r--services/musicrecognition/OWNERS1
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt13
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java148
-rw-r--r--services/profcollect/src/com/android/server/profcollect/Utils.java56
-rw-r--r--services/proguard.flags5
-rw-r--r--services/robotests/Android.bp1
-rw-r--r--services/robotests/backup/Android.bp1
-rw-r--r--services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt3
-rw-r--r--services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java24
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java64
-rw-r--r--services/tests/mockingservicestests/jni/Android.bp1
-rw-r--r--services/tests/mockingservicestests/jni/onload.cpp2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java12
-rw-r--r--services/tests/ondeviceintelligencetests/OWNERS1
-rw-r--r--services/tests/servicestests/Android.bp3
-rw-r--r--services/tests/servicestests/src/com/android/server/OWNERS1
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/OWNERS5
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/OWNERS6
-rw-r--r--services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/media/projection/OWNERS1
-rw-r--r--services/tests/servicestests/src/com/android/server/memory/OWNERS3
-rw-r--r--services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt154
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java216
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java59
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/OWNERS1
-rw-r--r--services/usb/OWNERS6
-rw-r--r--services/usb/java/com/android/server/usb/UsbPortManager.java11
-rw-r--r--startop/OWNERS1
-rw-r--r--telecomm/java/android/telecom/OWNERS1
-rw-r--r--tests/Codegen/OWNERS1
-rw-r--r--tests/CompanionDeviceMultiDeviceTests/client/Android.bp1
-rw-r--r--tests/CompanionDeviceMultiDeviceTests/host/Android.bp9
-rw-r--r--tests/EnforcePermission/OWNERS1
-rw-r--r--tests/Input/Android.bp3
-rw-r--r--tests/InputScreenshotTest/robotests/Android.bp1
-rw-r--r--tests/SharedLibrary/lib/Android.bp1
-rw-r--r--tests/SharedLibrary/lib/proguard.proguard4
-rw-r--r--tests/SoundTriggerTestApp/OWNERS1
-rw-r--r--tests/vcn/Android.bp11
-rw-r--r--tests/vcn/AndroidManifest.xml5
-rw-r--r--tests/vcn/AndroidTest.xml10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java13
-rw-r--r--tests/vcn/java/android/net/vcn/VcnConfigTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnManagerTest.java12
-rw-r--r--tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java12
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java12
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/VcnUtilsTest.java12
-rw-r--r--tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java13
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java9
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java10
-rw-r--r--tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java10
-rw-r--r--tests/vcn/java/com/android/server/VcnManagementServiceTest.java27
-rw-r--r--tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java12
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java12
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java10
-rw-r--r--tests/vcn/java/com/android/server/vcn/VcnTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java16
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java12
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java11
-rw-r--r--tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java11
-rwxr-xr-xtools/aosp/upload_aosp.sh116
-rw-r--r--tools/codegen/OWNERS1
-rw-r--r--tools/hiddenapi/OWNERS1
-rw-r--r--tools/lint/OWNERS1
-rw-r--r--tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt2
-rw-r--r--tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt107
-rw-r--r--tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt173
-rwxr-xr-xtools/localedata/extract_icu_data.py151
-rw-r--r--tools/processors/view_inspector/OWNERS3
-rw-r--r--tools/systemfeatures/Android.bp69
-rw-r--r--tools/systemfeatures/README.md108
-rw-r--r--tools/systemfeatures/errorprone/java/com/android/systemfeatures/errorprone/RoSystemFeaturesChecker.java119
-rw-r--r--tools/systemfeatures/errorprone/tests/java/com/android/systemfeatures/errorprone/RoSystemFeaturesCheckerTest.java123
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt60
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt80
-rw-r--r--tools/systemfeatures/tests/golden/RoFeatures.java.gen2
-rw-r--r--tools/systemfeatures/tests/golden/RoNoFeatures.java.gen2
-rw-r--r--tools/systemfeatures/tests/golden/RwFeatures.java.gen2
-rw-r--r--tools/systemfeatures/tests/golden/RwNoFeatures.java.gen2
-rw-r--r--tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java22
-rw-r--r--tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java4
-rw-r--r--tools/systemfeatures/tests/src/android/content/Context.java (renamed from tools/systemfeatures/tests/src/Context.java)0
-rw-r--r--tools/systemfeatures/tests/src/android/content/pm/FeatureInfo.java (renamed from tools/systemfeatures/tests/src/FeatureInfo.java)0
-rw-r--r--tools/systemfeatures/tests/src/android/content/pm/PackageManager.java (renamed from tools/systemfeatures/tests/src/PackageManager.java)8
-rw-r--r--tools/systemfeatures/tests/src/android/util/ArrayMap.java (renamed from tools/systemfeatures/tests/src/ArrayMap.java)0
-rw-r--r--tools/systemfeatures/tests/src/android/util/ArraySet.java (renamed from nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl)18
-rw-r--r--wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS1
786 files changed, 29039 insertions, 24062 deletions
diff --git a/ADPF_OWNERS b/ADPF_OWNERS
index bcdc33825a13..c7ff4640b185 100644
--- a/ADPF_OWNERS
+++ b/ADPF_OWNERS
@@ -1,4 +1,5 @@
-sumir@google.com
+adyabr@google.com
chingtangyu@google.com
-xwxw@google.com
mattbuckley@google.com
+sumir@google.com
+xwxw@google.com \ No newline at end of file
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 45e33ce4b6e9..7453cbffe4d9 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -345,7 +345,7 @@ aconfig_declarations {
name: "android.nfc.flags-aconfig",
package: "android.nfc",
container: "system",
- srcs: ["nfc/java/android/nfc/*.aconfig"],
+ srcs: ["nfc-non-updatable/flags/*.aconfig"],
}
cc_aconfig_library {
@@ -401,6 +401,7 @@ java_aconfig_library {
min_sdk_version: "30",
apex_available: [
"//apex_available:platform",
+ "com.android.tethering",
"com.android.wifi",
],
defaults: ["framework-minus-apex-aconfig-java-defaults"],
@@ -464,7 +465,7 @@ java_aconfig_library {
"//apex_available:platform",
"com.android.art",
"com.android.art.debug",
- "com.android.btservices",
+ "com.android.bt",
"com.android.mediaprovider",
"com.android.permission",
],
diff --git a/Android.bp b/Android.bp
index 529da53e58f7..a47a272fbc96 100644
--- a/Android.bp
+++ b/Android.bp
@@ -530,6 +530,7 @@ java_library {
],
},
jarjar_prefix: "com.android.internal.hidden_from_bootclasspath",
+ jarjar_shards: "10",
}
java_library {
diff --git a/MEMORY_OWNERS b/MEMORY_OWNERS
index 89ce5140d8ea..12aa2951bbc9 100644
--- a/MEMORY_OWNERS
+++ b/MEMORY_OWNERS
@@ -2,5 +2,4 @@ surenb@google.com
tjmercier@google.com
kaleshsingh@google.com
jyescas@google.com
-carlosgalo@google.com
jji@google.com
diff --git a/OWNERS b/OWNERS
index d0a634e529c5..058ea3619a58 100644
--- a/OWNERS
+++ b/OWNERS
@@ -34,6 +34,8 @@ per-file TestProtoLibraries.bp = file:platform/tools/tradefederation:/OWNERS
per-file *ravenwood* = file:ravenwood/OWNERS
per-file *Ravenwood* = file:ravenwood/OWNERS
+per-file PREUPLOAD.cfg = file:/PREUPLOAD_OWNERS
+
per-file INPUT_OWNERS = file:/INPUT_OWNERS
per-file ZYGOTE_OWNERS = file:/ZYGOTE_OWNERS
per-file SQLITE_OWNERS = file:/SQLITE_OWNERS
@@ -48,3 +50,4 @@ per-file BROADCASTS_OWNERS = file:/BROADCASTS_OWNERS
per-file ADPF_OWNERS = file:/ADPF_OWNERS
per-file GAME_MANAGER_OWNERS = file:/GAME_MANAGER_OWNERS
per-file SDK_OWNERS = file:/SDK_OWNERS
+per-file PREUPLOAD_OWNERS = file:/PREUPLOAD_OWNERS
diff --git a/PREUPLOAD_OWNERS b/PREUPLOAD_OWNERS
new file mode 100644
index 000000000000..ece4d3e5e268
--- /dev/null
+++ b/PREUPLOAD_OWNERS
@@ -0,0 +1,2 @@
+roosa@google.com
+gsennton@google.com
diff --git a/nfc/tests/Android.bp b/apct-tests/perftests/aconfig/Android.bp
index b6090e853158..715923de1eb7 100644
--- a/nfc/tests/Android.bp
+++ b/apct-tests/perftests/aconfig/Android.bp
@@ -1,4 +1,4 @@
-// Copyright 2021 The Android Open Source Project
+// Copyright (C) 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
// limitations under the License.
package {
- default_team: "trendy_team_fwk_nfc",
+ default_team: "trendy_team_android_core_experiments",
// 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"
@@ -23,38 +23,17 @@ package {
}
android_test {
- name: "NfcManagerTests",
+ name: "AconfigPerfTests",
+ srcs: ["src/**/*.java"],
static_libs: [
- "androidx.test.core",
+ "aconfig_device_paths_java_util",
"androidx.test.rules",
- "androidx.test.runner",
- "androidx.test.ext.junit",
- "framework-nfc.impl",
- "mockito-target-extended-minus-junit4",
- "frameworks-base-testutils",
+ "apct-perftests-utils",
+ "collector-device-lib",
"truth",
- "androidx.annotation_annotation",
- "androidx.appcompat_appcompat",
- "flag-junit",
- "platform-test-annotations",
- "testables",
- ],
- libs: [
- "android.test.base.stubs.system",
- "android.test.mock.stubs.system",
- "android.test.runner.stubs.system",
- ],
- jni_libs: [
- // Required for ExtendedMockito
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
],
- srcs: ["src/**/*.java"],
platform_apis: true,
certificate: "platform",
- test_suites: [
- "device-tests",
- "mts-nfc",
- ],
- min_sdk_version: "35", // Should be 36 later.
+ test_suites: ["device-tests"],
+ data: [":perfetto_artifacts"],
}
diff --git a/nfc/tests/AndroidManifest.xml b/apct-tests/perftests/aconfig/AndroidManifest.xml
index 95646720d3d5..e9d7c176303f 100644
--- a/nfc/tests/AndroidManifest.xml
+++ b/apct-tests/perftests/aconfig/AndroidManifest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Android Open Source Project
+<!-- Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,17 +15,13 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.nfc">
+ package="com.android.perftests.aconfig">
- <application android:debuggable="true">
+ <application>
<uses-library android:name="android.test.runner" />
</application>
- <!-- This is a self-instrumenting test package. -->
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.nfc"
- android:label="NFC Manager Tests">
- </instrumentation>
-
-</manifest>
+ android:targetPackage="com.android.perftests.aconfig"/>
+</manifest> \ No newline at end of file
diff --git a/apct-tests/perftests/aconfig/AndroidTest.xml b/apct-tests/perftests/aconfig/AndroidTest.xml
new file mode 100644
index 000000000000..036e0310def2
--- /dev/null
+++ b/apct-tests/perftests/aconfig/AndroidTest.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs AconfigPerfTests metric instrumentation.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-metric-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="AconfigPerfTests.apk" />
+ </target_preparer>
+
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
+
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
+ </metrics_collector>
+
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false" />
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.perftests.aconfig" />
+ <option name="hidden-api-checks" value="false"/>
+
+ <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+ <option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+ <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ </test>
+</configuration> \ No newline at end of file
diff --git a/apct-tests/perftests/aconfig/OWNERS b/apct-tests/perftests/aconfig/OWNERS
new file mode 100644
index 000000000000..2202076593fb
--- /dev/null
+++ b/apct-tests/perftests/aconfig/OWNERS
@@ -0,0 +1 @@
+file:platform/packages/modules/ConfigInfrastructure:/OWNERS \ No newline at end of file
diff --git a/apct-tests/perftests/aconfig/src/android/os/flagging/AconfigPackagePerfTest.java b/apct-tests/perftests/aconfig/src/android/os/flagging/AconfigPackagePerfTest.java
new file mode 100644
index 000000000000..e790874ebc61
--- /dev/null
+++ b/apct-tests/perftests/aconfig/src/android/os/flagging/AconfigPackagePerfTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.flagging;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.aconfig.DeviceProtosTestUtil;
+import android.aconfig.nano.Aconfig.parsed_flag;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(Parameterized.class)
+public class AconfigPackagePerfTest {
+
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Parameterized.Parameters(name = "isPlatform_{0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {{false}, {true}});
+ }
+
+ private static final Set<String> PLATFORM_CONTAINERS = Set.of("system", "vendor", "product");
+ private static List<parsed_flag> sFlags;
+
+ @BeforeClass
+ public static void init() {
+ try {
+ sFlags = DeviceProtosTestUtil.loadAndParseFlagProtos();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // if this variable is true, then the test query flags from system/product/vendor
+ // if this variable is false, then the test query flags from updatable partitions
+ @Parameterized.Parameter(0)
+ public boolean mIsPlatform;
+
+ @Test
+ public void timeAconfigPackageLoadOnePackage() {
+ String packageName = "";
+ for (parsed_flag flag : sFlags) {
+ if (mIsPlatform == PLATFORM_CONTAINERS.contains(flag.container)) {
+ packageName = flag.package_;
+ break;
+ }
+ }
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ AconfigPackage.load(packageName);
+ }
+ }
+
+ @Test
+ public void timeAconfigPackageLoadMultiplePackages() {
+ // load num packages
+ int packageNum = 25;
+ Set<String> packageSet = new HashSet<>();
+ for (parsed_flag flag : sFlags) {
+ if (mIsPlatform == PLATFORM_CONTAINERS.contains(flag.container)) {
+ packageSet.add(flag.package_);
+ }
+ if (packageSet.size() >= packageNum) {
+ break;
+ }
+ }
+ List<String> packageList = new ArrayList(packageSet);
+ assertThat(packageList.size()).isAtLeast(packageNum);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ for (int i = 0; state.keepRunning(); i++) {
+ AconfigPackage.load(packageList.get(i % packageNum));
+ }
+ }
+
+ @Test
+ public void timeAconfigPackageGetBooleanFlagValue() {
+ // get one package contains num of flags
+ int flagNum = 20;
+ List<parsed_flag> l = findNumFlagsInSamePackage(flagNum, mIsPlatform);
+ List<String> flagName = new ArrayList<>();
+ String packageName = l.get(0).package_;
+ for (parsed_flag flag : l) {
+ flagName.add(flag.name);
+ }
+ assertThat(flagName.size()).isAtLeast(flagNum);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ AconfigPackage ap = AconfigPackage.load(packageName);
+ for (int i = 0; state.keepRunning(); i++) {
+ ap.getBooleanFlagValue(flagName.get(i % flagNum), false);
+ }
+ }
+
+ private static List<parsed_flag> findNumFlagsInSamePackage(int num, boolean isPlatform) {
+ Map<String, List<parsed_flag>> packageToFlag = new HashMap<>();
+ List<parsed_flag> ret = new ArrayList<parsed_flag>();
+ for (parsed_flag flag : sFlags) {
+ if (isPlatform == PLATFORM_CONTAINERS.contains(flag.container)) {
+ ret =
+ packageToFlag.computeIfAbsent(
+ flag.package_, k -> new ArrayList<parsed_flag>());
+ ret.add(flag);
+ if (ret.size() >= num) {
+ break;
+ }
+ }
+ }
+ return ret;
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
index 1a7258a802df..4c3416523b99 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientEndpoint.java
@@ -20,6 +20,7 @@ import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.AutoCloseable;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.channels.ClosedChannelException;
@@ -33,7 +34,7 @@ import org.conscrypt.ChannelType;
* Client-side endpoint. Provides basic services for sending/receiving messages from the client
* socket.
*/
-final class ClientEndpoint {
+final class ClientEndpoint implements AutoCloseable {
private final SSLSocket socket;
private InputStream input;
private OutputStream output;
@@ -56,6 +57,11 @@ final class ClientEndpoint {
}
}
+ @Override
+ public void close() {
+ stop();
+ }
+
void stop() {
try {
socket.close();
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
index f20b1706129b..bcc0a3b70dfa 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
@@ -44,24 +44,21 @@ import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import org.junit.Rule;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import android.conscrypt.ServerEndpoint.MessageProcessor;
-/**
- * Benchmark for comparing performance of server socket implementations.
- */
+/** Benchmark for comparing performance of server socket implementations. */
@RunWith(JUnitParamsRunner.class)
@LargeTest
public final class ClientSocketPerfTest {
@Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
- /**
- * Provider for the test configuration
- */
+ /** Provider for the test configuration */
private class Config {
EndpointFactory a_clientFactory;
EndpointFactory b_serverFactory;
@@ -69,19 +66,22 @@ public final class ClientSocketPerfTest {
String d_cipher;
ChannelType e_channelType;
PerfTestProtocol f_protocol;
- Config(EndpointFactory clientFactory,
- EndpointFactory serverFactory,
- int messageSize,
- String cipher,
- ChannelType channelType,
- PerfTestProtocol protocol) {
- a_clientFactory = clientFactory;
- b_serverFactory = serverFactory;
- c_messageSize = messageSize;
- d_cipher = cipher;
- e_channelType = channelType;
- f_protocol = protocol;
+
+ Config(
+ EndpointFactory clientFactory,
+ EndpointFactory serverFactory,
+ int messageSize,
+ String cipher,
+ ChannelType channelType,
+ PerfTestProtocol protocol) {
+ a_clientFactory = clientFactory;
+ b_serverFactory = serverFactory;
+ c_messageSize = messageSize;
+ d_cipher = cipher;
+ e_channelType = channelType;
+ f_protocol = protocol;
}
+
public EndpointFactory clientFactory() {
return a_clientFactory;
}
@@ -112,23 +112,27 @@ public final class ClientSocketPerfTest {
for (EndpointFactory endpointFactory : EndpointFactory.values()) {
for (ChannelType channelType : ChannelType.values()) {
for (PerfTestProtocol protocol : PerfTestProtocol.values()) {
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 64, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- channelType, protocol)});
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 512, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- channelType, protocol)});
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 4096, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- channelType, protocol)});
+ for (int messageSize : ConscryptParams.messageSizes) {
+ for (String cipher : ConscryptParams.ciphers) {
+ params.add(
+ new Object[] {
+ new Config(
+ endpointFactory,
+ endpointFactory,
+ messageSize,
+ cipher,
+ channelType,
+ protocol)
+ });
+ }
+ }
}
}
}
return params;
}
- private ClientEndpoint client;
- private ServerEndpoint server;
+ private SocketPair socketPair = new SocketPair();
private byte[] message;
private ExecutorService executor;
private Future<?> sendingFuture;
@@ -137,46 +141,78 @@ public final class ClientSocketPerfTest {
private static final AtomicLong bytesCounter = new AtomicLong();
private AtomicBoolean recording = new AtomicBoolean();
+ private static class SocketPair implements AutoCloseable {
+ public ClientEndpoint client;
+ public ServerEndpoint server;
+
+ SocketPair() {
+ client = null;
+ server = null;
+ }
+
+ @Override
+ public void close() {
+ if (client != null) {
+ client.stop();
+ }
+ if (server != null) {
+ server.stop();
+ }
+ }
+ }
+
private void setup(Config config) throws Exception {
message = newTextMessage(512);
// Always use the same server for consistency across the benchmarks.
- server = config.serverFactory().newServer(
- config.messageSize(), config.protocol().getProtocols(),
- ciphers(config));
-
- server.setMessageProcessor(new ServerEndpoint.MessageProcessor() {
- @Override
- public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
- if (recording.get()) {
- // Server received a message, increment the count.
- bytesCounter.addAndGet(numBytes);
- }
- }
- });
- Future<?> connectedFuture = server.start();
+ socketPair.server =
+ config.serverFactory()
+ .newServer(
+ config.messageSize(),
+ config.protocol().getProtocols(),
+ ciphers(config));
+ socketPair.server.init();
+
+ socketPair.server.setMessageProcessor(
+ new ServerEndpoint.MessageProcessor() {
+ @Override
+ public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
+ if (recording.get()) {
+ // Server received a message, increment the count.
+ bytesCounter.addAndGet(numBytes);
+ }
+ }
+ });
+ Future<?> connectedFuture = socketPair.server.start();
- client = config.clientFactory().newClient(
- config.channelType(), server.port(), config.protocol().getProtocols(), ciphers(config));
- client.start();
+ socketPair.client =
+ config.clientFactory()
+ .newClient(
+ config.channelType(),
+ socketPair.server.port(),
+ config.protocol().getProtocols(),
+ ciphers(config));
+ socketPair.client.start();
// Wait for the initial connection to complete.
connectedFuture.get(5, TimeUnit.SECONDS);
executor = Executors.newSingleThreadExecutor();
- sendingFuture = executor.submit(new Runnable() {
- @Override
- public void run() {
- try {
- Thread thread = Thread.currentThread();
- while (!stopping && !thread.isInterrupted()) {
- client.sendMessage(message);
- }
- } finally {
- client.flush();
- }
- }
- });
+ sendingFuture =
+ executor.submit(
+ new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread thread = Thread.currentThread();
+ while (!stopping && !thread.isInterrupted()) {
+ socketPair.client.sendMessage(message);
+ }
+ } finally {
+ socketPair.client.flush();
+ }
+ }
+ });
}
void close() throws Exception {
@@ -185,29 +221,37 @@ public final class ClientSocketPerfTest {
// Wait for the sending thread to stop.
sendingFuture.get(5, TimeUnit.SECONDS);
- client.stop();
- server.stop();
- executor.shutdown();
- executor.awaitTermination(5, TimeUnit.SECONDS);
+ if (socketPair != null) {
+ socketPair.close();
+ }
+ if (executor != null) {
+ executor.shutdown();
+ executor.awaitTermination(5, TimeUnit.SECONDS);
+ }
}
- /**
- * Simple benchmark for the amount of time to send a given number of messages
- */
+ /** Simple benchmark for the amount of time to send a given number of messages */
@Test
@Parameters(method = "getParams")
public void time(Config config) throws Exception {
- reset();
- setup(config);
- recording.set(true);
-
- BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
- while (state.keepRunning()) {
- while (bytesCounter.get() < config.messageSize()) {
- }
- bytesCounter.set(0);
+ try {
+ reset();
+ setup(config);
+ recording.set(true);
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ while (bytesCounter.get() < config.messageSize()) {}
+ bytesCounter.set(0);
+ }
+ recording.set(false);
+ } finally {
+ close();
}
- recording.set(false);
+ }
+
+ @After
+ public void tearDown() throws Exception {
close();
}
@@ -219,4 +263,4 @@ public final class ClientSocketPerfTest {
private String[] ciphers(Config config) {
return new String[] {config.cipher()};
}
-} \ No newline at end of file
+}
diff --git a/core/tests/coretests/src/android/os/MessageQueueTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ConscryptParams.java
index 30f6636766d5..e5131b82cd8d 100644
--- a/core/tests/coretests/src/android/os/MessageQueueTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ConscryptParams.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,19 +14,22 @@
* limitations under the License.
*/
-package android.os;
+package android.conscrypt;
-import android.platform.test.ravenwood.RavenwoodRule;
+import java.util.List;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-import androidx.test.filters.Suppress;
+public class ConscryptParams {
+ public static final List<String> ciphers = List.of(
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
+ );
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class MessageQueueTest {
-
-}
+ public static final List<Integer> messageSizes = List.of(
+ 64,
+ 512,
+ 4096
+ );
+} \ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java
index cd0ac96b41de..341d8e608c0c 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineHandshakePerfTest.java
@@ -87,11 +87,13 @@ public final class EngineHandshakePerfTest {
}
}
+
public Collection getParams() {
final List<Object[]> params = new ArrayList<>();
for (BufferType bufferType : BufferType.values()) {
- params.add(new Object[] {new Config(bufferType,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 100)});
+ for (String cipher : ConscryptParams.ciphers) {
+ params.add(new Object[] {new Config(bufferType, cipher, 100)});
+ }
}
return params;
}
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java
index 1fee2183b11e..23b642ee9537 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EngineWrapPerfTest.java
@@ -37,10 +37,10 @@ import static org.conscrypt.TestUtils.newTextMessage;
import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer;
-import java.util.Locale;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Locale;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
@@ -94,12 +94,11 @@ public final class EngineWrapPerfTest {
public Collection getParams() {
final List<Object[]> params = new ArrayList<>();
for (BufferType bufferType : BufferType.values()) {
- params.add(new Object[] {new Config(bufferType, 64,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
- params.add(new Object[] {new Config(bufferType, 512,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
- params.add(new Object[] {new Config(bufferType, 4096,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")});
+ for (int messageSize : ConscryptParams.messageSizes) {
+ for (String cipher : ConscryptParams.ciphers) {
+ params.add(new Object[] {new Config(bufferType, messageSize, cipher)});
+ }
+ }
}
return params;
}
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
index 1e4f12460936..83eaaa1155e4 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
@@ -16,10 +16,14 @@
package android.conscrypt;
+import static org.conscrypt.TestUtils.getLoopbackAddress;
+
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.AutoCloseable;
+import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketException;
import java.nio.channels.ClosedChannelException;
@@ -37,7 +41,7 @@ import javax.net.ssl.SSLSocketFactory;
/**
* A simple socket-based test server.
*/
-final class ServerEndpoint {
+final class ServerEndpoint implements AutoCloseable {
/**
* A processor for receipt of a single message.
*/
@@ -82,7 +86,11 @@ final class ServerEndpoint {
this.messageSize = messageSize;
this.protocols = protocols;
this.cipherSuites = cipherSuites;
- buffer = new byte[messageSize];
+ this.buffer = new byte[messageSize];
+ }
+
+ void init() throws IOException {
+ serverSocket.bind(new InetSocketAddress(getLoopbackAddress(), 0));
}
void setMessageProcessor(MessageProcessor messageProcessor) {
@@ -94,6 +102,11 @@ final class ServerEndpoint {
return executor.submit(new AcceptTask());
}
+ @Override
+ public void close() {
+ stop();
+ }
+
void stop() {
try {
stopping = true;
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
index af3c405eab82..343bb1294af7 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
@@ -44,6 +44,7 @@ import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Rule;
+import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -101,28 +102,44 @@ public final class ServerSocketPerfTest {
final List<Object[]> params = new ArrayList<>();
for (EndpointFactory endpointFactory : EndpointFactory.values()) {
for (ChannelType channelType : ChannelType.values()) {
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 64,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 512,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
- params.add(new Object[] {new Config(endpointFactory,
- endpointFactory, 4096,
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", channelType)});
+ for (int messageSize : ConscryptParams.messageSizes) {
+ for (String cipher : ConscryptParams.ciphers) {
+ params.add(new Object[] {new Config(endpointFactory,
+ endpointFactory, messageSize, cipher, channelType)});
+ }
+ }
}
}
return params;
}
- private ClientEndpoint client;
- private ServerEndpoint server;
+ private SocketPair socketPair = new SocketPair();
private ExecutorService executor;
private Future<?> receivingFuture;
private volatile boolean stopping;
private static final AtomicLong bytesCounter = new AtomicLong();
private AtomicBoolean recording = new AtomicBoolean();
+ private static class SocketPair implements AutoCloseable {
+ public ClientEndpoint client;
+ public ServerEndpoint server;
+
+ SocketPair() {
+ client = null;
+ server = null;
+ }
+
+ @Override
+ public void close() {
+ if (client != null) {
+ client.stop();
+ }
+ if (server != null) {
+ server.stop();
+ }
+ }
+ }
+
private void setup(final Config config) throws Exception {
recording.set(false);
@@ -130,9 +147,10 @@ public final class ServerSocketPerfTest {
final ChannelType channelType = config.channelType();
- server = config.serverFactory().newServer(config.messageSize(),
+ socketPair.server = config.serverFactory().newServer(config.messageSize(),
new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
- server.setMessageProcessor(new MessageProcessor() {
+ socketPair.server.init();
+ socketPair.server.setMessageProcessor(new MessageProcessor() {
@Override
public void processMessage(byte[] inMessage, int numBytes, OutputStream os) {
try {
@@ -151,20 +169,20 @@ public final class ServerSocketPerfTest {
}
});
- Future<?> connectedFuture = server.start();
+ Future<?> connectedFuture = socketPair.server.start();
// Always use the same client for consistency across the benchmarks.
- client = config.clientFactory().newClient(
- ChannelType.CHANNEL, server.port(),
+ socketPair.client = config.clientFactory().newClient(
+ ChannelType.CHANNEL, socketPair.server.port(),
new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
- client.start();
+ socketPair.client.start();
// Wait for the initial connection to complete.
connectedFuture.get(5, TimeUnit.SECONDS);
// Start the server-side streaming by sending a message to the server.
- client.sendMessage(message);
- client.flush();
+ socketPair.client.sendMessage(message);
+ socketPair.client.flush();
executor = Executors.newSingleThreadExecutor();
receivingFuture = executor.submit(new Runnable() {
@@ -173,7 +191,7 @@ public final class ServerSocketPerfTest {
Thread thread = Thread.currentThread();
byte[] buffer = new byte[config.messageSize()];
while (!stopping && !thread.isInterrupted()) {
- int numBytes = client.readMessage(buffer);
+ int numBytes = socketPair.client.readMessage(buffer);
if (numBytes < 0) {
return;
}
@@ -191,25 +209,38 @@ public final class ServerSocketPerfTest {
void close() throws Exception {
stopping = true;
// Stop and wait for sending to complete.
- server.stop();
- client.stop();
- executor.shutdown();
- receivingFuture.get(5, TimeUnit.SECONDS);
- executor.awaitTermination(5, TimeUnit.SECONDS);
+ if (socketPair != null) {
+ socketPair.close();
+ }
+ if (executor != null) {
+ executor.shutdown();
+ executor.awaitTermination(5, TimeUnit.SECONDS);
+ }
+ if (receivingFuture != null) {
+ receivingFuture.get(5, TimeUnit.SECONDS);
+ }
}
@Test
@Parameters(method = "getParams")
public void throughput(Config config) throws Exception {
- setup(config);
- BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
- while (state.keepRunning()) {
- recording.set(true);
- while (bytesCounter.get() < config.messageSize()) {
- }
- bytesCounter.set(0);
- recording.set(false);
+ try {
+ setup(config);
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ recording.set(true);
+ while (bytesCounter.get() < config.messageSize()) {
+ }
+ bytesCounter.set(0);
+ recording.set(false);
+ }
+ } finally {
+ close();
}
+ }
+
+ @After
+ public void tearDown() throws Exception {
close();
}
diff --git a/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesMetadataPerfTest.java b/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesMetadataPerfTest.java
new file mode 100644
index 000000000000..205c7b875bbc
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesMetadataPerfTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SystemFeaturesMetadataPerfTest {
+ // As each query is relatively cheap, add an inner iteration loop to reduce execution noise.
+ private static final int NUM_ITERATIONS = 10;
+
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void maybeGetSdkFeatureIndex_featureDefined() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < NUM_ITERATIONS; ++i) {
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_WATCH);
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_LEANBACK);
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_IPSEC_TUNNELS);
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_WEBVIEW);
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_NFC_BEAM);
+ PackageManager.maybeGetSdkFeatureIndex(PackageManager.FEATURE_AUTOFILL);
+ }
+ }
+ }
+
+ @Test
+ public void maybeGetSdkFeatureIndex_featureUndefined() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < NUM_ITERATIONS; ++i) {
+ PackageManager.maybeGetSdkFeatureIndex("com.android.custom.feature.1");
+ PackageManager.maybeGetSdkFeatureIndex("com.android.custom.feature.2");
+ PackageManager.maybeGetSdkFeatureIndex("foo");
+ PackageManager.maybeGetSdkFeatureIndex("bar");
+ PackageManager.maybeGetSdkFeatureIndex("0");
+ PackageManager.maybeGetSdkFeatureIndex("");
+ }
+ }
+ }
+
+}
diff --git a/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesPerfTest.java b/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesPerfTest.java
new file mode 100644
index 000000000000..43f545318124
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/content/pm/SystemFeaturesPerfTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.pm.RoSystemFeatures;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SystemFeaturesPerfTest {
+ // As each query is relatively cheap, add an inner iteration loop to reduce execution noise.
+ private static final int NUM_ITERATIONS = 10;
+
+ @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @Test
+ public void hasSystemFeature_PackageManager() {
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < NUM_ITERATIONS; ++i) {
+ pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
+ pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ pm.hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS);
+ pm.hasSystemFeature(PackageManager.FEATURE_AUTOFILL);
+ pm.hasSystemFeature("com.android.custom.feature.1");
+ pm.hasSystemFeature("foo");
+ pm.hasSystemFeature("");
+ }
+ }
+ }
+
+ @Test
+ public void hasSystemFeature_SystemFeaturesCache() {
+ final PackageManager pm =
+ InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
+ final SystemFeaturesCache cache =
+ new SystemFeaturesCache(Arrays.asList(pm.getSystemAvailableFeatures()));
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < NUM_ITERATIONS; ++i) {
+ cache.maybeHasFeature(PackageManager.FEATURE_WATCH, 0);
+ cache.maybeHasFeature(PackageManager.FEATURE_LEANBACK, 0);
+ cache.maybeHasFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
+ cache.maybeHasFeature(PackageManager.FEATURE_AUTOFILL, 0);
+ cache.maybeHasFeature("com.android.custom.feature.1", 0);
+ cache.maybeHasFeature("foo", 0);
+ cache.maybeHasFeature("", 0);
+ }
+ }
+ }
+
+ @Test
+ public void hasSystemFeature_RoSystemFeatures() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int i = 0; i < NUM_ITERATIONS; ++i) {
+ RoSystemFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 0);
+ RoSystemFeatures.maybeHasFeature(PackageManager.FEATURE_LEANBACK, 0);
+ RoSystemFeatures.maybeHasFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
+ RoSystemFeatures.maybeHasFeature(PackageManager.FEATURE_AUTOFILL, 0);
+ RoSystemFeatures.maybeHasFeature("com.android.custom.feature.1", 0);
+ RoSystemFeatures.maybeHasFeature("foo", 0);
+ RoSystemFeatures.maybeHasFeature("", 0);
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
index ecbfc7169945..10ec2bfcb49a 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -75,8 +75,19 @@ public class ExpensiveObjectsPerfTest {
@Test(timeout = 900000)
public void timeNewCollator() {
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ int i = 0;
while (state.keepRunning()) {
Collator.getInstance(Locale.US);
+
+ if (++i % 1000 == 0) {
+ state.pauseTiming();
+ // GC and finalize occasionally to avoid GC for alloc and/or
+ // blocking on finalization during benchmark time.
+ // See: b/394961590
+ System.gc();
+ System.runFinalization();
+ state.resumeTiming();
+ }
}
}
@@ -84,8 +95,19 @@ public class ExpensiveObjectsPerfTest {
public void timeClonedCollator() {
Collator c = Collator.getInstance(Locale.US);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ int i = 0;
while (state.keepRunning()) {
c.clone();
+
+ if (++i % 1000 == 0) {
+ state.pauseTiming();
+ // GC and finalize occasionally to avoid GC for alloc and/or
+ // blocking on finalization during benchmark time.
+ // See: b/394961590
+ System.gc();
+ System.runFinalization();
+ state.resumeTiming();
+ }
}
}
diff --git a/apct-tests/perftests/healthconnect/OWNERS b/apct-tests/perftests/healthconnect/OWNERS
index da0b46adeaef..7c9e7692a9fc 100644
--- a/apct-tests/perftests/healthconnect/OWNERS
+++ b/apct-tests/perftests/healthconnect/OWNERS
@@ -1,6 +1,4 @@
# Bug component: 1219472
-arkivanov@google.com
jstembridge@google.com
-pratyushmore@google.com
itsleo@google.com
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
index 73bff08c626d..af0237491639 100644
--- a/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/BenchmarkState.java
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.Instrumentation;
import android.os.Bundle;
import android.os.Debug;
+import android.os.Trace;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -129,17 +130,23 @@ public final class BenchmarkState {
}
private void beginWarmup() {
+ Trace.beginSection("Warmup");
mStartTimeNs = System.nanoTime();
mIteration = 0;
mState = WARMUP;
}
+ private void endWarmup() {
+ Trace.endSection();
+ }
+
private void beginBenchmark(long warmupDuration, int iterations) {
if (ENABLE_PROFILING) {
File f = new File(InstrumentationRegistry.getContext().getDataDir(), "benchprof");
Log.d(TAG, "Tracing to: " + f.getAbsolutePath());
Debug.startMethodTracingSampling(f.getAbsolutePath(), 16 * 1024 * 1024, 100);
}
+ Trace.beginSection("Benchmark");
mMaxIterations = (int) (TARGET_TEST_DURATION_NS / (warmupDuration / iterations));
mMaxIterations = Math.min(MAX_TEST_ITERATIONS,
Math.max(mMaxIterations, MIN_TEST_ITERATIONS));
@@ -150,6 +157,10 @@ public final class BenchmarkState {
mStartTimeNs = System.nanoTime();
}
+ private void endBenchmark() {
+ Trace.endSection();
+ }
+
private boolean startNextTestRun() {
final long currentTime = System.nanoTime();
mResults.add((currentTime - mStartTimeNs - mPausedDurationNs) / mMaxIterations);
@@ -165,6 +176,7 @@ public final class BenchmarkState {
return true;
}
mState = FINISHED;
+ endBenchmark();
return false;
}
mPausedDurationNs = 0;
@@ -189,6 +201,7 @@ public final class BenchmarkState {
// don't yet have a target iteration count.
final long duration = System.nanoTime() - mStartTimeNs;
if (mIteration >= WARMUP_MIN_ITERATIONS && duration >= WARMUP_DURATION_NS) {
+ endWarmup();
beginBenchmark(duration, mIteration);
}
return true;
@@ -208,6 +221,7 @@ public final class BenchmarkState {
mCustomizedIterations++;
if (mCustomizedIterations >= mMaxCustomizedIterations) {
mState = FINISHED;
+ endBenchmark();
return false;
}
mCustomizedIterationListener.onStart(mCustomizedIterations);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 8f44698ffd8d..5dfb3754e8fb 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -1034,7 +1034,7 @@ class JobConcurrencyManager {
for (int p = preferredUidOnly.size() - 1; p >= 0; --p) {
final ContextAssignment assignment = preferredUidOnly.get(p);
final JobStatus runningJob = assignment.context.getRunningJobLocked();
- if (runningJob.getUid() != nextPending.getUid()) {
+ if (runningJob == null || runningJob.getUid() != nextPending.getUid()) {
continue;
}
final int jobBias = mService.evaluateJobBiasLocked(runningJob);
@@ -1916,8 +1916,9 @@ class JobConcurrencyManager {
for (int i = 0; i < mActiveServices.size(); i++) {
final JobServiceContext jc = mActiveServices.get(i);
final JobStatus js = jc.getRunningJobLocked();
- if (jc.stopIfExecutingLocked(pkgName, userId, namespace, matchJobId, jobId,
- stopReason, internalStopReason)) {
+ if (js != null &&
+ jc.stopIfExecutingLocked(pkgName, userId, namespace,
+ matchJobId, jobId, stopReason, internalStopReason)) {
foundSome = true;
pw.print("Stopping job: ");
js.printUniqueId(pw);
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index 89351fd47ff8..03fb44fd8145 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -130,6 +130,10 @@ droidstubs {
droidstubs {
name: "framework-doc-stubs",
defaults: ["android-non-updatable-doc-stubs-defaults"],
+ flags: [
+ // Ignore any compatibility errors, see check_api.last_released below for more information.
+ "--hide-category Compatibility",
+ ],
srcs: [":all-modules-public-stubs-source-exportable"],
api_levels_module: "api_versions_public",
aidl: {
@@ -138,13 +142,39 @@ droidstubs {
"packages/modules/Media/apex/aidl/stable",
],
},
+
+ // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+ // a flagged API will cause it to be removed, even if it had previously been released. This
+ // has the side effect of causing compatibility issues to be reported but they are already
+ // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+ check_api: {
+ last_released: {
+ api_file: ":android.api.combined.public.latest",
+ removed_api_file: ":android-removed.api.combined.public.latest",
+ },
+ },
}
droidstubs {
name: "framework-doc-system-stubs",
defaults: ["framework-doc-stubs-sources-default"],
- flags: ["--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"],
+ flags: [
+ "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)",
+ // Ignore any compatibility errors, see check_api.last_released below for more information.
+ "--hide-category Compatibility",
+ ],
api_levels_module: "api_versions_system",
+
+ // Pass the previously released API to support reverting flagged APIs. Without this, reverting
+ // a flagged API will cause it to be removed, even if it had previously been released. This
+ // has the side effect of causing compatibility issues to be reported but they are already
+ // checked elsewhere so they will be ignored, see `--hide-category Compatibility` above.
+ check_api: {
+ last_released: {
+ api_file: ":android.api.combined.system.latest",
+ removed_api_file: ":android-removed.api.combined.system.latest",
+ },
+ },
}
/////////////////////////////////////////////////////////////////////
diff --git a/api/OWNERS b/api/OWNERS
index 965093c9ab38..31ffa8cd4e9f 100644
--- a/api/OWNERS
+++ b/api/OWNERS
@@ -1,4 +1,3 @@
-hansson@google.com
# Modularization team
file:platform/packages/modules/common:/OWNERS
@@ -9,4 +8,4 @@ per-file *.go,go.mod,go.work,go.work.sum = file:platform/build/soong:/OWNERS
per-file Android.bp = file:platform/build/soong:/OWNERS #{LAST_RESORT_SUGGESTION}
# For metalava team to disable lint checks in platform
-per-file Android.bp = aurimas@google.com,emberrose@google.com
+per-file Android.bp = aurimas@google.com
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index a949ff5a331b..3314b4aa0d71 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -648,7 +648,7 @@ java_api_library {
java_api_library {
name: "android-non-updatable.stubs.module_lib.from-text",
- api_surface: "module_lib",
+ api_surface: "module-lib",
api_contributions: [
"api-stubs-docs-non-updatable.api.contribution",
"system-api-stubs-docs-non-updatable.api.contribution",
@@ -668,7 +668,7 @@ java_api_library {
// generated from this module, as this module is strictly used for hiddenapi only.
java_api_library {
name: "android-non-updatable.stubs.test_module_lib",
- api_surface: "module_lib",
+ api_surface: "module-lib",
api_contributions: [
"api-stubs-docs-non-updatable.api.contribution",
"system-api-stubs-docs-non-updatable.api.contribution",
@@ -689,7 +689,7 @@ java_api_library {
java_api_library {
name: "android-non-updatable.stubs.system_server.from-text",
- api_surface: "system_server",
+ api_surface: "system-server",
api_contributions: [
"api-stubs-docs-non-updatable.api.contribution",
"system-api-stubs-docs-non-updatable.api.contribution",
@@ -1023,7 +1023,6 @@ stubs_defaults {
api_levels_annotations_enabled: true,
api_levels_annotations_dirs: [
"sdk-dir",
- "api-versions-jars-dir",
],
}
diff --git a/api/api.go b/api/api.go
index e4d783eba4c3..640773be0f9b 100644
--- a/api/api.go
+++ b/api/api.go
@@ -104,8 +104,9 @@ func (a *CombinedApis) DepsMutator(ctx android.BottomUpMutatorContext) {
}
func (a *CombinedApis) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- ctx.WalkDeps(func(child, parent android.Module) bool {
- if _, ok := child.(java.AndroidLibraryDependency); ok && child.Name() != "framework-res" {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ javaInfo, ok := android.OtherModuleProvider(ctx, child, java.JavaInfoProvider)
+ if ok && javaInfo.AndroidLibraryDependencyInfo != nil && child.Name() != "framework-res" {
// Stubs of BCP and SSCP libraries should not have any dependencies on apps
// This check ensures that we do not run into circular dependencies when UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT=true
ctx.ModuleErrorf(
diff --git a/boot/Android.bp b/boot/Android.bp
index eaa984ac0cdd..f4ef1df96bc5 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -76,8 +76,8 @@ custom_platform_bootclasspath {
module: "art-bootclasspath-fragment",
},
{
- apex: "com.android.btservices",
- module: "com.android.btservices-bootclasspath-fragment",
+ apex: "com.android.bt",
+ module: "com.android.bt-bootclasspath-fragment",
},
{
apex: "com.android.configinfrastructure",
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
index a696e03d5bdf..9926aef91ee1 100644
--- a/boot/preloaded-classes
+++ b/boot/preloaded-classes
@@ -6469,6 +6469,8 @@ android.os.connectivity.WifiActivityEnergyInfo$1
android.os.connectivity.WifiActivityEnergyInfo
android.os.connectivity.WifiBatteryStats$1
android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
+android.os.flagging.PlatformAconfigPackage
android.os.health.HealthKeys$Constant
android.os.health.HealthKeys$Constants
android.os.health.HealthKeys$SortedIntArray
@@ -6582,6 +6584,7 @@ android.permission.LegacyPermissionManager
android.permission.PermissionCheckerManager
android.permission.PermissionControllerManager$1
android.permission.PermissionControllerManager
+android.permission.PermissionManager
android.permission.PermissionManager$1
android.permission.PermissionManager$2
android.permission.PermissionManager$OnPermissionsChangeListenerDelegate
diff --git a/cmds/idmap2/OWNERS b/cmds/idmap2/OWNERS
index 062ffd41348a..def9f401e51f 100644
--- a/cmds/idmap2/OWNERS
+++ b/cmds/idmap2/OWNERS
@@ -1,4 +1,3 @@
set noparent
-toddke@google.com
patb@google.com
zyy@google.com
diff --git a/cmds/incidentd/OWNERS b/cmds/incidentd/OWNERS
index bcdcfc3cafed..db8fa9f09725 100644
--- a/cmds/incidentd/OWNERS
+++ b/cmds/incidentd/OWNERS
@@ -1,4 +1,3 @@
joeo@google.com
yaochen@google.com
yanmin@google.com
-zhouwenjie@google.com
diff --git a/cmds/svc/src/com/android/commands/svc/OWNERS b/cmds/svc/src/com/android/commands/svc/OWNERS
index d5a5d7b3b858..a901dfdeddfb 100644
--- a/cmds/svc/src/com/android/commands/svc/OWNERS
+++ b/cmds/svc/src/com/android/commands/svc/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 48448
-per-file NfcCommand.java = file:platform/packages/apps/Nfc:/OWNERS
+per-file NfcCommand.java = file:platform/packages/modules/Nfc:/OWNERS
diff --git a/config/preloaded-classes b/config/preloaded-classes
index ed402767ee64..bdd95f8e67ae 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6473,6 +6473,8 @@ android.os.connectivity.WifiActivityEnergyInfo$1
android.os.connectivity.WifiActivityEnergyInfo
android.os.connectivity.WifiBatteryStats$1
android.os.connectivity.WifiBatteryStats
+android.os.flagging.AconfigPackage
+android.os.flagging.PlatformAconfigPackage
android.os.health.HealthKeys$Constant
android.os.health.HealthKeys$Constants
android.os.health.HealthKeys$SortedIntArray
@@ -6586,6 +6588,7 @@ android.permission.LegacyPermissionManager
android.permission.PermissionCheckerManager
android.permission.PermissionControllerManager$1
android.permission.PermissionControllerManager
+android.permission.PermissionManager
android.permission.PermissionManager$1
android.permission.PermissionManager$2
android.permission.PermissionManager$OnPermissionsChangeListenerDelegate
diff --git a/config/preloaded-classes-denylist b/config/preloaded-classes-denylist
index 16f069394639..a6a1d1680b7b 100644
--- a/config/preloaded-classes-denylist
+++ b/config/preloaded-classes-denylist
@@ -1,9 +1,7 @@
android.content.AsyncTaskLoader$LoadTask
-android.media.MediaCodecInfo$CodecCapabilities$FeatureList
android.net.ConnectivityThread$Singleton
android.os.FileObserver
android.os.NullVibrator
-android.permission.PermissionManager
android.provider.MediaStore
android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
android.view.HdrRenderState
diff --git a/core/api/current.txt b/core/api/current.txt
index 5efa74779c06..cb4e4f09f6e0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -1505,7 +1505,6 @@ package android {
field public static final int shadowRadius = 16843108; // 0x1010164
field public static final int shape = 16843162; // 0x101019a
field public static final int shareInterpolator = 16843195; // 0x10101bb
- field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final int shareRolePriority;
field @Deprecated public static final int sharedUserId = 16842763; // 0x101000b
field @Deprecated public static final int sharedUserLabel = 16843361; // 0x1010261
field public static final int sharedUserMaxSdkVersion = 16844365; // 0x101064d
@@ -1870,6 +1869,7 @@ package android {
field public static final int wallpaperIntraOpenExitAnimation = 16843416; // 0x1010298
field public static final int wallpaperOpenEnterAnimation = 16843411; // 0x1010293
field public static final int wallpaperOpenExitAnimation = 16843412; // 0x1010294
+ field @FlaggedApi("android.nfc.nfc_associated_role_services") public static final int wantsRoleHolderPriority;
field public static final int webTextViewStyle = 16843449; // 0x10102b9
field public static final int webViewStyle = 16842885; // 0x1010085
field public static final int weekDayTextAppearance = 16843592; // 0x1010348
@@ -11129,6 +11129,7 @@ package android.content {
field public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
field public static final String TELEPHONY_SERVICE = "phone";
field public static final String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service";
+ field public static final String TETHERING_SERVICE = "tethering";
field public static final String TEXT_CLASSIFICATION_SERVICE = "textclassification";
field public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
field @FlaggedApi("android.media.tv.flags.enable_ad_service_fw") public static final String TV_AD_SERVICE = "tv_ad";
@@ -13380,6 +13381,7 @@ package android.content.pm {
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
method @NonNull @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
@@ -14025,8 +14027,17 @@ package android.content.pm {
method public android.content.pm.Signature[] getSigningCertificateHistory();
method public boolean hasMultipleSigners();
method public boolean hasPastSigningCertificates();
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.SigningInfo> CREATOR;
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
+ field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
+ }
+
+ @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
+ method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
}
public final class VersionedPackage implements android.os.Parcelable {
@@ -19328,7 +19339,7 @@ package android.hardware.biometrics {
public class BiometricManager {
method @Deprecated @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate(int);
- method @FlaggedApi("android.hardware.biometrics.last_authentication_time") @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public long getLastAuthenticationTime(int);
+ method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public long getLastAuthenticationTime(int);
method @NonNull @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public android.hardware.biometrics.BiometricManager.Strings getStrings(int);
field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE = 20; // 0x14
@@ -19336,7 +19347,7 @@ package android.hardware.biometrics {
field @FlaggedApi("android.hardware.biometrics.identity_check_api") public static final int BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS = 21; // 0x15
field public static final int BIOMETRIC_ERROR_NO_HARDWARE = 12; // 0xc
field public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; // 0xf
- field @FlaggedApi("android.hardware.biometrics.last_authentication_time") public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
+ field public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
field public static final int BIOMETRIC_SUCCESS = 0; // 0x0
}
@@ -19389,7 +19400,7 @@ package android.hardware.biometrics {
field public static final int BIOMETRIC_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
field public static final int BIOMETRIC_ERROR_USER_CANCELED = 10; // 0xa
field public static final int BIOMETRIC_ERROR_VENDOR = 8; // 0x8
- field @FlaggedApi("android.hardware.biometrics.last_authentication_time") public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
+ field public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
}
public abstract static class BiometricPrompt.AuthenticationCallback {
@@ -49356,7 +49367,7 @@ package android.text {
method public static void dumpSpans(CharSequence, android.util.Printer, String);
method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt);
method public static CharSequence ellipsize(CharSequence, android.text.TextPaint, float, android.text.TextUtils.TruncateAt, boolean, @Nullable android.text.TextUtils.EllipsizeCallback);
- method public static boolean equals(CharSequence, CharSequence);
+ method public static boolean equals(@Nullable CharSequence, @Nullable CharSequence);
method public static CharSequence expandTemplate(CharSequence, java.lang.CharSequence...);
method public static int getCapsMode(CharSequence, int, int);
method public static void getChars(CharSequence, int, int, char[], int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index bca2ce2473c5..40069aa00106 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -130,7 +130,6 @@ package android.content.pm {
public abstract class PackageManager {
method @NonNull public String getSdkSandboxPackageName();
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException;
method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int);
field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH";
field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
@@ -141,18 +140,6 @@ package android.content.pm {
method @NonNull public String getPackageName();
}
- public final class SigningInfo implements android.os.Parcelable {
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo);
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3
- field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4
- }
-
- @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception {
- method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode();
- }
-
}
package android.hardware.usb {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 9590e1ab19c9..3e62c50c0fd5 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3800,7 +3800,6 @@ package android.content {
field public static final String STATS_MANAGER = "stats";
field public static final String SYSTEM_CONFIG_SERVICE = "system_config";
field public static final String SYSTEM_UPDATE_SERVICE = "system_update";
- field public static final String TETHERING_SERVICE = "tethering";
field @FlaggedApi("com.android.net.thread.platform.flags.thread_enabled_platform") public static final String THREAD_NETWORK_SERVICE = "thread_network";
field public static final String TIME_MANAGER_SERVICE = "time_manager";
field public static final String TRANSLATION_MANAGER_SERVICE = "translation";
@@ -10936,6 +10935,7 @@ package android.nfc.cardemulation {
}
@FlaggedApi("android.nfc.enable_nfc_mainline") public final class ApduServiceInfo implements android.os.Parcelable {
+ ctor @FlaggedApi("android.nfc.nfc_apdu_service_info_constructor") public ApduServiceInfo(@NonNull android.content.pm.ResolveInfo, boolean, @NonNull String, @NonNull java.util.List<android.nfc.cardemulation.AidGroup>, @NonNull java.util.List<android.nfc.cardemulation.AidGroup>, boolean, int, int, @NonNull String, @NonNull String, @NonNull String);
ctor @FlaggedApi("android.nfc.enable_nfc_mainline") public ApduServiceInfo(@NonNull android.content.pm.PackageManager, @NonNull android.content.pm.ResolveInfo, boolean) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopFilter(@NonNull String, boolean);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void addPollingLoopPatternFilter(@NonNull String, boolean);
@@ -10973,8 +10973,8 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setDynamicAidGroup(@NonNull android.nfc.cardemulation.AidGroup);
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void setOffHostSecureElement(@NonNull String);
method @FlaggedApi("android.nfc.nfc_observe_mode") public void setShouldDefaultToObserveMode(boolean);
- method @FlaggedApi("android.nfc.nfc_associated_role_services") public boolean shareRolePriority();
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean shouldDefaultToObserveMode();
+ method @FlaggedApi("android.nfc.nfc_associated_role_services") public boolean wantsRoleHolderPriority();
method @FlaggedApi("android.nfc.enable_nfc_mainline") public void writeToParcel(@NonNull android.os.Parcel, int);
field @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.ApduServiceInfo> CREATOR;
field @FlaggedApi("android.permission.flags.wallet_role_icon_property_enabled") public static final String PROPERTY_WALLET_PREFERRED_BANNER_AND_LABEL = "android.nfc.cardemulation.PROPERTY_WALLET_PREFERRED_BANNER_AND_LABEL";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 6230a59a62c0..6446bbd7d507 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2431,6 +2431,12 @@ package android.os {
method @NonNull public static byte[] digest(@NonNull java.io.InputStream, @NonNull String) throws java.io.IOException, java.security.NoSuchAlgorithmException;
}
+ public class Handler {
+ method @FlaggedApi("android.os.mainline_vcn_platform_api") public final boolean hasMessagesOrCallbacks();
+ method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeCallbacksAndEqualMessages(@Nullable Object);
+ method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeEqualMessages(int, @Nullable Object);
+ }
+
public class IpcDataCache<Query, Result> extends android.app.PropertyInvalidatedCache<Query,Result> {
ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>);
method public static void disableForCurrentProcess(@NonNull String);
diff --git a/core/java/android/accessibilityservice/OWNERS b/core/java/android/accessibilityservice/OWNERS
index 1265dfa2c441..dac64f47ba7e 100644
--- a/core/java/android/accessibilityservice/OWNERS
+++ b/core/java/android/accessibilityservice/OWNERS
@@ -1,4 +1,7 @@
-# Bug component: 44215
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
# Android Accessibility Framework owners
include /services/accessibility/OWNERS \ No newline at end of file
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 69d3e8d4c0d2..f9ec214390f9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -550,35 +550,35 @@ public class ActivityManager {
public static final int START_ASSISTANT_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 11;
/**
- * Result for IActivityManaqer.startActivity: the activity was started
+ * Result for IActivityManager.startActivity: the activity was started
* successfully as normal.
* @hide
*/
public static final int START_SUCCESS = FIRST_START_SUCCESS_CODE;
/**
- * Result for IActivityManaqer.startActivity: the caller asked that the Intent not
+ * Result for IActivityManager.startActivity: the caller asked that the Intent not
* be executed if it is the recipient, and that is indeed the case.
* @hide
*/
public static final int START_RETURN_INTENT_TO_CALLER = FIRST_START_SUCCESS_CODE + 1;
/**
- * Result for IActivityManaqer.startActivity: activity was started or brought forward in an
+ * Result for IActivityManager.startActivity: activity was started or brought forward in an
* existing task which was brought to the foreground.
* @hide
*/
public static final int START_TASK_TO_FRONT = FIRST_START_SUCCESS_CODE + 2;
/**
- * Result for IActivityManaqer.startActivity: activity wasn't really started, but
+ * Result for IActivityManager.startActivity: activity wasn't really started, but
* the given Intent was given to the existing top activity.
* @hide
*/
public static final int START_DELIVERED_TO_TOP = FIRST_START_SUCCESS_CODE + 3;
/**
- * Result for IActivityManaqer.startActivity: request was canceled because
+ * Result for IActivityManager.startActivity: request was canceled because
* app switches are temporarily canceled to ensure the user's last request
* (such as pressing home) is performed.
* @hide
@@ -586,7 +586,7 @@ public class ActivityManager {
public static final int START_SWITCHES_CANCELED = FIRST_START_NON_FATAL_ERROR_CODE;
/**
- * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
+ * Result for IActivityManager.startActivity: a new activity was attempted to be started
* while in Lock Task Mode.
* @hide
*/
@@ -594,55 +594,55 @@ public class ActivityManager {
FIRST_START_NON_FATAL_ERROR_CODE + 1;
/**
- * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+ * Result for IActivityManager.startActivity: a new activity start was aborted. Never returned
* externally.
* @hide
*/
public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
/**
- * Flag for IActivityManaqer.startActivity: do special start mode where
+ * Flag for IActivityManager.startActivity: do special start mode where
* a new activity is launched only if it is needed.
* @hide
*/
public static final int START_FLAG_ONLY_IF_NEEDED = 1<<0;
/**
- * Flag for IActivityManaqer.startActivity: launch the app for
+ * Flag for IActivityManager.startActivity: launch the app for
* debugging.
* @hide
*/
public static final int START_FLAG_DEBUG = 1<<1;
/**
- * Flag for IActivityManaqer.startActivity: launch the app for
+ * Flag for IActivityManager.startActivity: launch the app for
* allocation tracking.
* @hide
*/
public static final int START_FLAG_TRACK_ALLOCATION = 1<<2;
/**
- * Flag for IActivityManaqer.startActivity: launch the app with
+ * Flag for IActivityManager.startActivity: launch the app with
* native debugging support.
* @hide
*/
public static final int START_FLAG_NATIVE_DEBUGGING = 1<<3;
/**
- * Flag for IActivityManaqer.startActivity: launch the app for
+ * Flag for IActivityManager.startActivity: launch the app for
* debugging and suspend threads.
* @hide
*/
public static final int START_FLAG_DEBUG_SUSPEND = 1 << 4;
/**
- * Result for IActivityManaqer.broadcastIntent: success!
+ * Result for IActivityManager.broadcastIntent: success!
* @hide
*/
public static final int BROADCAST_SUCCESS = 0;
/**
- * Result for IActivityManaqer.broadcastIntent: attempt to broadcast
+ * Result for IActivityManager.broadcastIntent: attempt to broadcast
* a sticky intent without appropriate permission.
* @hide
*/
@@ -656,20 +656,20 @@ public class ActivityManager {
public static final int BROADCAST_FAILED_USER_STOPPED = -2;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent type is unknown.
+ * Type for IActivityManager.getIntentSender: this PendingIntent type is unknown.
* @hide
*/
public static final int INTENT_SENDER_UNKNOWN = 0;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * Type for IActivityManager.getIntentSender: this PendingIntent is
* for a sendBroadcast operation.
* @hide
*/
public static final int INTENT_SENDER_BROADCAST = 1;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * Type for IActivityManager.getIntentSender: this PendingIntent is
* for a startActivity operation.
* @hide
*/
@@ -677,21 +677,21 @@ public class ActivityManager {
public static final int INTENT_SENDER_ACTIVITY = 2;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * Type for IActivityManager.getIntentSender: this PendingIntent is
* for an activity result operation.
* @hide
*/
public static final int INTENT_SENDER_ACTIVITY_RESULT = 3;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * Type for IActivityManager.getIntentSender: this PendingIntent is
* for a startService operation.
* @hide
*/
public static final int INTENT_SENDER_SERVICE = 4;
/**
- * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * Type for IActivityManager.getIntentSender: this PendingIntent is
* for a startForegroundService operation.
* @hide
*/
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 48b74f2d0776..f9952fda2822 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7037,7 +7037,7 @@ public final class ActivityThread extends ClientTransactionHandler
Slog.w(TAG, "Low overhead tracing feature is not enabled");
break;
}
- VMDebug.startLowOverheadTrace();
+ VMDebug.startLowOverheadTraceForAllMethods();
break;
default:
try {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 7eacaac29d4b..bb35e6cf1bfa 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -190,6 +190,7 @@ public class Instrumentation {
* @param arguments Any additional arguments that were supplied when the
* instrumentation was started.
*/
+ @android.ravenwood.annotation.RavenwoodKeep
public void onCreate(Bundle arguments) {
}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 67f7bee4028e..b5ac4e78c7ad 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -70,7 +70,6 @@ import com.android.internal.widget.VerifyCredentialResponse;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.Charset;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -1064,7 +1063,7 @@ public class KeyguardManager {
Log.e(TAG, "Save lock exception", e);
success = false;
} finally {
- Arrays.fill(password, (byte) 0);
+ LockPatternUtils.zeroize(password);
}
return success;
}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3d85ea6a1fca..ffd235f91e09 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -1129,6 +1129,10 @@ public final class LoadedApk {
@UnsupportedAppUsage
public ClassLoader getClassLoader() {
+ ClassLoader ret = mClassLoader;
+ if (ret != null) {
+ return ret;
+ }
synchronized (mLock) {
if (mClassLoader == null) {
createOrUpdateClassLoaderLocked(null /*addedPaths*/);
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 6e4c28f3eca6..7a811a1cdfb8 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -28,6 +28,7 @@ per-file ProfilerInfo* = file:/ACTIVITY_MANAGER_OWNERS
per-file Service* = file:/ACTIVITY_MANAGER_OWNERS
per-file SystemServiceRegistry.java = file:/ACTIVITY_MANAGER_OWNERS
per-file *UserSwitchObserver* = file:/ACTIVITY_MANAGER_OWNERS
+per-file UidObserver* = file:/ACTIVITY_MANAGER_OWNERS
# UI Automation
per-file *UiAutomation* = file:/services/accessibility/OWNERS
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 2e6f3e1c7f0a..57549847f05d 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -753,7 +753,7 @@ public class UiModeManager {
* <p>
* The mode can be one of:
* <ul>
- * <li><em>{@link #MODE_NIGHT_NO}<em> sets the device into
+ * <li><em>{@link #MODE_NIGHT_NO}</em> sets the device into
* {@code notnight} mode</li>
* <li><em>{@link #MODE_NIGHT_YES}</em> sets the device into
* {@code night} mode</li>
@@ -889,7 +889,7 @@ public class UiModeManager {
* <p>
* The mode can be one of:
* <ul>
- * <li><em>{@link #MODE_NIGHT_NO}<em> sets the device into
+ * <li><em>{@link #MODE_NIGHT_NO}</em> sets the device into
* {@code notnight} mode</li>
* <li><em>{@link #MODE_NIGHT_YES}</em> sets the device into
* {@code night} mode</li>
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index af035cb630dc..75589fa47892 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -160,16 +160,6 @@ flag {
}
flag {
- name: "fix_race_condition_in_tie_profile_lock"
- namespace: "enterprise"
- description: "Fix race condition in tieProfileLockIfNecessary()"
- bug: "355905501"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "quiet_mode_credential_bug_fix"
namespace: "enterprise"
description: "Guards a bugfix that ends the credential input flow if the managed user has not stopped."
diff --git a/core/java/android/app/contentsuggestions/OWNERS b/core/java/android/app/contentsuggestions/OWNERS
index 5f8de77c9dda..3d21a6a2b58f 100644
--- a/core/java/android/app/contentsuggestions/OWNERS
+++ b/core/java/android/app/contentsuggestions/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 643919
hackz@google.com
-volnov@google.com
diff --git a/core/java/android/app/people/OWNERS b/core/java/android/app/people/OWNERS
index 7371a88df237..399511a0e0cb 100644
--- a/core/java/android/app/people/OWNERS
+++ b/core/java/android/app/people/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 978868
-danningc@google.com
-juliacr@google.com \ No newline at end of file
+juliacr@google.com
diff --git a/core/java/android/app/wearable/OWNERS b/core/java/android/app/wearable/OWNERS
index 497eaf0e40f1..56c8ca57a293 100644
--- a/core/java/android/app/wearable/OWNERS
+++ b/core/java/android/app/wearable/OWNERS
@@ -2,4 +2,3 @@ charliewang@google.com
hackz@google.com
oni@google.com
tomchan@google.com
-volnov@google.com \ No newline at end of file
diff --git a/core/java/android/appwidget/OWNERS b/core/java/android/appwidget/OWNERS
index 0e85d5bd7a27..1dc4cbb701fa 100644
--- a/core/java/android/appwidget/OWNERS
+++ b/core/java/android/appwidget/OWNERS
@@ -3,5 +3,4 @@ sihua@google.com
pinyaoting@google.com
suprabh@google.com
sunnygoyal@google.com
-zakcohen@google.com
shamalip@google.com
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index a81629445263..cf684876d33f 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -52,6 +52,8 @@ import com.android.internal.os.DebugStore;
* <a href="{@docRoot}guide/components/broadcasts.html">Broadcasts</a> developer guide.</p></div>
*
*/
+@android.ravenwood.annotation.RavenwoodPartiallyAllowlisted
+@android.ravenwood.annotation.RavenwoodKeepPartialClass
public abstract class BroadcastReceiver {
@UnsupportedAppUsage
private PendingResult mPendingResult;
@@ -360,6 +362,7 @@ public abstract class BroadcastReceiver {
}
}
+ @android.ravenwood.annotation.RavenwoodKeep
public BroadcastReceiver() {
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6ec6a62ff639..389e56cd453e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4236,6 +4236,7 @@ public abstract class Context {
//@hide: STATUS_BAR_SERVICE,
THREAD_NETWORK_SERVICE,
CONNECTIVITY_SERVICE,
+ TETHERING_SERVICE,
PAC_PROXY_SERVICE,
VCN_MANAGEMENT_SERVICE,
//@hide: IP_MEMORY_STORE_SERVICE,
@@ -4930,10 +4931,10 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a {@link android.net.TetheringManager}
* for managing tethering functions.
- * @hide
+ *
* @see android.net.TetheringManager
*/
- @SystemApi
+ @SuppressLint("UnflaggedApi")
public static final String TETHERING_SERVICE = "tethering";
/**
diff --git a/core/java/android/content/EventLogTags.logtags b/core/java/android/content/EventLogTags.logtags
index 21ea90ad2e1e..861a5b72c86c 100644
--- a/core/java/android/content/EventLogTags.logtags
+++ b/core/java/android/content/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.content;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3d75423edfa9..3001da5c0342 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5460,7 +5460,7 @@ public class Intent implements Parcelable, Cloneable {
/**
* Activities that can be safely invoked from a browser must support this
* category. For example, if the user is viewing a web page or an e-mail
- * and clicks on a link in the text, the Intent generated execute that
+ * and clicks on a link in the text, the Intent generated to execute that
* link will require the BROWSABLE category, so that only activities
* supporting this category will be considered as possible actions. By
* supporting this category, you are promising that there is nothing
diff --git a/core/java/android/content/integrity/OWNERS b/core/java/android/content/integrity/OWNERS
index 20c758aedd67..ca65fdab99b1 100644
--- a/core/java/android/content/integrity/OWNERS
+++ b/core/java/android/content/integrity/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 722021
toddke@android.com
-toddke@google.com
patb@google.com
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7e0805137d0b..265fcc05ba92 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3151,16 +3151,6 @@ public abstract class PackageManager {
public static final long MAXIMUM_VERIFICATION_TIMEOUT = 60*60*1000;
/**
- * As the generated feature count is useful for classes that may not be compiled in the same
- * annotation processing unit as PackageManager, we redeclare it here for visibility.
- *
- * @hide
- */
- @VisibleForTesting
- public static final int SDK_FEATURE_COUNT =
- com.android.internal.pm.SystemFeaturesMetadata.SDK_FEATURE_COUNT;
-
- /**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device's
* audio pipeline is low-latency, more suitable for audio applications sensitive to delays or
* lag in sound input or output.
@@ -4659,6 +4649,7 @@ public abstract class PackageManager {
* the Android Keystore backed by an isolated execution environment. The version indicates
* which features are implemented in the isolated execution environment:
* <ul>
+ * <li>400: Inclusion of module information (via tag MODULE_HASH) in the attestation record.
* <li>300: Ability to include a second IMEI in the ID attestation record, see
* {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}.
* <li>200: Hardware support for Curve 25519 (including both Ed25519 signature generation and
@@ -4692,6 +4683,7 @@ public abstract class PackageManager {
* StrongBox</a>. If this feature has a version, the version number indicates which features are
* implemented in StrongBox:
* <ul>
+ * <li>400: Inclusion of module information (via tag MODULE_HASH) in the attestation record.
* <li>300: Ability to include a second IMEI in the ID attestation record, see
* {@link android.app.admin.DevicePolicyManager#ID_TYPE_IMEI}.
* <li>200: No new features for StrongBox (the Android Keystore environment backed by an
@@ -12023,11 +12015,8 @@ public abstract class PackageManager {
* file.
*
* @throws SigningInfoException if the verification fails
- *
- * @hide
*/
@FlaggedApi(android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static @NonNull SigningInfo getVerifiedSigningInfo(@NonNull String path,
@AppSigningSchemeVersion int minAppSigningSchemeVersion) throws SigningInfoException {
ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
@@ -12039,4 +12028,28 @@ public abstract class PackageManager {
}
return new SigningInfo(result.getResult());
}
+
+ /**
+ * As the generated feature count is useful for classes that may not be compiled in the same
+ * annotation processing unit as PackageManager, we redeclare it here for visibility.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static final int SDK_FEATURE_COUNT =
+ com.android.internal.pm.SystemFeaturesMetadata.SDK_FEATURE_COUNT;
+
+ /**
+ * Returns a stable index for PackageManager-defined features.
+ *
+ * <p> Similar to {@link #SDK_FEATURE_COUNT}, we redeclare this utility method generated by the
+ * annotation processor for internal visibility.
+ *
+ * @return index in [0, {@link #SDK_FEATURECOUNT}) for PackageManager-defined features, else -1.
+ * @hide
+ */
+ @VisibleForTesting
+ public static int maybeGetSdkFeatureIndex(String featureName) {
+ return com.android.internal.pm.SystemFeaturesMetadata.maybeGetSdkFeatureIndex(featureName);
+ }
}
diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java
index e4fbd1f28dbb..21bbb0a0a81c 100644
--- a/core/java/android/content/pm/SigningInfo.java
+++ b/core/java/android/content/pm/SigningInfo.java
@@ -22,7 +22,6 @@ import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.content.pm.SigningDetails.SignatureSchemeVersion;
import android.os.Parcel;
import android.os.Parcelable;
@@ -40,41 +39,29 @@ public final class SigningInfo implements Parcelable {
/**
* JAR signing (v1 scheme).
* See https://source.android.com/docs/security/features/apksigning#v1.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_JAR = SignatureSchemeVersion.JAR;
/**
* APK signature scheme v2.
* See https://source.android.com/docs/security/features/apksigning/v2.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V2 = SignatureSchemeVersion.SIGNING_BLOCK_V2;
/**
* APK signature scheme v3.
* See https://source.android.com/docs/security/features/apksigning/v3.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V3 = SignatureSchemeVersion.SIGNING_BLOCK_V3;
/**
* APK signature scheme v4.
* See https://source.android.com/docs/security/features/apksigning/v4.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public static final int VERSION_SIGNING_BLOCK_V4 = SignatureSchemeVersion.SIGNING_BLOCK_V4;
/** @hide */
@@ -255,11 +242,8 @@ public final class SigningInfo implements Parcelable {
/**
* Returns true if the signing certificates in this and other match exactly.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public boolean signersMatchExactly(@NonNull SigningInfo other) {
return mSigningDetails.signaturesMatchExactly(other.mSigningDetails);
}
diff --git a/core/java/android/content/pm/SigningInfoException.java b/core/java/android/content/pm/SigningInfoException.java
index a81e07e73685..2fd1bfb46f4c 100644
--- a/core/java/android/content/pm/SigningInfoException.java
+++ b/core/java/android/content/pm/SigningInfoException.java
@@ -19,17 +19,13 @@ package android.content.pm;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
/**
* Indicates an error when verifying the
* <a href="https://source.android.com/docs/security/features/apksigning">app signing</a>
* information.
- *
- * @hide
*/
@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM)
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public class SigningInfoException extends Exception {
private final int mCode;
diff --git a/core/java/android/content/pm/SystemFeaturesCache.aidl b/core/java/android/content/pm/SystemFeaturesCache.aidl
new file mode 100644
index 000000000000..18c1830a1859
--- /dev/null
+++ b/core/java/android/content/pm/SystemFeaturesCache.aidl
@@ -0,0 +1,19 @@
+/*
+** Copyright 2025, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.content.pm;
+
+parcelable SystemFeaturesCache;
diff --git a/core/java/android/content/pm/SystemFeaturesCache.java b/core/java/android/content/pm/SystemFeaturesCache.java
new file mode 100644
index 000000000000..c41a7abbbc35
--- /dev/null
+++ b/core/java/android/content/pm/SystemFeaturesCache.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * A simple cache for SDK-defined system feature versions.
+ *
+ * The dense representation minimizes any per-process memory impact (<1KB). The tradeoff is that
+ * custom, non-SDK defined features are not captured by the cache, for which we can rely on the
+ * usual IPC cache for related queries.
+ *
+ * @hide
+ */
+public final class SystemFeaturesCache implements Parcelable {
+
+ // Sentinel value used for SDK-declared features that are unavailable on the current device.
+ private static final int UNAVAILABLE_FEATURE_VERSION = Integer.MIN_VALUE;
+
+ // An array of versions for SDK-defined features, from [0, PackageManager.SDK_FEATURE_COUNT).
+ @NonNull
+ private final int[] mSdkFeatureVersions;
+
+ /**
+ * Populates the cache from the set of all available {@link FeatureInfo} definitions.
+ *
+ * System features declared in {@link PackageManager} will be entered into the cache based on
+ * availability in this feature set. Other custom system features will be ignored.
+ */
+ public SystemFeaturesCache(@NonNull ArrayMap<String, FeatureInfo> availableFeatures) {
+ this(availableFeatures.values());
+ }
+
+ @VisibleForTesting
+ public SystemFeaturesCache(@NonNull Collection<FeatureInfo> availableFeatures) {
+ // First set all SDK-defined features as unavailable.
+ mSdkFeatureVersions = new int[PackageManager.SDK_FEATURE_COUNT];
+ Arrays.fill(mSdkFeatureVersions, UNAVAILABLE_FEATURE_VERSION);
+
+ // Then populate SDK-defined feature versions from the full set of runtime features.
+ for (FeatureInfo fi : availableFeatures) {
+ int sdkFeatureIndex = PackageManager.maybeGetSdkFeatureIndex(fi.name);
+ if (sdkFeatureIndex >= 0) {
+ mSdkFeatureVersions[sdkFeatureIndex] = fi.version;
+ }
+ }
+ }
+
+ /** Only used by @{code CREATOR.createFromParcel(...)} */
+ private SystemFeaturesCache(@NonNull Parcel parcel) {
+ final int[] featureVersions = parcel.createIntArray();
+ if (featureVersions == null) {
+ throw new IllegalArgumentException(
+ "Parceled SDK feature versions should never be null");
+ }
+ if (featureVersions.length != PackageManager.SDK_FEATURE_COUNT) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Unexpected cached SDK feature count: %d (expected %d)",
+ featureVersions.length, PackageManager.SDK_FEATURE_COUNT));
+ }
+ mSdkFeatureVersions = featureVersions;
+ }
+
+ /**
+ * @return Whether the given feature is available (for SDK-defined features), otherwise null.
+ */
+ public Boolean maybeHasFeature(@NonNull String featureName, int version) {
+ // Features defined outside of the SDK aren't cached.
+ int sdkFeatureIndex = PackageManager.maybeGetSdkFeatureIndex(featureName);
+ if (sdkFeatureIndex < 0) {
+ return null;
+ }
+
+ // As feature versions can in theory collide with our sentinel value, in the (extremely)
+ // unlikely event that the queried version matches the sentinel value, we can't distinguish
+ // between an unavailable feature and a feature with the defined sentinel value.
+ if (version == UNAVAILABLE_FEATURE_VERSION
+ && mSdkFeatureVersions[sdkFeatureIndex] == UNAVAILABLE_FEATURE_VERSION) {
+ return null;
+ }
+
+ return mSdkFeatureVersions[sdkFeatureIndex] >= version;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
+ parcel.writeIntArray(mSdkFeatureVersions);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<SystemFeaturesCache> CREATOR =
+ new Parcelable.Creator<SystemFeaturesCache>() {
+
+ @Override
+ public SystemFeaturesCache createFromParcel(Parcel parcel) {
+ return new SystemFeaturesCache(parcel);
+ }
+
+ @Override
+ public SystemFeaturesCache[] newArray(int size) {
+ return new SystemFeaturesCache[size];
+ }
+ };
+}
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index dfeee2a2335f..62f1683d5e94 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -149,6 +149,13 @@ flag {
}
flag {
+ name: "cache_sdk_system_features"
+ namespace: "system_performance"
+ description: "Feature flag to enable optimized cache for SDK-defined system feature lookups."
+ bug: "326623529"
+}
+
+flag {
name: "provide_info_of_apk_in_apex"
is_exported: true
namespace: "package_manager_service"
@@ -362,3 +369,10 @@ flag {
is_fixed_read_only: true
}
+flag {
+ name: "cloud_compilation_verification"
+ namespace: "art_mainline"
+ description: "Feature flag to enable the Cloud Compilation install-time verification in the package manager."
+ bug: "377474232"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/content/pm/parsing/OWNERS b/core/java/android/content/pm/parsing/OWNERS
index 8049d5cb7fa2..b8fa1a93ed78 100644
--- a/core/java/android/content/pm/parsing/OWNERS
+++ b/core/java/android/content/pm/parsing/OWNERS
@@ -1,5 +1,3 @@
# Bug component: 36137
-chiuwinson@google.com
patb@google.com
-toddke@google.com
diff --git a/core/java/android/content/pm/permission/OWNERS b/core/java/android/content/pm/permission/OWNERS
index cf7e6890876a..8ef84745c99f 100644
--- a/core/java/android/content/pm/permission/OWNERS
+++ b/core/java/android/content/pm/permission/OWNERS
@@ -3,6 +3,5 @@
include platform/frameworks/base:/core/java/android/permission/OWNERS
toddke@android.com
-toddke@google.com
patb@google.com
diff --git a/core/java/android/gesture/OWNERS b/core/java/android/gesture/OWNERS
index 168630af6da4..ffa753aa65b2 100644
--- a/core/java/android/gesture/OWNERS
+++ b/core/java/android/gesture/OWNERS
@@ -3,5 +3,4 @@
romainguy@google.com
adamp@google.com
aurimas@google.com
-nduca@google.com
sumir@google.com
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index f649e476ffca..93cd18c505f5 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -324,6 +324,5 @@ public interface BiometricConstants {
* Returned from {@link BiometricManager#getLastAuthenticationTime(int)} when there has
* been no successful authentication for the given authenticator since boot.
*/
- @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
long BIOMETRIC_NO_AUTHENTICATION = -1;
}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index c690c67ed79f..cefe20c15ced 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -116,7 +116,6 @@ public class BiometricManager {
* Returned from {@link BiometricManager#getLastAuthenticationTime(int)} when no matching
* successful authentication has been performed since boot.
*/
- @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
public static final long BIOMETRIC_NO_AUTHENTICATION =
BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
@@ -777,7 +776,6 @@ public class BiometricManager {
*/
@RequiresPermission(USE_BIOMETRIC)
@ElapsedRealtimeLong
- @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
public long getLastAuthenticationTime(
@BiometricManager.Authenticators.Types int authenticators) {
if (authenticators == 0
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 73b6417a6ba4..4815f3e4f524 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -2,14 +2,6 @@ package: "android.hardware.biometrics"
container: "system"
flag {
- name: "last_authentication_time"
- is_exported: true
- namespace: "wallet_integration"
- description: "Feature flag for adding getLastAuthenticationTime API to BiometricManager"
- bug: "301979982"
-}
-
-flag {
name: "add_key_agreement_crypto_object"
is_exported: true
namespace: "biometrics"
diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS
index 37604bc2eb65..1de8a242acfc 100644
--- a/core/java/android/hardware/usb/OWNERS
+++ b/core/java/android/hardware/usb/OWNERS
@@ -1,7 +1,7 @@
# Bug component: 175220
-anothermark@google.com
+vmartensson@google.com
+nkapron@google.com
febinthattil@google.com
-aprasath@google.com
+shubhankarm@google.com
badhri@google.com
-kumarashishg@google.com \ No newline at end of file
diff --git a/core/java/android/metrics/OWNERS b/core/java/android/metrics/OWNERS
index ba867e0cad2b..98aaf3f47b21 100644
--- a/core/java/android/metrics/OWNERS
+++ b/core/java/android/metrics/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 26805
cwren@android.com
-cwren@google.com
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 95b5f697969e..da2cccde126f 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -37,3 +37,11 @@ flag {
description: "Flag to use checkServerTrusted to verify SCTs in OCSP and TLS Data"
bug: "319829948"
}
+
+flag {
+ name: "mdns_improvement_for_25q2"
+ is_exported: true
+ namespace: "android_core_networking"
+ description: "Flag for MDNS quality, reliability and performance improvement in 25Q2"
+ bug: "373270045"
+}
diff --git a/core/java/android/net/thread/flags.aconfig b/core/java/android/net/thread/flags.aconfig
index afb982ba64ca..100d50d8e70c 100644
--- a/core/java/android/net/thread/flags.aconfig
+++ b/core/java/android/net/thread/flags.aconfig
@@ -17,5 +17,5 @@ flag {
is_exported: true
namespace: "thread_network"
description: "Controls whether the Android Thread feature is enabled"
- bug: "301473012"
+ bug: "384596973"
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index ef1e6c9405f3..51aa06b93122 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -2741,4 +2741,12 @@ public final class Debug
*/
public static native boolean logAllocatorStats();
+ /**
+ * Return the amount of memory (in kB) allocated by kernel drivers through CMA.
+ * @return a non-negative value or -1 on error.
+ *
+ * @hide
+ */
+ public static native long getKernelCmaUsageKb();
+
}
diff --git a/core/java/android/os/EventLogTags.logtags b/core/java/android/os/EventLogTags.logtags
index b143a7443066..f57aad00e591 100644
--- a/core/java/android/os/EventLogTags.logtags
+++ b/core/java/android/os/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.os
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 8f6a50843ddb..12080ca511b2 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -78,6 +78,9 @@ public class GraphicsEnvironment {
private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time";
+ /// System properties related to EGL
+ private static final String PROPERTY_RO_HARDWARE_EGL = "ro.hardware.egl";
+
// Metadata flags within the <application> tag in the AndroidManifest.xml file.
private static final String METADATA_DRIVER_BUILD_TIME =
"com.android.graphics.driver.build_time";
@@ -504,9 +507,11 @@ public class GraphicsEnvironment {
final List<ResolveInfo> resolveInfos =
pm.queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
- if (resolveInfos.size() != 1) {
- Log.v(TAG, "Invalid number of ANGLE packages. Required: 1, Found: "
- + resolveInfos.size());
+ if (resolveInfos.isEmpty()) {
+ Log.v(TAG, "No ANGLE packages installed.");
+ return "";
+ } else if (resolveInfos.size() > 1) {
+ Log.v(TAG, "Too many ANGLE packages found: " + resolveInfos.size());
if (DEBUG) {
for (ResolveInfo resolveInfo : resolveInfos) {
Log.d(TAG, "Found ANGLE package: " + resolveInfo.activityInfo.packageName);
@@ -516,7 +521,7 @@ public class GraphicsEnvironment {
}
// Must be exactly 1 ANGLE PKG found to get here.
- return resolveInfos.get(0).activityInfo.packageName;
+ return resolveInfos.getFirst().activityInfo.packageName;
}
/**
@@ -545,10 +550,12 @@ public class GraphicsEnvironment {
}
/**
- * Determine whether ANGLE should be used, attempt to set up from apk first, if ANGLE can be
- * set up from apk, pass ANGLE details down to the C++ GraphicsEnv class via
- * GraphicsEnv::setAngleInfo(). If apk setup fails, attempt to set up to use system ANGLE.
- * Return false if both fail.
+ * If ANGLE is not the system driver, determine whether ANGLE should be used, and if so, pass
+ * down the necessary details to the C++ GraphicsEnv class via GraphicsEnv::setAngleInfo().
+ * <p>
+ * If ANGLE is the system driver or the various flags indicate it should be used, attempt to
+ * set up ANGLE from the APK first, so the updatable libraries are used. If APK setup fails,
+ * attempt to set up the system ANGLE. Return false if both fail.
*
* @param context - Context of the application.
* @param bundle - Bundle of the application.
@@ -559,15 +566,26 @@ public class GraphicsEnvironment {
*/
private boolean setupAngle(Context context, Bundle bundle, PackageManager packageManager,
String packageName) {
- final String angleChoice = queryAngleChoice(context, bundle, packageName);
- if (angleChoice.equals(ANGLE_GL_DRIVER_CHOICE_DEFAULT)) {
- return false;
- }
- if (angleChoice.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)) {
- nativeSetAngleInfo("", true, packageName, null);
- return false;
+ final String eglDriverName = SystemProperties.get(PROPERTY_RO_HARDWARE_EGL);
+
+ // The ANGLE choice only makes sense if ANGLE is not the system driver.
+ if (!eglDriverName.equals(ANGLE_DRIVER_NAME)) {
+ final String angleChoice = queryAngleChoice(context, bundle, packageName);
+ if (angleChoice.equals(ANGLE_GL_DRIVER_CHOICE_DEFAULT)) {
+ return false;
+ }
+ if (angleChoice.equals(ANGLE_GL_DRIVER_CHOICE_NATIVE)) {
+ nativeSetAngleInfo("", true, packageName, null);
+ return false;
+ }
}
+ // If we reach here, it means either:
+ // 1. system driver is not ANGLE, but ANGLE is requested.
+ // 2. system driver is ANGLE.
+ // In both cases, setup ANGLE info. We attempt to setup the APK first, so
+ // updated/development libraries are used if the APK is present, falling back to the system
+ // libraries otherwise.
return setupAngleFromApk(context, bundle, packageManager, packageName)
|| setupAngleFromSystem(context, bundle, packageName);
}
@@ -605,7 +623,6 @@ public class GraphicsEnvironment {
if (angleInfo == null) {
anglePkgName = getAnglePackageName(packageManager);
if (TextUtils.isEmpty(anglePkgName)) {
- Log.v(TAG, "Failed to find ANGLE package.");
return false;
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index d0828c384664..eaecd34b9d75 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -20,6 +20,7 @@ import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.util.Log;
import android.util.Printer;
@@ -839,6 +840,7 @@ public class Handler {
*@hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
@FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API)
public final void removeEqualMessages(int what, @Nullable Object object) {
mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object));
@@ -872,6 +874,7 @@ public class Handler {
*@hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
@FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API)
public final void removeCallbacksAndEqualMessages(@Nullable Object token) {
mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token));
@@ -889,6 +892,7 @@ public class Handler {
* @hide
*/
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ @TestApi
@FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API)
public final boolean hasMessagesOrCallbacks() {
return mQueue.hasMessages(this);
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index ddf2b61324ad..2fe4871e08dd 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -70,6 +70,13 @@ public final class Looper {
private static final String TAG = "Looper";
+ private static class NoImagePreloadHolder {
+ // Enable/Disable verbose logging with a system prop. e.g.
+ // adb shell 'setprop log.looper.slow.verbose false && stop && start'
+ private static final boolean sVerboseLogging =
+ SystemProperties.getBoolean("log.looper.slow.verbose", false);
+ }
+
// sThreadLocal.get() will return null unless you've called prepare().
@UnsupportedAppUsage
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
@@ -246,17 +253,21 @@ public final class Looper {
}
}
if (logSlowDelivery) {
+ boolean slow = false;
+
+ if (!me.mSlowDeliveryDetected || NoImagePreloadHolder.sVerboseLogging) {
+ slow = showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart,
+ "delivery", msg);
+ }
if (me.mSlowDeliveryDetected) {
- if ((dispatchStart - msg.when) <= 10) {
+ if (!slow && (dispatchStart - msg.when) <= 10) {
Slog.w(TAG, "Drained");
me.mSlowDeliveryDetected = false;
}
- } else {
- if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
- msg)) {
- // Once we write a slow delivery log, suppress until the queue drains.
- me.mSlowDeliveryDetected = true;
- }
+ } else if (slow) {
+ // A slow delivery is detected, suppressing further logs unless verbose logging
+ // is enabled.
+ me.mSlowDeliveryDetected = true;
}
}
if (logSlowDispatch) {
@@ -322,6 +333,23 @@ public final class Looper {
@android.ravenwood.annotation.RavenwoodReplace
private static int getThresholdOverride() {
+ // Allow overriding the threshold for all processes' main looper with a system prop.
+ // e.g. adb shell 'setprop log.looper.any.main.slow 1 && stop && start'
+ if (myLooper() == getMainLooper()) {
+ final int globalOverride = SystemProperties.getInt("log.looper.any.main.slow", -1);
+ if (globalOverride >= 0) {
+ return globalOverride;
+ }
+ }
+
+ // Allow overriding the threshold for all threads within a process with a system prop.
+ // e.g. adb shell 'setprop log.looper.1000.any.slow 1 && stop && start'
+ final int processOverride = SystemProperties.getInt("log.looper."
+ + Process.myUid() + ".any.slow", -1);
+ if (processOverride >= 0) {
+ return processOverride;
+ }
+
return SystemProperties.getInt("log.looper."
+ Process.myUid() + "."
+ Thread.currentThread().getName()
@@ -332,16 +360,55 @@ public final class Looper {
return -1;
}
+ private static int getThreadGroup() {
+ int threadGroup = Process.THREAD_GROUP_DEFAULT;
+
+ if (!Process.isIsolated()) {
+ threadGroup = Process.getProcessGroup(Process.myTid());
+ }
+ return threadGroup;
+ }
+
+ private static String threadGroupToString(int threadGroup) {
+ switch (threadGroup) {
+ case Process.THREAD_GROUP_BACKGROUND:
+ return "BACKGROUND";
+ case Process.THREAD_GROUP_FOREGROUND:
+ return "FOREGROUND";
+ case Process.THREAD_GROUP_SYSTEM:
+ return "SYSTEM";
+ case Process.THREAD_GROUP_AUDIO_APP:
+ return "AUDIO_APP";
+ case Process.THREAD_GROUP_AUDIO_SYS:
+ return "AUDIO_SYS";
+ case Process.THREAD_GROUP_TOP_APP:
+ return "TOP_APP";
+ case Process.THREAD_GROUP_RT_APP:
+ return "RT_APP";
+ case Process.THREAD_GROUP_RESTRICTED:
+ return "RESTRICTED";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
private static boolean showSlowLog(long threshold, long measureStart, long measureEnd,
String what, Message msg) {
final long actualTime = measureEnd - measureStart;
if (actualTime < threshold) {
return false;
}
+
+ String name = Process.myProcessName();
+ String threadGroup = threadGroupToString(getThreadGroup());
+ boolean isMain = myLooper() == getMainLooper();
+
// For slow delivery, the current message isn't really important, but log it anyway.
Slog.w(TAG, "Slow " + what + " took " + actualTime + "ms "
- + Thread.currentThread().getName() + " h="
- + msg.target.getClass().getName() + " c=" + msg.callback + " m=" + msg.what);
+ + Thread.currentThread().getName() + " app=" + name
+ + " main=" + isMain + " group=" + threadGroup
+ + " h=" + msg.target.getClass().getName() + " c=" + msg.callback
+ + " m=" + msg.what);
return true;
}
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 8d353384f1e2..a6785bab56f3 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -4,6 +4,8 @@ per-file *Vibrator* = file:/services/core/java/com/android/server/vibrator/OWNER
# PowerManager
per-file IPowerManager.aidl = file:/services/core/java/com/android/server/power/OWNERS
+per-file IScreenTimeoutPolicyListener.aidl = file:/services/core/java/com/android/server/power/OWNERS
+per-file IWakeLockCallback.aidl = file:/services/core/java/com/android/server/power/OWNERS
per-file PowerManager.java = file:/services/core/java/com/android/server/power/OWNERS
per-file PowerManagerInternal.java = file:/services/core/java/com/android/server/power/OWNERS
@@ -76,7 +78,7 @@ per-file Trace.java = file:/TRACE_OWNERS
per-file PatternMatcher* = file:/PACKAGE_MANAGER_OWNERS
# PermissionEnforcer
-per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com
+per-file PermissionEnforcer.java = tweek@google.com
# RemoteCallbackList
per-file RemoteCallbackList.java = shayba@google.com
@@ -115,13 +117,20 @@ per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
# Performance
per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
+# Processes, threads, and scheduling
+per-file Process.java = file:/PERFORMANCE_OWNERS
+
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
# MessageQueue and related classes
per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file Looper.java = mfasheh@google.com, shayba@google.com
per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
+per-file Handler.java = mfasheh@google.com, shayba@google.com
+per-file HandlerThread.java = mfasheh@google.com, shayba@google.com
+per-file HandlerExecutor.java = mfasheh@google.com, shayba@google.com
# Stats
per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e7282435ad46..907d96834857 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -553,10 +553,9 @@ public class Process {
* Foreground thread group - All threads in
* this group are scheduled with a normal share of the CPU.
* Value is same as constant SP_FOREGROUND of enum SchedPolicy.
- * Not used at this level.
* @hide
**/
- private static final int THREAD_GROUP_FOREGROUND = 1;
+ public static final int THREAD_GROUP_FOREGROUND = 1;
/**
* System thread group.
@@ -1315,19 +1314,6 @@ public class Process {
}
/**
- * Adjust the swappiness level for a process.
- *
- * @param pid The process identifier to set.
- * @param is_increased Whether swappiness should be increased or default.
- *
- * @return Returns true if the underlying system supports this
- * feature, else false.
- *
- * {@hide}
- */
- public static final native boolean setSwappiness(int pid, boolean is_increased);
-
- /**
* Change this process's argv[0] parameter. This can be useful to show
* more descriptive information in things like the 'ps' command.
*
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 9085fe09bdaa..a58fea891851 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -278,7 +278,7 @@ public final class ServiceManager {
return service;
} else {
return Binder.allowBlocking(
- getIServiceManager().checkService(name).getServiceWithMetadata().service);
+ getIServiceManager().checkService2(name).getServiceWithMetadata().service);
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 49b696d95723..a5aa1b3efcd2 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -50,7 +50,8 @@ public final class ServiceManagerNative {
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
- mServiceManager = IServiceManager.Stub.asInterface(this.getNativeServiceManager());
+ mServiceManager = IServiceManager.Stub.asInterface(
+ Binder.allowBlocking(this.getNativeServiceManager()));
}
public IBinder asBinder() {
@@ -61,16 +62,23 @@ class ServiceManagerProxy implements IServiceManager {
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException {
// Same as checkService (old versions of servicemanager had both methods).
- return checkService(name).getServiceWithMetadata().service;
+ return checkService2(name).getServiceWithMetadata().service;
}
public Service getService2(String name) throws RemoteException {
// Same as checkService (old versions of servicemanager had both methods).
- return checkService(name);
+ return checkService2(name);
}
- public Service checkService(String name) throws RemoteException {
- return mServiceManager.checkService(name);
+ // TODO(b/355394904): This function has been deprecated, please use checkService2 instead.
+ @UnsupportedAppUsage
+ public IBinder checkService(String name) throws RemoteException {
+ // Same as checkService (old versions of servicemanager had both methods).
+ return checkService2(name).getServiceWithMetadata().service;
+ }
+
+ public Service checkService2(String name) throws RemoteException {
+ return mServiceManager.checkService2(name);
}
public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 46ae9d8682ee..320641ded0f9 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -25,8 +25,6 @@ import android.system.OsConstants;
import dalvik.system.VMRuntime;
-import libcore.io.IoUtils;
-
import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -65,7 +63,7 @@ public final class SharedMemory implements Parcelable, Closeable {
mMemoryRegistration = new MemoryRegistration(mSize);
mCleaner = Cleaner.create(mFileDescriptor,
- new Closer(mFileDescriptor, mMemoryRegistration));
+ new Closer(mFileDescriptor.getInt$(), mMemoryRegistration));
}
/**
@@ -278,6 +276,7 @@ public final class SharedMemory implements Parcelable, Closeable {
*/
@Override
public void close() {
+ mFileDescriptor.setInt$(-1);
if (mCleaner != null) {
mCleaner.clean();
mCleaner = null;
@@ -327,20 +326,21 @@ public final class SharedMemory implements Parcelable, Closeable {
* Cleaner that closes the FD
*/
private static final class Closer implements Runnable {
- private FileDescriptor mFd;
+ private int mFd;
private MemoryRegistration mMemoryReference;
- private Closer(FileDescriptor fd, MemoryRegistration memoryReference) {
+ private Closer(int fd, MemoryRegistration memoryReference) {
mFd = fd;
- IoUtils.setFdOwner(mFd, this);
mMemoryReference = memoryReference;
}
@Override
public void run() {
- IoUtils.closeQuietly(mFd);
- mFd = null;
-
+ try {
+ FileDescriptor fd = new FileDescriptor();
+ fd.setInt$(mFd);
+ Os.close(fd);
+ } catch (ErrnoException e) { /* swallow error */ }
mMemoryReference.release();
mMemoryReference = null;
}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 2a467386569d..df73ec697050 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -183,6 +183,13 @@ flag {
}
flag {
+ name: "disable_madvise_artfile_default"
+ namespace: "system_performance"
+ description: "Disables madvise of .art files by default during app start."
+ bug: "382110550"
+}
+
+flag {
name: "disallow_cellular_null_ciphers_restriction"
namespace: "cellular_security"
description: "Guards a new UserManager user restriction that admins can use to require cellular encryption on their managed devices."
diff --git a/core/java/android/os/health/OWNERS b/core/java/android/os/health/OWNERS
index 6045344126c0..26fc8fae8f45 100644
--- a/core/java/android/os/health/OWNERS
+++ b/core/java/android/os/health/OWNERS
@@ -2,3 +2,6 @@
dplotnikov@google.com
mwachens@google.com
+
+# for headroom API only
+xwxw@google.com \ No newline at end of file
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 2473de4ff6d7..054609d015cb 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1716,20 +1716,14 @@ public final class PermissionManager {
private static int checkPermissionUncached(@Nullable String permission, int pid, int uid,
int deviceId) {
+ final int appId = UserHandle.getAppId(uid);
+ if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
+ return PackageManager.PERMISSION_GRANTED;
+ }
final IActivityManager am = ActivityManager.getService();
if (am == null) {
- // Well this is super awkward; we somehow don't have an active ActivityManager
- // instance. If we're testing a root or system UID, then they totally have whatever
- // permission this is.
- final int appId = UserHandle.getAppId(uid);
- if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
- if (sShouldWarnMissingActivityManager) {
- Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " holds "
- + permission);
- sShouldWarnMissingActivityManager = false;
- }
- return PackageManager.PERMISSION_GRANTED;
- }
+ // We don't have an active ActivityManager instance and the calling UID is not root or
+ // system, so we don't grant this permission.
Slog.w(LOG_TAG, "Missing ActivityManager; assuming " + uid + " does not hold "
+ permission);
return PackageManager.PERMISSION_DENIED;
diff --git a/core/java/android/preference/OWNERS b/core/java/android/preference/OWNERS
index b4cb9ec7ceda..38a5abd8ff56 100644
--- a/core/java/android/preference/OWNERS
+++ b/core/java/android/preference/OWNERS
@@ -1,5 +1,4 @@
lpf@google.com
-pavlis@google.com
clarabayarri@google.com
-per-file SeekBarVolumizer.java = jmtrivi@google.com \ No newline at end of file
+per-file SeekBarVolumizer.java = jmtrivi@google.com
diff --git a/core/java/android/print/OWNERS b/core/java/android/print/OWNERS
index ce79f5d0c669..15f640650868 100644
--- a/core/java/android/print/OWNERS
+++ b/core/java/android/print/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 47273
anothermark@google.com
-kumarashishg@google.com
bmgordon@google.com
diff --git a/core/java/android/printservice/OWNERS b/core/java/android/printservice/OWNERS
index ce79f5d0c669..15f640650868 100644
--- a/core/java/android/printservice/OWNERS
+++ b/core/java/android/printservice/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 47273
anothermark@google.com
-kumarashishg@google.com
bmgordon@google.com
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 34bae46b484c..cdecaced33f2 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -42,6 +42,16 @@ flag {
}
flag {
+ name: "secure_array_zeroization"
+ namespace: "security"
+ description: "Enable secure array zeroization"
+ bug: "320392352"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "deprecate_fsv_sig"
namespace: "hardware_backed_security"
description: "Feature flag for deprecating .fsv_sig"
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index d9cc82a77a85..029b674b6be1 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -16,16 +16,17 @@
package android.security.net.config;
+import android.util.ArrayMap;
+
import com.android.org.conscrypt.TrustManagerImpl;
-import android.util.ArrayMap;
import java.io.IOException;
import java.net.Socket;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -105,7 +106,7 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
/**
* Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
- * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
* modify without modifying those callers.
*/
public List<X509Certificate> checkServerTrusted(X509Certificate[] certs, String authType,
@@ -115,6 +116,19 @@ public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
return trustedChain;
}
+ /**
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * modify without modifying those callers.
+ */
+ public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+ byte[] ocspData, byte[] tlsSctData, String authType,
+ String host) throws CertificateException {
+ List<X509Certificate> trustedChain = mDelegate.checkServerTrusted(
+ certs, ocspData, tlsSctData, authType, host);
+ checkPins(trustedChain);
+ return trustedChain;
+ }
+
private void checkPins(List<X509Certificate> chain) throws CertificateException {
PinSet pinSet = mNetworkSecurityConfig.getPins();
if (pinSet.pins.isEmpty()
diff --git a/core/java/android/security/net/config/OWNERS b/core/java/android/security/net/config/OWNERS
index 85ce3c63f18b..e945ff98a96f 100644
--- a/core/java/android/security/net/config/OWNERS
+++ b/core/java/android/security/net/config/OWNERS
@@ -1,5 +1,6 @@
-# Bug component: 36824
-set noparent
+# Bug component: 1479456
-cbrubaker@google.com
+bessiej@google.com
brambonne@google.com
+sandrom@google.com
+tweek@google.com
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index 58dc4ba8df21..a1bdec5280db 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -120,7 +120,7 @@ public class RootTrustManager extends X509ExtendedTrustManager {
/**
* Hostname aware version of {@link #checkServerTrusted(X509Certificate[], String)}.
- * This interface is used by conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
* modify without modifying those callers.
*/
@UnsupportedAppUsage
@@ -134,6 +134,22 @@ public class RootTrustManager extends X509ExtendedTrustManager {
return config.getTrustManager().checkServerTrusted(certs, authType, hostname);
}
+ /**
+ * This interface is used by Conscrypt and android.net.http.X509TrustManagerExtensions do not
+ * modify without modifying those callers.
+ */
+ public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
+ byte[] ocspData, byte[] tlsSctData, String authType,
+ String hostname) throws CertificateException {
+ if (hostname == null && mConfig.hasPerDomainConfigs()) {
+ throw new CertificateException(
+ "Domain specific configurations require that the hostname be provided");
+ }
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(hostname);
+ return config.getTrustManager().checkServerTrusted(
+ certs, ocspData, tlsSctData, authType, hostname);
+ }
+
@Override
public X509Certificate[] getAcceptedIssuers() {
// getAcceptedIssuers is meant to be used to determine which trust anchors the server will
diff --git a/core/java/android/speech/OWNERS b/core/java/android/speech/OWNERS
index 32f482264103..f228ba46be0c 100644
--- a/core/java/android/speech/OWNERS
+++ b/core/java/android/speech/OWNERS
@@ -1,3 +1,2 @@
-volnov@google.com
eugeniom@google.com
schfan@google.com
diff --git a/core/java/android/text/OWNERS b/core/java/android/text/OWNERS
index 0935ffd9dd81..b493ef7009d9 100644
--- a/core/java/android/text/OWNERS
+++ b/core/java/android/text/OWNERS
@@ -4,7 +4,6 @@ grantapher@google.com
halilibo@google.com
haoyuchang@google.com
justinghan@google.com
-klippenstein@google.com
nona@google.com
seanmcq@google.com
siyamed@google.com
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index cb72b976c784..6dc82c40ddc5 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -678,7 +678,7 @@ public class TextUtils {
* @return true if a and b are equal
*/
@android.ravenwood.annotation.RavenwoodKeep
- public static boolean equals(CharSequence a, CharSequence b) {
+ public static boolean equals(@Nullable CharSequence a, @Nullable CharSequence b) {
if (a == b) return true;
int length;
if (a != null && b != null && (length = a.length()) == b.length()) {
diff --git a/core/java/android/util/apk/OWNERS b/core/java/android/util/apk/OWNERS
index 0f4e869f8b9a..f267f9a4edb6 100644
--- a/core/java/android/util/apk/OWNERS
+++ b/core/java/android/util/apk/OWNERS
@@ -1,3 +1,2 @@
include /core/java/android/content/pm/OWNERS
-cbrubaker@google.com
mpgroover@google.com
diff --git a/core/java/android/view/EventLogTags.logtags b/core/java/android/view/EventLogTags.logtags
index f3792930647a..95894fa32d6b 100644
--- a/core/java/android/view/EventLogTags.logtags
+++ b/core/java/android/view/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.view
@@ -35,7 +35,7 @@ option java_package android.view
# 6: Percent
# Default value for data of type int/long is 2 (bytes).
#
-# See system/core/logcat/event.logtags for the master copy of the tags.
+# See system/logging/logcat/event.logtags for the master copy of the tags.
# 32000 - 32999 reserved for input method framework
# IME animation is started.
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index acbd95bf6810..85f0251187eb 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -190,7 +190,7 @@ public class InsetsSourceControl implements Parcelable {
}
public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) {
- if (mLeash != null) {
+ if (mLeash != null && mLeash.isValid()) {
surfaceReleaseConsumer.accept(mLeash);
}
}
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index 80484a6328e0..3353923292e1 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -3,7 +3,6 @@
romainguy@google.com
adamp@google.com
aurimas@google.com
-nduca@google.com
sumir@google.com
ogunwale@google.com
jjaggi@google.com
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index b21e85aeeb6a..da3a817f0341 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -514,10 +514,14 @@ public final class PointerIcon implements Parcelable {
final TypedArray a = resources.obtainAttributes(
parser, com.android.internal.R.styleable.PointerIcon);
bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0);
- hotSpotX = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0)
- * pointerScale;
- hotSpotY = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0)
- * pointerScale;
+ // Cast the hotspot dimensions to int before scaling to match the scaling logic of
+ // the bitmap, whose intrinsic size is also an int before it is scaled.
+ final int unscaledHotSpotX =
+ (int) a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
+ final int unscaledHotSpotY =
+ (int) a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
+ hotSpotX = unscaledHotSpotX * pointerScale;
+ hotSpotY = unscaledHotSpotY * pointerScale;
a.recycle();
} catch (Exception ex) {
throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index dd9a95e58bd1..a32d6df3d2fe 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -4803,7 +4803,7 @@ public final class SurfaceControl implements Parcelable {
/**
* @hide
*/
- public Transaction setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
+ public Transaction setDestinationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
checkPreconditions(sc);
nativeSetDestinationFrame(mNativeObject, sc.mNativeObject,
destinationFrame.left, destinationFrame.top, destinationFrame.right,
@@ -4814,7 +4814,7 @@ public final class SurfaceControl implements Parcelable {
/**
* @hide
*/
- public Transaction setDesintationFrame(SurfaceControl sc, int width, int height) {
+ public Transaction setDestinationFrame(SurfaceControl sc, int width, int height) {
checkPreconditions(sc);
nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 0, 0, width, height);
return this;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b0051cefb21b..780e76122e8a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1125,7 +1125,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
- surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
+ surfaceUpdateTransaction.setDestinationFrame(mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
if (isHardwareAccelerated()) {
diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS
index f62b33f1f753..799ef0091f71 100644
--- a/core/java/android/view/accessibility/OWNERS
+++ b/core/java/android/view/accessibility/OWNERS
@@ -1,4 +1,7 @@
-# Bug component: 44215
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
# Android Accessibility Framework owners
include /services/accessibility/OWNERS
diff --git a/core/java/android/view/contentcapture/OWNERS b/core/java/android/view/contentcapture/OWNERS
index 9ac273f515e7..30f4cae4bf19 100644
--- a/core/java/android/view/contentcapture/OWNERS
+++ b/core/java/android/view/contentcapture/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 544200
-hackz@google.com
-shivanker@google.com
+dariofreni@google.com
+klikli@google.com
+shikhamalhotra@google.com
diff --git a/core/java/android/view/inspector/OWNERS b/core/java/android/view/inspector/OWNERS
index 705f4b342d42..f3450344ea81 100644
--- a/core/java/android/view/inspector/OWNERS
+++ b/core/java/android/view/inspector/OWNERS
@@ -2,5 +2,4 @@ romainguy@google.com
alanv@google.com
adamp@google.com
aurimas@google.com
-nduca@google.com
sumir@google.com
diff --git a/core/java/android/view/textclassifier/intent/OWNERS b/core/java/android/view/textclassifier/intent/OWNERS
index 3465fe62784f..4a5dfd8501be 100644
--- a/core/java/android/view/textclassifier/intent/OWNERS
+++ b/core/java/android/view/textclassifier/intent/OWNERS
@@ -1,7 +1,5 @@
# Bug component: 709498
-mns@google.com
toki@google.com
svetoslavganov@android.com
-svetoslavganov@google.com
joannechung@google.com
diff --git a/core/java/android/window/OWNERS b/core/java/android/window/OWNERS
index 77c99b98cf4a..82d37244dc70 100644
--- a/core/java/android/window/OWNERS
+++ b/core/java/android/window/OWNERS
@@ -3,3 +3,4 @@ set noparent
include /services/core/java/com/android/server/wm/OWNERS
per-file DesktopModeFlags.java = file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+per-file DesktopExperienceFlags.java = file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
diff --git a/core/java/com/android/internal/accessibility/OWNERS b/core/java/com/android/internal/accessibility/OWNERS
index 1265dfa2c441..dac64f47ba7e 100644
--- a/core/java/com/android/internal/accessibility/OWNERS
+++ b/core/java/com/android/internal/accessibility/OWNERS
@@ -1,4 +1,7 @@
-# Bug component: 44215
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
# Android Accessibility Framework owners
include /services/accessibility/OWNERS \ No newline at end of file
diff --git a/core/java/com/android/internal/app/EventLogTags.logtags b/core/java/com/android/internal/app/EventLogTags.logtags
index d681a8d26e8e..a18a8243305b 100644
--- a/core/java/com/android/internal/app/EventLogTags.logtags
+++ b/core/java/com/android/internal/app/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.app;
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 644d69919998..9d7bedc4d0c3 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -689,14 +689,15 @@ public class IntentForwarderActivity extends Activity {
}
private void setMiniresolverPadding() {
- Insets systemWindowInsets =
- getWindowManager().getCurrentWindowMetrics().getWindowInsets().getInsets(
- WindowInsets.Type.systemBars());
-
View buttonContainer = findViewById(R.id.button_bar_container);
- buttonContainer.setPadding(0, 0, 0,
- systemWindowInsets.bottom + getResources().getDimensionPixelOffset(
- R.dimen.resolver_button_bar_spacing));
+ if (buttonContainer != null) {
+ Insets systemWindowInsets =
+ getWindowManager().getCurrentWindowMetrics().getWindowInsets().getInsets(
+ WindowInsets.Type.systemBars());
+ buttonContainer.setPadding(0, 0, 0,
+ systemWindowInsets.bottom + getResources().getDimensionPixelOffset(
+ R.dimen.resolver_button_bar_spacing));
+ }
}
@VisibleForTesting
diff --git a/core/java/com/android/internal/app/NfcResolverActivity.java b/core/java/com/android/internal/app/NfcResolverActivity.java
index 78427fe91088..f15dbd65832a 100644
--- a/core/java/com/android/internal/app/NfcResolverActivity.java
+++ b/core/java/com/android/internal/app/NfcResolverActivity.java
@@ -34,13 +34,13 @@ public class NfcResolverActivity extends ResolverActivity {
@Override
@SuppressWarnings("MissingSuperCall") // Called indirectly via `super_onCreate()`.
protected void onCreate(Bundle savedInstanceState) {
- if (!enableNfcMainline()) {
+ Intent intent = getIntent();
+ if (!enableNfcMainline() || intent.getExtras() == null) {
super_onCreate(savedInstanceState);
finish();
return;
}
- Intent intent = getIntent();
Intent target = intent.getParcelableExtra(Intent.EXTRA_INTENT, Intent.class);
ArrayList<ResolveInfo> rList =
intent.getParcelableArrayListExtra(
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 52f18fb80c27..0bba24d4ce19 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -20,3 +20,6 @@ per-file *VisualQuery* = file:/core/java/android/service/voice/OWNERS
# System language settings
per-file *Locale* = file:platform/packages/apps/Settings:/src/com/android/settings/localepicker/OWNERS
+
+# Media
+per-file *MediaRoute* = file:/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index a1945352ae09..db65d31f59da 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -929,8 +929,11 @@ public class ResolverActivity extends Activity implements
if (shouldUseMiniResolver()) {
View buttonContainer = findViewById(R.id.button_bar_container);
- buttonContainer.setPadding(0, 0, 0, mSystemWindowInsets.bottom
- + getResources().getDimensionPixelOffset(R.dimen.resolver_button_bar_spacing));
+ if (buttonContainer != null) {
+ buttonContainer.setPadding(0, 0, 0, mSystemWindowInsets.bottom
+ + getResources().getDimensionPixelOffset(
+ R.dimen.resolver_button_bar_spacing));
+ }
}
// Need extra padding so the list can fully scroll up
diff --git a/core/java/com/android/internal/config/appcloning/OWNERS b/core/java/com/android/internal/config/appcloning/OWNERS
index 0645a8c54414..9369438deb07 100644
--- a/core/java/com/android/internal/config/appcloning/OWNERS
+++ b/core/java/com/android/internal/config/appcloning/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 1207885
jigarthakkar@google.com
-saumyap@google.com \ No newline at end of file
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index ad7329485a0e..4663d62896a2 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -36,6 +36,7 @@ import android.util.Log;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.annotations.WeaklyReferencedCallback;
import com.android.internal.os.BackgroundThread;
import java.lang.ref.WeakReference;
@@ -46,6 +47,7 @@ import java.util.concurrent.Executor;
* Helper class for monitoring the state of packages: adding, removing,
* updating, and disappearing and reappearing on the SD card.
*/
+@WeaklyReferencedCallback
public abstract class PackageMonitor extends android.content.BroadcastReceiver {
static final String TAG = "PackageMonitor";
diff --git a/core/java/com/android/internal/graphics/palette/OWNERS b/core/java/com/android/internal/graphics/palette/OWNERS
index 731dca9b128f..df867252c01c 100644
--- a/core/java/com/android/internal/graphics/palette/OWNERS
+++ b/core/java/com/android/internal/graphics/palette/OWNERS
@@ -1,3 +1,2 @@
-# Bug component: 484670
-dupin@google.com
-jamesoleary@google.com \ No newline at end of file
+# Bug component: 484670
+dupin@google.com
diff --git a/core/java/com/android/internal/infra/OWNERS b/core/java/com/android/internal/infra/OWNERS
index 45503582b2c5..e69de29bb2d1 100644
--- a/core/java/com/android/internal/infra/OWNERS
+++ b/core/java/com/android/internal/infra/OWNERS
@@ -1,6 +0,0 @@
-per-file AndroidFuture.java = eugenesusla@google.com
-per-file RemoteStream.java = eugenesusla@google.com
-per-file PerUser.java = eugenesusla@google.com
-per-file ServiceConnector.java = eugenesusla@google.com
-per-file AndroidFuture.aidl = eugenesusla@google.com
-per-file IAndroidFuture.aidl = eugenesusla@google.com \ No newline at end of file
diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags
index 693bd16e6170..db47797cb03d 100644
--- a/core/java/com/android/internal/logging/EventLogTags.logtags
+++ b/core/java/com/android/internal/logging/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.logging;
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
index c85b5d7aa7a6..af763e4c5fa9 100644
--- a/core/java/com/android/internal/os/BaseCommand.java
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -58,15 +58,23 @@ public abstract class BaseCommand {
mRawArgs = args;
mArgs.init(null, null, null, null, args, 0);
+ int status = 1;
try {
onRun();
+ status = 0;
} catch (IllegalArgumentException e) {
onShowUsage(System.err);
System.err.println();
System.err.println("Error: " + e.getMessage());
+ status = 0;
} catch (Exception e) {
e.printStackTrace(System.err);
- System.exit(1);
+ } finally {
+ System.out.flush();
+ System.err.flush();
+ }
+ if (status != 0) {
+ System.exit(status);
}
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 1709ca78af4b..f6de3459a1f5 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -174,7 +174,9 @@ public class RuntimeInit {
// System process is dead; ignore
} else {
try {
- Clog_e(TAG, "Error reporting crash", t2);
+ // Log original crash and then log the error reporting exception.
+ Clog_e(TAG, "Couldn't report crash. Here's the crash:", e);
+ Clog_e(TAG, "Error reporting crash. Here's the error:", t2);
} catch (Throwable t3) {
// Even Clog_e() fails! Oh well.
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index e60879e02b4b..38dc198fa9f8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -429,6 +429,27 @@ public class ZygoteInit {
null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
}
+ if (Flags.enableMediaAndLocationPreload()) {
+ // As these libraries are technically optional and not necessarily inherited from
+ // base_system.mk, only cache them if they exist.
+ final String mediaJarPath = "/system/framework/com.android.media.remotedisplay.jar";
+ if (new File(mediaJarPath).exists()) {
+ libs.add(new SharedLibraryInfo(
+ mediaJarPath, null /*packageName*/,
+ null /*codePaths*/, null /*name*/, 0 /*version*/,
+ SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
+ null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
+ }
+ final String locationJarPath = "/system/framework/com.android.location.provider.jar";
+ if (new File(locationJarPath).exists()) {
+ libs.add(new SharedLibraryInfo(
+ locationJarPath, null /*packageName*/,
+ null /*codePaths*/, null /*name*/, 0 /*version*/,
+ SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
+ null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
+ }
+ }
+
// WindowManager Extensions is an optional shared library that is required for WindowManager
// Jetpack to fully function. Since it is a widely used library, preload it to improve apps
// startup performance.
diff --git a/core/java/com/android/internal/os/flags.aconfig b/core/java/com/android/internal/os/flags.aconfig
index 25a9fbc8476c..32cde50f11a2 100644
--- a/core/java/com/android/internal/os/flags.aconfig
+++ b/core/java/com/android/internal/os/flags.aconfig
@@ -53,6 +53,13 @@ flag {
}
flag {
+ name: "enable_media_and_location_preload"
+ namespace: "system_performance"
+ description: "Enables zygote preload of non-BCP media and location libraries."
+ bug: "241474956"
+}
+
+flag {
name: "use_transaction_codes_for_unknown_methods"
namespace: "stability"
description: "Use transaction codes when the method names is unknown"
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
index 8df3f2abcafd..e522b508b44b 100644
--- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -94,14 +94,21 @@ public final class RavenwoodEnvironment {
/** Used for testing */
@Disabled
- @ChangeId public static final long TEST_COMPAT_ID_2 = 368131701L;
+ @ChangeId
+ public static final long TEST_COMPAT_ID_2 = 368131701L;
/** Used for testing */
@EnabledAfter(targetSdkVersion = S)
- @ChangeId public static final long TEST_COMPAT_ID_3 = 368131659L;
+ @ChangeId
+ public static final long TEST_COMPAT_ID_3 = 368131659L;
/** Used for testing */
@EnabledAfter(targetSdkVersion = UPSIDE_DOWN_CAKE)
- @ChangeId public static final long TEST_COMPAT_ID_4 = 368132057L;
+ @ChangeId
+ public static final long TEST_COMPAT_ID_4 = 368132057L;
+
+ /** Used for testing */
+ @ChangeId
+ public static final long TEST_COMPAT_ID_5 = 387558811L;
}
}
diff --git a/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
index 77550002e3c6..3ed902f69342 100644
--- a/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
+++ b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
@@ -1,3 +1,5 @@
# TODO(b/274465475): Migrate LatencyTracker testing to its own module
marcinoc@google.com
ilkos@google.com
+jjaggi@google.com
+nicomazz@google.com
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 9be8ea7aadc4..d174fe36e460 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -1,8 +1,8 @@
-per-file AsyncChannel* = lorenzo@google.com, satk@google.com, etancohen@google.com
+per-file AsyncChannel* = lorenzo@google.com, satk@google.com
per-file MessageUtils*, Protocol*, RingBuffer*, TokenBucket* = jchalard@google.com, lorenzo@google.com, satk@google.com
per-file *Notification* = file:/services/core/java/com/android/server/notification/OWNERS
per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file Protocol* = etancohen@google.com, lorenzo@google.com
+per-file Protocol* =lorenzo@google.com
per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
per-file *Dump* = file:/core/java/com/android/internal/util/dump/OWNERS
per-file *Screenshot* = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/com/android/internal/util/function/pooled/OWNERS b/core/java/com/android/internal/util/function/pooled/OWNERS
index da723b3b67da..e69de29bb2d1 100644
--- a/core/java/com/android/internal/util/function/pooled/OWNERS
+++ b/core/java/com/android/internal/util/function/pooled/OWNERS
@@ -1 +0,0 @@
-eugenesusla@google.com \ No newline at end of file
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 19c6f51ff9a7..83750aca3766 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -61,6 +61,7 @@ import android.util.SparseIntArray;
import android.util.SparseLongArray;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -71,6 +72,7 @@ import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -288,6 +290,56 @@ public class LockPatternUtils {
}
+ /**
+ * This exists temporarily due to trunk-stable policies.
+ * Please use ArrayUtils directly if you can.
+ */
+ public static byte[] newNonMovableByteArray(int length) {
+ if (!android.security.Flags.secureArrayZeroization()) {
+ return new byte[length];
+ }
+ return ArrayUtils.newNonMovableByteArray(length);
+ }
+
+ /**
+ * This exists temporarily due to trunk-stable policies.
+ * Please use ArrayUtils directly if you can.
+ */
+ public static char[] newNonMovableCharArray(int length) {
+ if (!android.security.Flags.secureArrayZeroization()) {
+ return new char[length];
+ }
+ return ArrayUtils.newNonMovableCharArray(length);
+ }
+
+ /**
+ * This exists temporarily due to trunk-stable policies.
+ * Please use ArrayUtils directly if you can.
+ */
+ public static void zeroize(byte[] array) {
+ if (!android.security.Flags.secureArrayZeroization()) {
+ if (array != null) {
+ Arrays.fill(array, (byte) 0);
+ }
+ return;
+ }
+ ArrayUtils.zeroize(array);
+ }
+
+ /**
+ * This exists temporarily due to trunk-stable policies.
+ * Please use ArrayUtils directly if you can.
+ */
+ public static void zeroize(char[] array) {
+ if (!android.security.Flags.secureArrayZeroization()) {
+ if (array != null) {
+ Arrays.fill(array, (char) 0);
+ }
+ return;
+ }
+ ArrayUtils.zeroize(array);
+ }
+
@UnsupportedAppUsage
public DevicePolicyManager getDevicePolicyManager() {
if (mDevicePolicyManager == null) {
@@ -999,7 +1051,7 @@ public class LockPatternUtils {
}
final int patternSize = pattern.size();
- byte[] res = new byte[patternSize];
+ byte[] res = newNonMovableByteArray(patternSize);
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1');
@@ -1326,7 +1378,7 @@ public class LockPatternUtils {
try {
getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
} catch (RemoteException e) {
- throw new RuntimeException("Could not register StrongAuthTracker");
+ e.rethrowFromSystemServer();
}
}
diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java
index 54b9a225f944..2a12c986ab04 100644
--- a/core/java/com/android/internal/widget/LockscreenCredential.java
+++ b/core/java/com/android/internal/widget/LockscreenCredential.java
@@ -81,9 +81,9 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
/**
* Private constructor, use static builder methods instead.
*
- * <p> Builder methods should create a private copy of the credential bytes and pass in here.
- * LockscreenCredential will only store the reference internally without copying. This is to
- * minimize the number of extra copies introduced.
+ * <p> Builder methods should create a private copy of the credential bytes using a non-movable
+ * array and pass it in here. LockscreenCredential will only store the reference internally
+ * without copying. This is to minimize the number of extra copies introduced.
*/
private LockscreenCredential(int type, byte[] credential, boolean hasInvalidChars) {
Objects.requireNonNull(credential);
@@ -141,7 +141,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
*/
public static LockscreenCredential createUnifiedProfilePassword(@NonNull byte[] password) {
return new LockscreenCredential(CREDENTIAL_TYPE_PASSWORD,
- Arrays.copyOf(password, password.length), /* hasInvalidChars= */ false);
+ copyOfArrayNonMovable(password), /* hasInvalidChars= */ false);
}
/**
@@ -237,7 +237,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
/** Create a copy of the credential */
public LockscreenCredential duplicate() {
return new LockscreenCredential(mType,
- mCredential != null ? Arrays.copyOf(mCredential, mCredential.length) : null,
+ mCredential != null ? copyOfArrayNonMovable(mCredential) : null,
mHasInvalidChars);
}
@@ -246,12 +246,21 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
*/
public void zeroize() {
if (mCredential != null) {
- Arrays.fill(mCredential, (byte) 0);
+ LockPatternUtils.zeroize(mCredential);
mCredential = null;
}
}
/**
+ * Copies the given array into a new non-movable array.
+ */
+ private static byte[] copyOfArrayNonMovable(byte[] array) {
+ byte[] copy = LockPatternUtils.newNonMovableByteArray(array.length);
+ System.arraycopy(array, 0, copy, 0, array.length);
+ return copy;
+ }
+
+ /**
* Checks whether the credential meets basic requirements for setting it as a new credential.
*
* This is redundant if {@link android.app.admin.PasswordMetrics#validateCredential()}, which
@@ -346,7 +355,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
byte[] sha1 = MessageDigest.getInstance("SHA-1").digest(saltedPassword);
byte[] md5 = MessageDigest.getInstance("MD5").digest(saltedPassword);
- Arrays.fill(saltedPassword, (byte) 0);
+ LockPatternUtils.zeroize(saltedPassword);
return HexEncoding.encodeToString(ArrayUtils.concat(sha1, md5));
} catch (NoSuchAlgorithmException e) {
throw new AssertionError("Missing digest algorithm: ", e);
@@ -440,7 +449,7 @@ public class LockscreenCredential implements Parcelable, AutoCloseable {
* @return A byte array representing the input
*/
private static byte[] charsToBytesTruncating(CharSequence chars) {
- byte[] bytes = new byte[chars.length()];
+ byte[] bytes = LockPatternUtils.newNonMovableByteArray(chars.length());
for (int i = 0; i < chars.length(); i++) {
bytes[i] = (byte) chars.charAt(i);
}
diff --git a/core/java/com/android/internal/widget/remotecompose/OWNERS b/core/java/com/android/internal/widget/remotecompose/OWNERS
index 54facab0c3f4..c606744df150 100644
--- a/core/java/com/android/internal/widget/remotecompose/OWNERS
+++ b/core/java/com/android/internal/widget/remotecompose/OWNERS
@@ -1,8 +1,6 @@
nicolasroard@google.com
hoford@google.com
-jnichol@google.com
sihua@google.com
sunnygoyal@google.com
oscarad@google.com
pinyaoting@google.com
-zakcohen@google.com
diff --git a/core/java/com/android/server/servicewatcher/ServiceWatcher.java b/core/java/com/android/server/servicewatcher/ServiceWatcher.java
index 831ff67a02a5..38872c996596 100644
--- a/core/java/com/android/server/servicewatcher/ServiceWatcher.java
+++ b/core/java/com/android/server/servicewatcher/ServiceWatcher.java
@@ -214,11 +214,7 @@ public interface ServiceWatcher {
@Override
public String toString() {
- if (mComponentName == null) {
- return "none";
- } else {
- return mUid + "/" + mComponentName.flattenToShortString();
- }
+ return mUid + "/" + mComponentName.flattenToShortString();
}
}
diff --git a/core/java/org/chromium/arc/EventLogTags.logtags b/core/java/org/chromium/arc/EventLogTags.logtags
index 1b7160e90224..8102d6f10ed4 100644
--- a/core/java/org/chromium/arc/EventLogTags.logtags
+++ b/core/java/org/chromium/arc/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package org.chromium.arc
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 027113a75f6b..31b280040259 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -42,6 +42,8 @@ cc_library_shared_for_libandroid_runtime {
"-DU_USING_ICU_NAMESPACE=0",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+
"-Wall",
"-Werror",
"-Wextra",
@@ -278,6 +280,7 @@ cc_library_shared_for_libandroid_runtime {
],
static_libs: [
+ "android.os.flags-aconfig-cc",
"libasync_safe",
"libbinderthreadstateutils",
"libdmabufinfo",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 78d69f0714e0..cbbf3a25b449 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -22,6 +22,7 @@
#include <android-base/parsebool.h>
#include <android-base/properties.h>
#include <android/graphics/jni_runtime.h>
+#include <android_os.h>
#include <android_runtime/AndroidRuntime.h>
#include <assert.h>
#include <binder/IBinder.h>
@@ -891,9 +892,13 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p
madviseWillNeedFileSizeOdex,
"-XMadviseWillNeedOdexFileSize:");
- parseRuntimeOption("dalvik.vm.madvise.artfile.size",
- madviseWillNeedFileSizeArt,
- "-XMadviseWillNeedArtFileSize:");
+ // Historically, dalvik.vm.madvise.artfile.size was set to UINT_MAX by default. With the
+ // disable_madvise_art_default flag rollout, we use this default only when the flag is disabled.
+ // TODO(b/382110550): Remove this property/flag entirely after validating and ramping.
+ const char* madvise_artfile_size_default =
+ android::os::disable_madvise_artfile_default() ? "" : "4294967295";
+ parseRuntimeOption("dalvik.vm.madvise.artfile.size", madviseWillNeedFileSizeArt,
+ "-XMadviseWillNeedArtFileSize:", madvise_artfile_size_default);
/*
* Profile related options.
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index 760037f63195..5b412ab19e16 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "ObbScanner"
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index b9c3bf73f11c..ed547ef7bb1c 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "BLASTBufferQueue"
diff --git a/core/jni/android_graphics_GraphicBuffer.cpp b/core/jni/android_graphics_GraphicBuffer.cpp
index d5765f1907d5..61dbb32c3b9f 100644
--- a/core/jni/android_graphics_GraphicBuffer.cpp
+++ b/core/jni/android_graphics_GraphicBuffer.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "GraphicBuffer"
diff --git a/core/jni/android_graphics_SurfaceTexture.cpp b/core/jni/android_graphics_SurfaceTexture.cpp
index 8dd63cc07b8a..93d1e2eef9e7 100644
--- a/core/jni/android_graphics_SurfaceTexture.cpp
+++ b/core/jni/android_graphics_SurfaceTexture.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#undef LOG_TAG
#define LOG_TAG "SurfaceTexture"
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 42406147b2f0..003ebc032a29 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -14,6 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "Camera-JNI"
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index 2ea2158d1884..c8059f39a34a 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "HardwareBuffer"
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 56ea52d2ad8b..2864a5718f33 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "SensorManager"
#include <nativehelper/JNIHelp.h>
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index b1221ee38db3..68ef3d424d12 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -165,19 +165,25 @@ android_hardware_UsbDeviceConnection_control_request(JNIEnv *env, jobject thiz,
return -1;
}
- jbyte* bufferBytes = NULL;
- if (buffer) {
- bufferBytes = (jbyte*)env->GetPrimitiveArrayCritical(buffer, NULL);
+ bool is_dir_in = (requestType & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN;
+ std::unique_ptr<jbyte[]> bufferBytes(new (std::nothrow) jbyte[length]);
+ if (!bufferBytes) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
+ return -1;
+ }
+
+ if (!is_dir_in && buffer) {
+ env->GetByteArrayRegion(buffer, start, length, bufferBytes.get());
}
- jint result = usb_device_control_transfer(device, requestType, request,
- value, index, bufferBytes + start, length, timeout);
+ jint bytes_transferred = usb_device_control_transfer(device, requestType, request,
+ value, index, bufferBytes.get(), length, timeout);
- if (bufferBytes) {
- env->ReleasePrimitiveArrayCritical(buffer, bufferBytes, 0);
+ if (bytes_transferred > 0 && is_dir_in) {
+ env->SetByteArrayRegion(buffer, start, bytes_transferred, bufferBytes.get());
}
- return result;
+ return bytes_transferred;
}
static jint
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index a0987373687b..7629faa3a72c 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -14,6 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
// #define LOG_NDEBUG 0
#include <memory>
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 82570be8e329..828f2eb76c60 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "DngCreator_JNI"
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index f1c4913fe006..a3de6fbc3992 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "InputWindowHandle"
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 5a183925e38e..102edc944c22 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 3d9a19e129a8..2ba6bc4912c3 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -14,6 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 5d4d1ce20e5d..3fc1a02f46b6 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "AudioTrack-JNI"
diff --git a/core/jni/android_media_AudioVolumeGroupCallback.cpp b/core/jni/android_media_AudioVolumeGroupCallback.cpp
index cb4ddbd119d5..d130a4bc68fa 100644
--- a/core/jni/android_media_AudioVolumeGroupCallback.cpp
+++ b/core/jni/android_media_AudioVolumeGroupCallback.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
diff --git a/core/jni/android_media_RemoteDisplay.cpp b/core/jni/android_media_RemoteDisplay.cpp
index 3b517f1eafe0..cf96f027bd5e 100644
--- a/core/jni/android_media_RemoteDisplay.cpp
+++ b/core/jni/android_media_RemoteDisplay.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "RemoteDisplay"
diff --git a/core/jni/android_media_ToneGenerator.cpp b/core/jni/android_media_ToneGenerator.cpp
index cc4657ded596..3c590c37adac 100644
--- a/core/jni/android_media_ToneGenerator.cpp
+++ b/core/jni/android_media_ToneGenerator.cpp
@@ -14,6 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "ToneGenerator"
#include <stdio.h>
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 917d28348d04..7e9beefdc38c 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -632,7 +632,7 @@ not_valid_surface:
if (producer == NULL)
goto not_valid_surface;
- window = new android::Surface(producer, true);
+ window = android::sp<android::Surface>::make(producer, true);
if (window == NULL)
goto not_valid_surface;
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 3c2dccd451d4..9ef17e82c38e 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -729,6 +729,17 @@ static jlong android_os_Debug_getGpuPrivateMemoryKb(JNIEnv* env, jobject clazz)
return gpuPrivateMem / 1024;
}
+static jlong android_os_Debug_getKernelCmaUsageKb(JNIEnv* env, jobject clazz) {
+ jlong totalKernelCmaUsageKb = -1;
+ uint64_t size;
+
+ if (meminfo::ReadKernelCmaUsageKb(&size)) {
+ totalKernelCmaUsageKb = size;
+ }
+
+ return totalKernelCmaUsageKb;
+}
+
static jlong android_os_Debug_getDmabufMappedSizeKb(JNIEnv* env, jobject clazz) {
jlong dmabufPss = 0;
std::vector<dmabufinfo::DmaBuffer> dmabufs;
@@ -836,6 +847,7 @@ static const JNINativeMethod gMethods[] = {
{"getGpuTotalUsageKb", "()J", (void*)android_os_Debug_getGpuTotalUsageKb},
{"isVmapStack", "()Z", (void*)android_os_Debug_isVmapStack},
{"logAllocatorStats", "()Z", (void*)android_os_Debug_logAllocatorStats},
+ {"getKernelCmaUsageKb", "()J", (void*)android_os_Debug_getKernelCmaUsageKb},
};
int register_android_os_Debug(JNIEnv *env)
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 734b5f497e2e..8060e6232482 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "android_os_HwBinder"
diff --git a/core/jni/android_os_HwBlob.cpp b/core/jni/android_os_HwBlob.cpp
index e554b44233b5..df579af0acb4 100644
--- a/core/jni/android_os_HwBlob.cpp
+++ b/core/jni/android_os_HwBlob.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "android_os_HwBlob"
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index c7866524668f..727455c21e02 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "android_os_HwParcel"
diff --git a/core/jni/android_os_HwRemoteBinder.cpp b/core/jni/android_os_HwRemoteBinder.cpp
index d2d7213e5761..3b567092f6a6 100644
--- a/core/jni/android_os_HwRemoteBinder.cpp
+++ b/core/jni/android_os_HwRemoteBinder.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
//#define LOG_NDEBUG 0
#define LOG_TAG "JHwRemoteBinder"
diff --git a/core/jni/android_os_MessageQueue.cpp b/core/jni/android_os_MessageQueue.cpp
index 30d9ea19be39..d5d5521eb8c8 100644
--- a/core/jni/android_os_MessageQueue.cpp
+++ b/core/jni/android_os_MessageQueue.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "MessageQueue-JNI"
diff --git a/core/jni/android_tracing_PerfettoDataSource.cpp b/core/jni/android_tracing_PerfettoDataSource.cpp
index fec28987e7e6..ea896e1678a7 100644
--- a/core/jni/android_tracing_PerfettoDataSource.cpp
+++ b/core/jni/android_tracing_PerfettoDataSource.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "NativeJavaPerfettoDs"
@@ -489,4 +490,4 @@ int register_android_tracing_PerfettoDataSource(JNIEnv* env) {
return 0;
}
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 8003bb7d442b..7f545164dbc3 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#define LOG_TAG "JavaBinder"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include "android_util_Binder.h"
@@ -478,7 +477,7 @@ public:
if (b) return b;
// b/360067751: constructor may trigger GC, so call outside lock
- b = new JavaBBinder(env, obj);
+ b = sp<JavaBBinder>::make(env, obj);
{
AutoMutex _l(mLock);
@@ -645,11 +644,17 @@ public:
} else {
mObject = env->NewGlobalRef(object);
}
+ }
+
+ void onFirstRef() override {
+ T::onFirstRef();
+
+ sp<RecipientList<T>> list = mList.promote();
// These objects manage their own lifetimes so are responsible for final bookkeeping.
// The list holds a strong reference to this object.
LOG_DEATH_FREEZE("%s Adding JavaRecipient %p to RecipientList %p", logPrefix<T>(), this,
list.get());
- list->add(this);
+ list->add(sp<JavaRecipient>::fromExisting(this));
}
void clearReference() {
@@ -657,7 +662,7 @@ public:
if (list != NULL) {
LOG_DEATH_FREEZE("%s Removing JavaRecipient %p from RecipientList %p", logPrefix<T>(),
this, list.get());
- list->remove(this);
+ list->remove(sp<JavaRecipient>::fromExisting(this));
} else {
LOG_DEATH_FREEZE("%s clearReference() on JavaRecipient %p but RecipientList wp purged",
logPrefix<T>(), this);
@@ -939,7 +944,7 @@ struct BinderProxyNativeData {
// Frozen state change callbacks for mObject. Reference counted only because
// JavaFrozenStateChangeCallback hold a weak reference that can be
// temporarily promoted.
- sp<FrozenStateChangeCallbackList> mFrozenStateChangCallbackList;
+ sp<FrozenStateChangeCallbackList> mFrozenStateChangeCallbackList;
};
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
@@ -964,8 +969,8 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
}
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
- nativeData->mOrgue = new DeathRecipientList;
- nativeData->mFrozenStateChangCallbackList = new FrozenStateChangeCallbackList;
+ nativeData->mOrgue = sp<DeathRecipientList>::make();
+ nativeData->mFrozenStateChangeCallbackList = sp<FrozenStateChangeCallbackList>::make();
nativeData->mObject = val;
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
@@ -1571,8 +1576,8 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,
LOG_DEATH_FREEZE("linkToDeath: binder=%p recipient=%p\n", target, recipient);
if (!target->localBinder()) {
- DeathRecipientList* list = nd->mOrgue.get();
- sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);
+ sp<DeathRecipientList> list = nd->mOrgue;
+ sp<JavaDeathRecipient> jdr = sp<JavaDeathRecipient>::make(env, recipient, list);
status_t err = target->linkToDeath(jdr, NULL, flags);
if (err != NO_ERROR) {
// Failure adding the death recipient, so clear its reference
@@ -1648,7 +1653,7 @@ static void android_os_BinderProxy_addFrozenStateChangeCallback(
LOG_DEATH_FREEZE("addFrozenStateChangeCallback: binder=%p callback=%p\n", target, callback);
if (!target->localBinder()) {
- FrozenStateChangeCallbackList* list = nd->mFrozenStateChangCallbackList.get();
+ sp<FrozenStateChangeCallbackList> list = nd->mFrozenStateChangeCallbackList;
auto jfscc = sp<JavaFrozenStateChangeCallback>::make(env, callback, list);
status_t err = target->addFrozenStateChangeCallback(jfscc);
if (err != NO_ERROR) {
@@ -1682,7 +1687,7 @@ static jboolean android_os_BinderProxy_removeFrozenStateChangeCallback(JNIEnv* e
status_t err = NAME_NOT_FOUND;
// If we find the matching callback, proceed to unlink using that
- FrozenStateChangeCallbackList* list = nd->mFrozenStateChangCallbackList.get();
+ FrozenStateChangeCallbackList* list = nd->mFrozenStateChangeCallbackList.get();
sp<JavaRecipient<IBinder::FrozenStateChangeCallback> > origJFSCC = list->find(callback);
LOG_DEATH_FREEZE(" removeFrozenStateChangeCallback found list %p and JFSCC %p", list,
origJFSCC.get());
@@ -1711,7 +1716,7 @@ static void BinderProxy_destroy(void* rawNativeData)
BinderProxyNativeData * nativeData = (BinderProxyNativeData *) rawNativeData;
LOG_DEATH_FREEZE("Destroying BinderProxy: binder=%p drl=%p fsccl=%p\n",
nativeData->mObject.get(), nativeData->mOrgue.get(),
- nativeData->mFrozenStateChangCallbackList.get());
+ nativeData->mFrozenStateChangeCallbackList.get());
delete nativeData;
IPCThreadState::self()->flushCommands();
}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7ef7829c6ba5..dc7253954d44 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -589,32 +589,6 @@ jint android_os_Process_getThreadPriority(JNIEnv* env, jobject clazz,
return pri;
}
-jboolean android_os_Process_setSwappiness(JNIEnv *env, jobject clazz,
- jint pid, jboolean is_increased)
-{
- char text[64];
-
- if (is_increased) {
- strcpy(text, "/sys/fs/cgroup/memory/sw/tasks");
- } else {
- strcpy(text, "/sys/fs/cgroup/memory/tasks");
- }
-
- struct stat st;
- if (stat(text, &st) || !S_ISREG(st.st_mode)) {
- return false;
- }
-
- int fd = open(text, O_WRONLY | O_CLOEXEC);
- if (fd >= 0) {
- sprintf(text, "%" PRId32, pid);
- write(fd, text, strlen(text));
- close(fd);
- }
-
- return true;
-}
-
void android_os_Process_setArgV0(JNIEnv* env, jobject clazz, jstring name)
{
if (name == NULL) {
@@ -1396,7 +1370,6 @@ static const JNINativeMethod methods[] = {
{"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup},
{"createProcessGroup", "(II)I", (void*)android_os_Process_createProcessGroup},
{"getExclusiveCores", "()[I", (void*)android_os_Process_getExclusiveCores},
- {"setSwappiness", "(IZ)Z", (void*)android_os_Process_setSwappiness},
{"setArgV0Native", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0},
{"setUid", "(I)I", (void*)android_os_Process_setUid},
{"setGid", "(I)I", (void*)android_os_Process_setGid},
diff --git a/core/jni/android_view_CompositionSamplingListener.cpp b/core/jni/android_view_CompositionSamplingListener.cpp
index 59c01dc37593..28616a063730 100644
--- a/core/jni/android_view_CompositionSamplingListener.cpp
+++ b/core/jni/android_view_CompositionSamplingListener.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "CompositionSamplingListener"
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 7ff1f8c4a748..d8f1b626abf2 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "DisplayEventReceiver"
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 3a1e8835c8db..0b350c5721d8 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "InputEventReceiver"
#define ATRACE_TAG ATRACE_TAG_INPUT
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 88b02baab924..01309b795567 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "InputEventSender"
diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp
index 50d2cbe2ce74..17165d8a03fe 100644
--- a/core/jni/android_view_InputQueue.cpp
+++ b/core/jni/android_view_InputQueue.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "InputQueue"
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 240be3fe5534..c105a6098870 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -704,7 +704,8 @@ static void android_view_MotionEvent_nativeSetFlags(CRITICAL_JNI_PARAMS_COMMA jl
jint flags) {
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
// Prevent private flags from being used from Java.
- event->setFlags(flags & ~AMOTION_EVENT_PRIVATE_FLAG_MASK);
+ const int32_t privateFlags = event->getFlags() & AMOTION_EVENT_PRIVATE_FLAG_MASK;
+ event->setFlags((flags & ~AMOTION_EVENT_PRIVATE_FLAG_MASK) | privateFlags);
}
static jint android_view_MotionEvent_nativeGetEdgeFlags(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) {
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ac6298d3d0b4..312c2067d396 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "Surface"
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 0c243d1dc185..8b4f57560f07 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "SurfaceControl"
#define LOG_NDEBUG 0
diff --git a/core/jni/android_view_SurfaceControlActivePictureListener.cpp b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
index 91849c1514cc..c9bd3824b94d 100644
--- a/core/jni/android_view_SurfaceControlActivePictureListener.cpp
+++ b/core/jni/android_view_SurfaceControlActivePictureListener.cpp
@@ -107,7 +107,7 @@ struct SurfaceControlActivePictureListener : public gui::BnActivePictureListener
status_t startListening() {
// TODO(b/337330263): Make SF multiple-listener capable
- return SurfaceComposerClient::setActivePictureListener(this);
+ return SurfaceComposerClient::setActivePictureListener(sp<SurfaceControlActivePictureListener>::fromExisting(this));
}
status_t stopListening() {
diff --git a/core/jni/android_view_SurfaceControlHdrLayerInfoListener.cpp b/core/jni/android_view_SurfaceControlHdrLayerInfoListener.cpp
index 443f99a78f02..09cb8116d04b 100644
--- a/core/jni/android_view_SurfaceControlHdrLayerInfoListener.cpp
+++ b/core/jni/android_view_SurfaceControlHdrLayerInfoListener.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "SurfaceControlHdrLayerInfoListener"
diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp
index 0aac07d17cdc..6ad109e80752 100644
--- a/core/jni/android_view_SurfaceSession.cpp
+++ b/core/jni/android_view_SurfaceSession.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "SurfaceSession"
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 391f515af115..21fe1f020b29 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#include "jni.h"
#include <nativehelper/JNIHelp.h>
diff --git a/core/jni/android_view_TunnelModeEnabledListener.cpp b/core/jni/android_view_TunnelModeEnabledListener.cpp
index d9ab9571cfbe..fd78a94fc2d9 100644
--- a/core/jni/android_view_TunnelModeEnabledListener.cpp
+++ b/core/jni/android_view_TunnelModeEnabledListener.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "TunnelModeEnabledListener"
diff --git a/core/jni/android_window_InputTransferToken.cpp b/core/jni/android_window_InputTransferToken.cpp
index 5bcea9b7c401..f92d128c7077 100644
--- a/core/jni/android_window_InputTransferToken.cpp
+++ b/core/jni/android_window_InputTransferToken.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "InputTransferToken"
@@ -137,4 +138,4 @@ int register_android_window_InputTransferToken(JNIEnv* env) {
return err;
}
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index 1a52fb74a1e9..59ff746a60a1 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "ScreenCapture"
// #define LOG_NDEBUG 0
diff --git a/core/jni/android_window_WindowInfosListener.cpp b/core/jni/android_window_WindowInfosListener.cpp
index c39d5e20aa1c..30846ef99d60 100644
--- a/core/jni/android_window_WindowInfosListener.cpp
+++ b/core/jni/android_window_WindowInfosListener.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#define LOG_TAG "WindowInfosListener"
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index 76ead2a3ca31..48c92c87f54e 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -21,8 +21,6 @@
#include <android-base/file.h>
#include <android-base/hex.h>
#include <android-base/unique_fd.h>
-#include <bionic/macros.h>
-#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/fs.h>
@@ -48,8 +46,8 @@ bool punchWithBlockAlignment(borrowed_fd fd, uint64_t start, uint64_t length, ui
return false;
}
- start = align_up(start, blockSize);
- end = align_down(end, blockSize);
+ start = __builtin_align_up(start, blockSize);
+ end = __builtin_align_down(end, blockSize);
uint64_t alignedLength;
if (__builtin_sub_overflow(end, start, &alignedLength)) {
@@ -67,7 +65,7 @@ bool punchWithBlockAlignment(borrowed_fd fd, uint64_t start, uint64_t length, ui
int result =
fallocate(fd.get(), FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, start, alignedLength);
if (result < 0) {
- ALOGE("fallocate failed to punch hole, error:%d", errno);
+ ALOGE("fallocate failed to punch hole: %m");
return false;
}
@@ -78,7 +76,7 @@ bool punchHoles(const char *filePath, const uint64_t offset,
const std::vector<Elf64_Phdr> &programHeaders) {
struct stat64 beforePunch;
if (int result = lstat64(filePath, &beforePunch); result != 0) {
- ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ ALOGE("lstat64 failed for filePath %s: %m", filePath);
return false;
}
@@ -190,7 +188,7 @@ bool punchHoles(const char *filePath, const uint64_t offset,
IF_ALOGD() {
struct stat64 afterPunch;
if (int result = lstat64(filePath, &afterPunch); result != 0) {
- ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ ALOGD("lstat64 failed for filePath %s: %m", filePath);
return false;
}
ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %" PRIu64
@@ -269,7 +267,7 @@ bool punchHolesInZip(const char *filePath, uint64_t offset, uint16_t extraFieldL
struct stat64 beforePunch;
if (int result = lstat64(filePath, &beforePunch); result != 0) {
- ALOGE("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ ALOGE("lstat64 failed for filePath %s: %m", filePath);
return false;
}
@@ -348,7 +346,7 @@ bool punchHolesInZip(const char *filePath, uint64_t offset, uint16_t extraFieldL
IF_ALOGD() {
struct stat64 afterPunch;
if (int result = lstat64(filePath, &afterPunch); result != 0) {
- ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
+ ALOGD("lstat64 failed for filePath %s: %m", filePath);
return false;
}
ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index f40cfd9f8e51..3108f1f2c7c5 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -314,8 +314,9 @@ static install_status_t copyFileIfChanged(JNIEnv* env, void* arg, ZipFileRO* zip
when, uncompLen, crc);
}
- ALOGE("Library '%s' is not PAGE(%zu)-aligned - will not be able to open it directly "
- "from apk.\n",
+ ALOGE("extractNativeLibs=false library '%s' is not PAGE(%zu)-"
+ "aligned within apk (APK alignment, not ELF alignment) -"
+ "will not be able to open it directly from apk.\n",
fileName, kPageSize);
return INSTALL_FAILED_INVALID_APK;
}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index aeaeeca3e845..8c7b335e6e86 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -88,8 +88,8 @@
#include "nativebridge/native_bridge.h"
#if defined(__BIONIC__)
+#include <android/dlext_private.h>
extern "C" void android_reset_stack_guards();
-extern "C" void android_set_16kb_appcompat_mode(bool enable_app_compat);
#endif
namespace {
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index e0cc055a62a6..c4259f41e380 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -266,16 +266,24 @@ class NativeCommandBuffer {
}
// Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
static int digitsVal(char* start, char* end) {
+ constexpr int vmax = std::numeric_limits<int>::max();
int result = 0;
- if (end - start > 6) {
- return -1;
- }
for (char* dp = start; dp < end; ++dp) {
if (*dp < '0' || *dp > '9') {
- ALOGW("Argument failed integer format check");
+ ALOGW("Argument contains non-integer characters");
+ return -1;
+ }
+ int digit = *dp - '0';
+ if (result > vmax / 10) {
+ ALOGW("Argument exceeds int limit");
+ return -1;
+ }
+ result *= 10;
+ if (result > vmax - digit) {
+ ALOGW("Argument exceeds int limit");
return -1;
}
- result = 10 * result + (*dp - '0');
+ result += digit;
}
return result;
}
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 5aea8485d0c1..75330be2624d 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -14,6 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
*/
+#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index b51f72dee260..c80402408180 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -5,8 +5,6 @@ joeo@google.com
singhtejinder@google.com
yanmin@google.com
yaochen@google.com
-yro@google.com
-zhouwenjie@google.com
# Frameworks
ogunwale@google.com
diff --git a/core/proto/android/net/OWNERS b/core/proto/android/net/OWNERS
index 509699b9fb4b..a6627fe344b6 100644
--- a/core/proto/android/net/OWNERS
+++ b/core/proto/android/net/OWNERS
@@ -1,3 +1,2 @@
-ek@google.com
lorenzo@google.com
satk@google.com
diff --git a/core/proto/android/nfc/OWNERS b/core/proto/android/nfc/OWNERS
index ca16721eacc1..36823aee4dbb 100644
--- a/core/proto/android/nfc/OWNERS
+++ b/core/proto/android/nfc/OWNERS
@@ -1 +1 @@
-include platform/packages/apps/Nfc:/OWNERS \ No newline at end of file
+include platform/packages/modules/Nfc:/OWNERS \ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6b8056c77fda..2371c3e15e93 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -180,6 +180,7 @@
<protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
<protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
<protected-broadcast android:name="android.bluetooth.device.action.KEY_MISSING" />
+ <protected-broadcast android:name="android.bluetooth.device.action.ENCRYPTION_CHANGE" />
<protected-broadcast android:name="android.bluetooth.device.action.SDP_RECORD" />
<protected-broadcast android:name="android.bluetooth.device.action.BATTERY_LEVEL_CHANGED" />
<protected-broadcast android:name="android.bluetooth.device.action.REMOTE_ISSUE_OCCURRED" />
@@ -9248,6 +9249,11 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
+ <service android:name="com.android.server.memory.ZramMaintenance"
+ android:exported="false"
+ android:permission="android.permission.BIND_JOB_SERVICE" >
+ </service>
+
<service android:name="com.android.server.ZramWriteback"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE" >
@@ -9319,7 +9325,11 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
- <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ProfcollectBGJobService"
+ <service android:name="com.android.server.profcollect.ProfcollectForwardingService$PeriodicTraceJobService"
+ android:permission="android.permission.BIND_JOB_SERVICE" >
+ </service>
+
+ <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ReportProcessJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
diff --git a/core/res/OWNERS b/core/res/OWNERS
index faed4d80f39b..a208f7f1a3ad 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -9,7 +9,6 @@ hackbod@google.com
ilyamaty@google.com
jbolinger@google.com
jsharkey@android.com
-jsharkey@google.com
juliacr@google.com
kchyn@google.com
michaelwr@google.com
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 792974defe07..728c856f5855 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4641,7 +4641,7 @@
role owner must opt into this behavior by using the property named by
{@link android.nfc.cardemulation.CardEmulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY }
in the <code>&lt;application&rt;</code> tag. -->
- <attr name="shareRolePriority" format="boolean"/>
+ <attr name="wantsRoleHolderPriority" format="boolean"/>
</declare-styleable>
<!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -4669,7 +4669,7 @@
<!-- Whether the device should default to observe mode when this service is
default or in the foreground. -->
<attr name="shouldDefaultToObserveMode"/>
- <attr name="shareRolePriority"/>
+ <attr name="wantsRoleHolderPriority"/>
</declare-styleable>
<!-- Specify one or more <code>aid-group</code> elements inside a
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 53b47622e8ae..007b8cc3ca6c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3218,6 +3218,14 @@
as private. {@see android.view.Display#FLAG_PRIVATE} -->
<integer-array translatable="false" name="config_localPrivateDisplayPorts"></integer-array>
+ <!-- Controls if local secondary displays should be able to steal focus and become top display.
+ Value specified in the array represents physical port address of each display and displays
+ in this list due to flag dependencies will be marked with the following flags:
+ {@see android.view.Display#FLAG_STEAL_TOP_FOCUS_DISABLED}
+ {@see android.view.Display#FLAG_OWN_FOCUS} -->
+ <integer-array translatable="false" name="config_localNotStealTopFocusDisplayPorts">
+ </integer-array>
+
<!-- The default mode for the default display. One of the following values (See Display.java):
0 - COLOR_MODE_DEFAULT
7 - COLOR_MODE_SRGB
@@ -5191,10 +5199,6 @@
<!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
<bool name="config_swipe_up_gesture_setting_available">true</bool>
- <!-- Applications which are disabled unless matching a particular sku -->
- <string-array name="config_disableApksUnlessMatchedSku_apk_list" translatable="false" />
- <string-array name="config_disableApkUnlessMatchedSku_skus_list" translatable="false" />
-
<!-- Whether or not we should show the option to show battery percentage -->
<bool name="config_battery_percentage_setting_available">true</bool>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 6c73b0c45a41..7fe20c6320fd 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -134,7 +134,7 @@
<!-- @FlaggedApi(android.content.pm.Flags.FLAG_APP_COMPAT_OPTION_16KB) -->
<public name="pageSizeCompat" />
<!-- @FlaggedApi(android.nfc.Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) -->
- <public name="shareRolePriority"/>
+ <public name="wantsRoleHolderPriority"/>
<!-- @FlaggedApi(android.sdk.Flags.FLAG_MAJOR_MINOR_VERSIONING_SCHEME) -->
<public name="minSdkVersionFull"/>
</staging-public-group>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 71532bbbe725..31ae988ae488 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -428,6 +428,7 @@
<java-symbol type="bool" name="config_enableProximityService" />
<java-symbol type="bool" name="config_enableVirtualDeviceManager" />
<java-symbol type="array" name="config_localPrivateDisplayPorts" />
+ <java-symbol type="array" name="config_localNotStealTopFocusDisplayPorts" />
<java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" />
<java-symbol type="bool" name="config_enableAppWidgetService" />
<java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
@@ -4328,10 +4329,6 @@
<java-symbol type="integer" name="config_unfoldTransitionHalfFoldedTimeout" />
<java-symbol type="array" name="config_perDeviceStateRotationLockDefaults" />
-
- <java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
- <java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
-
<java-symbol type="string" name="config_misprovisionedDeviceModel" />
<java-symbol type="string" name="config_misprovisionedBrandValue" />
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index bb5380e1312d..9b3a6cba5f23 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -34,7 +34,7 @@
http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ -->
<!-- Arab Emirates -->
- <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253|6568" />
+ <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253|6568|999" />
<!-- Albania: 5 digits, known short codes listed -->
<shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" />
@@ -63,8 +63,8 @@
<!-- Burkina Faso: 1-4 digits (standard system default, not country specific) -->
<shortcode country="bf" pattern="\\d{1,4}" free="3558" />
- <!-- Bulgaria: 4-5 digits, plus EU -->
- <shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}|1988|1490" />
+ <!-- Bulgaria: 4-6 digits, plus EU -->
+ <shortcode country="bg" pattern="\\d{4,6}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}|1988|1490|162055" />
<!-- Bahrain: 1-5 digits (standard system default, not country specific) -->
<shortcode country="bh" pattern="\\d{1,5}" free="81181|85999" />
@@ -81,18 +81,21 @@
<!-- Canada: 5-6 digits -->
<shortcode country="ca" pattern="\\d{5,6}" premium="60999|88188|43030" standard="244444" free="455677|24470" />
+ <!-- DR Congo: 1-6 digits, known premium codes listed -->
+ <shortcode country="cd" pattern="\\d{1,6}" free="444123" />
+
<!-- Switzerland: 3-5 digits: http://www.swisscom.ch/fxres/kmu/thirdpartybusiness_code_of_conduct_en.pdf -->
<shortcode country="ch" pattern="[2-9]\\d{2,4}" premium="543|83111|30118" free="98765|30075|30047" />
<!-- Chile: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="cl" pattern="\\d{4,5}" free="9963|9240|1038" />
+ <shortcode country="cl" pattern="\\d{4,5}" free="9963|9240|1038|4848" />
<!-- China: premium shortcodes start with "1066", free shortcodes start with "1065":
http://clients.txtnation.com/entries/197192-china-premium-sms-short-code-requirements -->
<shortcode country="cn" premium="1066.*" free="1065.*" />
<!-- Colombia: 1-6 digits (not confirmed) -->
- <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960|899948|87739|85517|491289" />
+ <shortcode country="co" pattern="\\d{1,6}" free="890350|908160|892255|898002|898880|899960|899948|87739|85517|491289|890119" />
<!-- Costa Rica -->
<shortcode country="cr" pattern="\\d{1,6}" free="466453" />
@@ -108,7 +111,7 @@
<shortcode country="cz" premium="90\\d{5}|90\\d{3}" free="116\\d{3}" />
<!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
- <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215|47529|70296|83782|3011|73240|72438" />
+ <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215|47529|70296|83782|3011|73240|72438|70997" />
<!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
<shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}|4665" />
@@ -116,6 +119,9 @@
<!-- Dominican Republic: 1-6 digits (standard system default, not country specific) -->
<shortcode country="do" pattern="\\d{1,6}" free="912892|912" />
+ <!-- Algeria: 1-5 digits, known premium codes listed -->
+ <shortcode country="dz" pattern="\\d{1,5}" free="63071" />
+
<!-- Ecuador: 1-6 digits (standard system default, not country specific) -->
<shortcode country="ec" pattern="\\d{1,6}" free="466453|18512" />
@@ -123,20 +129,23 @@
http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
<shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}|95034" />
- <!-- Egypt: 4-5 digits, known codes listed -->
- <shortcode country="eg" pattern="\\d{4,5}" free="1499|10020" />
+ <!-- Egypt: 4-6 digits, known codes listed -->
+ <shortcode country="eg" pattern="\\d{4,6}" free="1499|10020|100158" />
<!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
<shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}|22791|222145|22189" />
+ <!-- Ethiopia: 1-4 digits, known codes listed -->
+ <shortcode country="et" pattern="\\d{1,4}" free="8527" />
+
<!-- Finland: 5-6 digits, premium 0600, 0700: http://en.wikipedia.org/wiki/Telephone_numbers_in_Finland -->
<shortcode country="fi" pattern="\\d{5,6}" premium="0600.*|0700.*|171(?:59|63)" free="116\\d{3}|14789|17110" />
<!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
visual voicemail code for Orange: 21101 -->
- <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051|33033" />
+ <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051|33033|21727" />
<!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
@@ -179,17 +188,17 @@
<shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" />
<!-- Iran: 4-8 digits, known premium codes listed -->
- <shortcode country="ir" pattern="\\d{4,8}" free="700791|700792|100016|30008360" />
+ <shortcode country="ir" pattern="\\d{4,8}" free="700792|100016|30008360" />
<!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU:
https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
<shortcode country="it" pattern="\\d{5}" premium="44[0-4]\\d{2}|47[0-4]\\d{2}|48[0-4]\\d{2}|44[5-9]\\d{4}|47[5-9]\\d{4}|48[5-9]\\d{4}|455\\d{2}|499\\d{2}" free="116\\d{3}|4112503|40\\d{0,12}" standard="430\\d{2}|431\\d{2}|434\\d{4}|435\\d{4}|439\\d{7}" />
<!-- Jordan: 1-5 digits (standard system default, not country specific) -->
- <shortcode country="jo" pattern="\\d{1,5}" free="99066" />
+ <shortcode country="jo" pattern="\\d{1,5}" free="99066|99390" />
<!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
- <shortcode country="jp" pattern="\\d{1,5}" free="8083" />
+ <shortcode country="jp" pattern="\\d{1,9}" free="8083|00050320" />
<!-- Kenya: 5 digits, known premium codes listed -->
<shortcode country="ke" pattern="\\d{5}" free="21725|21562|40520|23342|40023|24088|23054" />
@@ -206,6 +215,9 @@
<!-- Kuwait: 1-5 digits (standard system default, not country specific) -->
<shortcode country="kw" pattern="\\d{1,5}" free="1378|50420|94006|55991|50976|7112" />
+ <!-- Lesotho: 4-5 digits, known codes listed -->
+ <shortcode country="ls" pattern="\\d{4,5}" free="32012" />
+
<!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
<shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}|1399|1324" />
@@ -222,11 +234,14 @@
<!-- Macedonia: 1-6 digits (not confirmed), known premium codes listed -->
<shortcode country="mk" pattern="\\d{1,6}" free="129005|122" />
+ <!-- Mali: 1-5 digits, known codes listed -->
+ <shortcode country="ml" pattern="\\d{1,5}" free="36098" />
+
<!-- Mongolia : 1-6 digits (standard system default, not country specific) -->
<shortcode country="mn" pattern="\\d{1,6}" free="44444|45678|445566" />
<!-- Malawi: 1-5 digits (standard system default, not country specific) -->
- <shortcode country="mw" pattern="\\d{1,5}" free="4276|4305" />
+ <shortcode country="mw" pattern="\\d{1,5}" free="4276|4305|4326" />
<!-- Mozambique: 1-5 digits (standard system default, not country specific) -->
<shortcode country="mz" pattern="\\d{1,5}" free="1714" />
@@ -323,11 +338,14 @@
<!-- Tajikistan: 4 digits, known premium codes listed -->
<shortcode country="tj" pattern="\\d{4}" premium="11[3-7]1|4161|4333|444[689]" />
+ <!-- Timor-Leste 1-5 digits, known codes listed -->
+ <shortcode country="tl" pattern="\\d{1,5}" free="46645" />
+
<!-- Tanzania: 1-5 digits (standard system default, not country specific) -->
- <shortcode country="tz" pattern="\\d{1,5}" free="15046|15234|15324|15610" />
+ <shortcode country="tz" pattern="\\d{1,5}" free="15046|15324|15610" />
- <!-- Tunisia: 5 digits, known premium codes listed -->
- <shortcode country="tn" pattern="\\d{5}" free="85799" />
+ <!-- Tunisia: 1-6 digits, known premium codes listed -->
+ <shortcode country="tn" pattern="\\d{1,6}" free="85799|772024" />
<!-- Turkey -->
<shortcode country="tr" pattern="\\d{1,5}" free="7529|5528|6493|3193" />
@@ -336,7 +354,7 @@
<shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" />
<!-- Uganda(UG): 4 digits (standard system default, not country specific) -->
- <shortcode country="ug" pattern="\\d{4}" free="8000|8009" />
+ <shortcode country="ug" pattern="\\d{4}" free="8009" />
<!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm),
visual voicemail code for T-Mobile: 122 -->
@@ -349,7 +367,7 @@
<shortcode country="ve" pattern="\\d{1,6}" free="538352" />
<!-- Vietnam: 1-6 digits (standard system default, not country specific) -->
- <shortcode country="vn" pattern="\\d{1,6}" free="5001|9055|8079|90002|118989" />
+ <shortcode country="vn" pattern="\\d{1,6}" free="5001|9055|90002|118989|46645" />
<!-- Mayotte (French Territory): 1-5 digits (not confirmed) -->
<shortcode country="yt" pattern="\\d{1,5}" free="38600,36300,36303,959" />
diff --git a/core/tests/coretests/src/android/content/pm/OWNERS b/core/tests/coretests/src/android/content/pm/OWNERS
index 867336515ce3..c4c40dcaa87a 100644
--- a/core/tests/coretests/src/android/content/pm/OWNERS
+++ b/core/tests/coretests/src/android/content/pm/OWNERS
@@ -1,5 +1,4 @@
include /core/java/android/content/pm/OWNERS
per-file AppSearchPersonTest.java = file:/core/java/android/content/pm/SHORTCUT_OWNERS
-per-file SigningDetailsTest.java = cbrubaker@google.com
per-file SigningDetailsTest.java = mpgroover@google.com
diff --git a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
new file mode 100644
index 000000000000..ce4aa42f39b6
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Parcel;
+import android.util.ArrayMap;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SystemFeaturesCacheTest {
+
+ private SystemFeaturesCache mCache;
+
+ @Test
+ public void testNoFeatures() throws Exception {
+ SystemFeaturesCache cache = new SystemFeaturesCache(new ArrayMap<String, FeatureInfo>());
+ assertThat(cache.maybeHasFeature("", 0)).isNull();
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, 0)).isFalse();
+ assertThat(cache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0)).isFalse();
+ assertThat(cache.maybeHasFeature("com.missing.feature", 0)).isNull();
+ }
+
+ @Test
+ public void testNonSdkFeature() throws Exception {
+ ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
+ features.put("custom.feature", createFeature("custom.feature", 0));
+ SystemFeaturesCache cache = new SystemFeaturesCache(features);
+
+ assertThat(cache.maybeHasFeature("custom.feature", 0)).isNull();
+ }
+
+ @Test
+ public void testSdkFeature() throws Exception {
+ ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
+ features.put(FEATURE_WATCH, createFeature(FEATURE_WATCH, 0));
+ SystemFeaturesCache cache = new SystemFeaturesCache(features);
+
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, 0)).isTrue();
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, -1)).isTrue();
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, 1)).isFalse();
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, Integer.MIN_VALUE)).isTrue();
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, Integer.MAX_VALUE)).isFalse();
+
+ // Other SDK-declared features should be reported as unavailable.
+ assertThat(cache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0)).isFalse();
+ }
+
+ @Test
+ public void testSdkFeatureHasMinVersion() throws Exception {
+ ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
+ features.put(FEATURE_WATCH, createFeature(FEATURE_WATCH, Integer.MIN_VALUE));
+ SystemFeaturesCache cache = new SystemFeaturesCache(features);
+
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, 0)).isFalse();
+
+ // If both the query and the feature version itself happen to use MIN_VALUE, we can't
+ // reliably indicate availability, so it should report an indeterminate result.
+ assertThat(cache.maybeHasFeature(FEATURE_WATCH, Integer.MIN_VALUE)).isNull();
+ }
+
+ @Test
+ public void testParcel() throws Exception {
+ ArrayMap<String, FeatureInfo> features = new ArrayMap<>();
+ features.put(FEATURE_WATCH, createFeature(FEATURE_WATCH, 0));
+ SystemFeaturesCache cache = new SystemFeaturesCache(features);
+
+ Parcel parcel = Parcel.obtain();
+ SystemFeaturesCache parceledCache;
+ try {
+ parcel.writeParcelable(cache, 0);
+ parcel.setDataPosition(0);
+ parceledCache = parcel.readParcelable(getClass().getClassLoader());
+ } finally {
+ parcel.recycle();
+ }
+
+ assertThat(parceledCache.maybeHasFeature(FEATURE_WATCH, 0))
+ .isEqualTo(cache.maybeHasFeature(FEATURE_WATCH, 0));
+ assertThat(parceledCache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0))
+ .isEqualTo(cache.maybeHasFeature(FEATURE_PICTURE_IN_PICTURE, 0));
+ assertThat(parceledCache.maybeHasFeature("custom.feature", 0))
+ .isEqualTo(cache.maybeHasFeature("custom.feature", 0));
+ }
+
+ private static FeatureInfo createFeature(String name, int version) {
+ FeatureInfo fi = new FeatureInfo();
+ fi.name = name;
+ fi.version = version;
+ return fi;
+ }
+}
diff --git a/core/tests/coretests/src/android/net/http/OWNERS b/core/tests/coretests/src/android/net/http/OWNERS
new file mode 100644
index 000000000000..c93a4195c2d9
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/net/http/OWNERS
diff --git a/core/tests/coretests/src/android/os/BinderProxyTest.java b/core/tests/coretests/src/android/os/BinderProxyTest.java
index 335791c031b4..5fff0b8d0849 100644
--- a/core/tests/coretests/src/android/os/BinderProxyTest.java
+++ b/core/tests/coretests/src/android/os/BinderProxyTest.java
@@ -138,7 +138,7 @@ public class BinderProxyTest {
new Intent(mContext, BinderProxyService.class),
connection,
Context.BIND_AUTO_CREATE);
- if (!bindLatch.await(500, TimeUnit.MILLISECONDS)) {
+ if (!bindLatch.await(1000, TimeUnit.MILLISECONDS)) {
fail(
"Timed out while binding service: "
+ BinderProxyService.class.getSimpleName());
diff --git a/core/tests/coretests/src/android/os/OWNERS b/core/tests/coretests/src/android/os/OWNERS
index c45080fb5e26..5fd4ffc7329a 100644
--- a/core/tests/coretests/src/android/os/OWNERS
+++ b/core/tests/coretests/src/android/os/OWNERS
@@ -10,6 +10,9 @@ per-file PowerManager*.java = file:/services/core/java/com/android/server/power/
# PerformanceHintManager
per-file PerformanceHintManagerTest.java = file:/ADPF_OWNERS
+# SystemHealthManager
+per-file SystemHealthManagerUnitTest.java = file:/ADPF_OWNERS
+
# Caching
per-file IpcDataCache* = file:/PERFORMANCE_OWNERS
diff --git a/core/tests/coretests/src/android/security/advancedprotection/OWNERS b/core/tests/coretests/src/android/security/advancedprotection/OWNERS
new file mode 100644
index 000000000000..9bf5e58c01a9
--- /dev/null
+++ b/core/tests/coretests/src/android/security/advancedprotection/OWNERS
@@ -0,0 +1 @@
+file:platform/frameworks/base:main:/core/java/android/security/advancedprotection/OWNERS
diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java
index d0f9a38720bf..419c05f5b8c1 100644
--- a/core/tests/coretests/src/android/view/MotionEventTest.java
+++ b/core/tests/coretests/src/android/view/MotionEventTest.java
@@ -49,9 +49,14 @@ public class MotionEventTest {
private static final int ID_SOURCE_MASK = 0x3 << 30;
private PointerCoords pointerCoords(float x, float y) {
+ return pointerCoords(x, y, 0f /*orientation*/);
+ }
+
+ private PointerCoords pointerCoords(float x, float y, float orientation) {
final var coords = new PointerCoords();
coords.x = x;
coords.y = y;
+ coords.orientation = orientation;
return coords;
}
@@ -295,4 +300,24 @@ public class MotionEventTest {
// Expected
}
}
+
+ @Test
+ public void testAxesAreNotAffectedByFlagChanges() {
+ final int pointerCount = 1;
+ final var properties = new PointerProperties[]{fingerProperties(0)};
+ final var coords = new PointerCoords[]{pointerCoords(20, 60, 0.1234f)};
+
+ final MotionEvent event = MotionEvent.obtain(0 /* downTime */,
+ 0 /* eventTime */, MotionEvent.ACTION_MOVE, pointerCount, properties, coords,
+ 0 /* metaState */, 0 /* buttonState */, 1 /* xPrecision */, 1 /* yPrecision */,
+ 0 /* deviceId */, 0 /* edgeFlags */, InputDevice.SOURCE_TOUCHSCREEN,
+ 0 /* flags */);
+
+ // Mark the event as tainted to update the MotionEvent flags.
+ event.setTainted(true);
+
+ assertEquals(20f, event.getX(), 0.0001);
+ assertEquals(60f, event.getY(), 0.0001);
+ assertEquals(0.1234f, event.getOrientation(), 0.0001);
+ }
}
diff --git a/core/tests/featureflagtests/OWNERS b/core/tests/featureflagtests/OWNERS
index 2ff4f5ab8807..6784f2891009 100644
--- a/core/tests/featureflagtests/OWNERS
+++ b/core/tests/featureflagtests/OWNERS
@@ -1,2 +1 @@
-sbasi@google.com
-tmfang@google.com \ No newline at end of file
+tmfang@google.com
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
index 634098074cca..9b7200436f02 100644
--- a/core/tests/overlaytests/host/Android.bp
+++ b/core/tests/overlaytests/host/Android.bp
@@ -28,14 +28,14 @@ java_test_host {
test_suites: [
"device-tests",
],
- target_required: [
- "OverlayHostTests_NonPlatformSignatureOverlay",
- "OverlayHostTests_PlatformSignatureStaticOverlay",
- "OverlayHostTests_PlatformSignatureOverlay",
- "OverlayHostTests_UpdateOverlay",
- "OverlayHostTests_FrameworkOverlayV1",
- "OverlayHostTests_FrameworkOverlayV2",
- "OverlayHostTests_AppOverlayV1",
- "OverlayHostTests_AppOverlayV2",
+ device_common_data: [
+ ":OverlayHostTests_NonPlatformSignatureOverlay",
+ ":OverlayHostTests_PlatformSignatureStaticOverlay",
+ ":OverlayHostTests_PlatformSignatureOverlay",
+ ":OverlayHostTests_UpdateOverlay",
+ ":OverlayHostTests_FrameworkOverlayV1",
+ ":OverlayHostTests_FrameworkOverlayV2",
+ ":OverlayHostTests_AppOverlayV1",
+ ":OverlayHostTests_AppOverlayV2",
],
}
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index 85dae631cac3..1251fce1ce19 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -1,11 +1,9 @@
include /PACKAGE_MANAGER_OWNERS
-cbrubaker@google.com
hackbod@android.com
hackbod@google.com
jeffv@google.com
jsharkey@android.com
-jsharkey@google.com
lorenzo@google.com
yamasani@google.com
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index baaec86828eb..ca20aebf95d8 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -210,6 +210,7 @@
<assign-permission name="android.permission.STATSCOMPANION" uid="statsd" />
<assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="statsd" />
+ <assign-permission name="android.permission.REGISTER_STATS_PULL_ATOM" uid="mmd" />
<assign-permission name="android.permission.REGISTER_STATS_PULL_ATOM" uid="gpu_service" />
<assign-permission name="android.permission.REGISTER_STATS_PULL_ATOM" uid="keystore" />
diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml
index 782327713fdc..efa0b8c21695 100644
--- a/data/etc/preinstalled-packages-platform.xml
+++ b/data/etc/preinstalled-packages-platform.xml
@@ -102,7 +102,7 @@ Changes to the whitelist during system updates can result in installing addition
to pre-existing users, but cannot uninstall pre-existing system packages from pre-existing users.
-->
<config>
- <!-- Bluetooth (com.android.btservices apex) - visible on the sharesheet -->
+ <!-- Bluetooth (com.android.bt apex) - visible on the sharesheet -->
<install-in-user-type package="com.android.bluetooth">
<install-in user-type="SYSTEM" />
<install-in user-type="FULL" />
diff --git a/data/fonts/script/test/test_commandline.py b/data/fonts/script/test/test_commandline.py
index 75318cc10e68..dbcba417c5e1 100755
--- a/data/fonts/script/test/test_commandline.py
+++ b/data/fonts/script/test/test_commandline.py
@@ -75,20 +75,20 @@ class CommandlineTest(unittest.TestCase):
functools.partial(CommandlineTest.fileread, filemap),
)
- self.assertEquals("output.xml", args.outfile)
+ self.assertEqual("output.xml", args.outfile)
- self.assertEquals(1, len(args.aliases))
- self.assertEquals("sans-serif-thin", args.aliases[0].name)
- self.assertEquals("sans-serif", args.aliases[0].to)
- self.assertEquals(100, args.aliases[0].weight)
+ self.assertEqual(1, len(args.aliases))
+ self.assertEqual("sans-serif-thin", args.aliases[0].name)
+ self.assertEqual("sans-serif", args.aliases[0].to)
+ self.assertEqual(100, args.aliases[0].weight)
- self.assertEquals(2, len(args.fallback))
+ self.assertEqual(2, len(args.fallback))
# Order is not a part of expectation. Check the expected lang is included.
langs = set(["und-Arab", "und-Ethi"])
self.assertTrue(args.fallback[0].lang in langs)
self.assertTrue(args.fallback[1].lang in langs)
- self.assertEquals(3, len(args.families))
+ self.assertEqual(3, len(args.families))
# Order is not a part of expectation. Check the expected name is included.
names = set(["sans-serif", "sans-serif-condensed", "roboto-flex"])
self.assertTrue(args.families[0].name in names)
diff --git a/data/fonts/script/test/test_xml_builder.py b/data/fonts/script/test/test_xml_builder.py
index 24a033b43cbc..f15c51379b46 100755
--- a/data/fonts/script/test/test_xml_builder.py
+++ b/data/fonts/script/test/test_xml_builder.py
@@ -328,16 +328,16 @@ class XmlBuilderTest(unittest.TestCase):
self.expect_xml(xml)
def expect_xml(self, xml):
- self.assertEquals("sans-serif", xml.families[0].name) # _SANS_SERIF
- self.assertEquals("serif", xml.families[1].name) # _SERIF
- self.assertEquals("und-Arab", xml.families[2].lang) # __ARABIC
- self.assertEquals("elegant", xml.families[2].variant)
- self.assertEquals("und-Arab", xml.families[3].lang) # _ARABIC_UI
- self.assertEquals("zh-Hans", xml.families[4].lang) # _HANS (_HANS_SERIF)
- self.assertEquals(2, len(xml.families[4].fonts))
- self.assertEquals("serif", xml.families[4].fonts[1].fallback_for)
- self.assertEquals("ja", xml.families[5].lang) # _HANS (_HANS_SERIF)
- self.assertEquals("serif", xml.families[5].fonts[1].fallback_for)
+ self.assertEqual("sans-serif", xml.families[0].name) # _SANS_SERIF
+ self.assertEqual("serif", xml.families[1].name) # _SERIF
+ self.assertEqual("und-Arab", xml.families[2].lang) # __ARABIC
+ self.assertEqual("elegant", xml.families[2].variant)
+ self.assertEqual("und-Arab", xml.families[3].lang) # _ARABIC_UI
+ self.assertEqual("zh-Hans", xml.families[4].lang) # _HANS (_HANS_SERIF)
+ self.assertEqual(2, len(xml.families[4].fonts))
+ self.assertEqual("serif", xml.families[4].fonts[1].fallback_for)
+ self.assertEqual("ja", xml.families[5].lang) # _HANS (_HANS_SERIF)
+ self.assertEqual("serif", xml.families[5].fonts[1].fallback_for)
if __name__ == "__main__":
diff --git a/drm/java/android/drm/OWNERS b/drm/java/android/drm/OWNERS
index 43871001c9ad..b65cce70225e 100644
--- a/drm/java/android/drm/OWNERS
+++ b/drm/java/android/drm/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 49079
-jtinker@google.com
robertshih@google.com
diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt
index 087378bef6a1..3da69e854b63 100644
--- a/framework-jarjar-rules.txt
+++ b/framework-jarjar-rules.txt
@@ -10,3 +10,6 @@ rule com.android.modules.utils.build.** android.internal.modules.utils.build.@1
# For Perfetto proto dependencies
rule perfetto.protos.** android.internal.perfetto.protos.@1
+
+# For aconfig storage classes
+rule android.aconfig.storage.** android.internal.aconfig.storage.@1
diff --git a/graphics/java/android/graphics/OWNERS b/graphics/java/android/graphics/OWNERS
index ef8d26cc65b9..1ea197658f93 100644
--- a/graphics/java/android/graphics/OWNERS
+++ b/graphics/java/android/graphics/OWNERS
@@ -2,10 +2,10 @@
romainguy@google.com
jreck@google.com
-njawad@google.com
sumir@google.com
djsollen@google.com
-scroggo@google.com
+alecmouri@google.com
+sallyqi@google.com
per-file BLASTBufferQueue.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file FontFamily.java = file:fonts/OWNERS
diff --git a/graphics/java/android/graphics/pdf/OWNERS b/graphics/java/android/graphics/pdf/OWNERS
index 057dc0d9583c..24557b48ca5a 100644
--- a/graphics/java/android/graphics/pdf/OWNERS
+++ b/graphics/java/android/graphics/pdf/OWNERS
@@ -4,4 +4,3 @@ romainguy@google.com
djsollen@google.com
sumir@google.com
svetoslavganov@android.com
-svetoslavganov@google.com
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 464714fe2895..c2792e1f2394 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -28,7 +28,7 @@ import android.service.gatekeeper.IGateKeeperService;
*
* @hide
*/
-public abstract class GateKeeper {
+public final class GateKeeper {
public static final long INVALID_SECURE_USER_ID = 0;
diff --git a/keystore/java/android/security/keystore/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java
index f22b6041800f..6472ca9957d0 100644
--- a/keystore/java/android/security/keystore/ArrayUtils.java
+++ b/keystore/java/android/security/keystore/ArrayUtils.java
@@ -23,7 +23,7 @@ import java.util.function.Consumer;
/**
* @hide
*/
-public abstract class ArrayUtils {
+public final class ArrayUtils {
private ArrayUtils() {}
public static String[] nullToEmpty(String[] array) {
diff --git a/keystore/java/android/security/keystore/KeyStoreManager.java b/keystore/java/android/security/keystore/KeyStoreManager.java
index 740ccb53a691..13f1a72469c2 100644
--- a/keystore/java/android/security/keystore/KeyStoreManager.java
+++ b/keystore/java/android/security/keystore/KeyStoreManager.java
@@ -312,9 +312,11 @@ public final class KeyStoreManager {
* When passed into getSupplementaryAttestationInfo, getSupplementaryAttestationInfo returns the
* DER-encoded structure corresponding to the `Modules` schema described in the KeyMint HAL's
* KeyCreationResult.aidl. The SHA-256 hash of this encoded structure is what's included with
- * the tag in attestations.
+ * the tag in attestations. To ensure the returned encoded structure is the one attested to,
+ * clients should verify its SHA-256 hash matches the one in the attestation. Note that the
+ * returned structure can vary between boots.
*/
- // TODO(b/369375199): Replace with Tag.MODULE_HASH when flagging is removed.
+ // TODO(b/380020528): Replace with Tag.MODULE_HASH when KeyMint V4 is frozen.
public static final int MODULE_HASH = TagType.BYTES | 724;
/**
diff --git a/keystore/java/android/security/keystore/Utils.java b/keystore/java/android/security/keystore/Utils.java
index e58b1ccb5370..c38ce8e86a15 100644
--- a/keystore/java/android/security/keystore/Utils.java
+++ b/keystore/java/android/security/keystore/Utils.java
@@ -23,7 +23,7 @@ import java.util.Date;
*
* @hide
*/
-abstract class Utils {
+public final class Utils {
private Utils() {}
static Date cloneIfNotNull(Date value) {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index e6c652c14c71..5e93f8db9388 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -20,6 +20,7 @@ import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MG
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.content.Context;
import android.hardware.security.keymint.EcCurve;
import android.hardware.security.keymint.KeyParameter;
@@ -732,6 +733,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
}
}
+ @RequiresPermission(value = android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ conditional = true)
private void addAttestationParameters(@NonNull List<KeyParameter> params)
throws ProviderException, IllegalArgumentException, DeviceIdAttestationException {
byte[] challenge = mSpec.getAttestationChallenge();
@@ -824,7 +827,13 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
break;
}
case AttestationUtils.ID_TYPE_MEID: {
- final String meid = telephonyService.getMeid(0);
+ String meid;
+ try {
+ meid = telephonyService.getMeid(0);
+ } catch (UnsupportedOperationException e) {
+ Log.e(TAG, "Unable to retrieve MEID", e);
+ meid = null;
+ }
if (meid == null) {
throw new DeviceIdAttestationException("Unable to retrieve MEID");
}
diff --git a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
index 1394bd443f03..9d306ce1ed38 100644
--- a/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStore2ParameterUtils.java
@@ -38,7 +38,9 @@ import java.util.function.Consumer;
/**
* @hide
*/
-public abstract class KeyStore2ParameterUtils {
+public final class KeyStore2ParameterUtils {
+
+ private KeyStore2ParameterUtils() {}
/**
* This function constructs a {@link KeyParameter} expressing a boolean value.
diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java
index 614e3684c417..02f3f578d03e 100644
--- a/keystore/java/android/security/keystore2/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore2/KeymasterUtils.java
@@ -16,13 +16,10 @@
package android.security.keystore2;
-import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
-import android.security.keystore.KeyProperties;
import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.InvalidParameterSpecException;
@@ -30,7 +27,7 @@ import java.security.spec.InvalidParameterSpecException;
/**
* @hide
*/
-public abstract class KeymasterUtils {
+public final class KeymasterUtils {
private KeymasterUtils() {}
@@ -86,47 +83,6 @@ public abstract class KeymasterUtils {
}
}
- /**
- * Adds {@code KM_TAG_MIN_MAC_LENGTH} tag, if necessary, to the keymaster arguments for
- * generating or importing a key. This tag may only be needed for symmetric keys (e.g., HMAC,
- * AES-GCM).
- */
- public static void addMinMacLengthAuthorizationIfNecessary(KeymasterArguments args,
- int keymasterAlgorithm,
- int[] keymasterBlockModes,
- int[] keymasterDigests) {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_AES:
- if (com.android.internal.util.ArrayUtils.contains(
- keymasterBlockModes, KeymasterDefs.KM_MODE_GCM)) {
- // AES GCM key needs the minimum length of AEAD tag specified.
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH,
- AndroidKeyStoreAuthenticatedAESCipherSpi.GCM
- .MIN_SUPPORTED_TAG_LENGTH_BITS);
- }
- break;
- case KeymasterDefs.KM_ALGORITHM_HMAC:
- // HMAC key needs the minimum length of MAC set to the output size of the associated
- // digest. This is because we do not offer a way to generate shorter MACs and
- // don't offer a way to verify MACs (other than by generating them).
- if (keymasterDigests.length != 1) {
- throw new ProviderException(
- "Unsupported number of authorized digests for HMAC key: "
- + keymasterDigests.length
- + ". Exactly one digest must be authorized");
- }
- int keymasterDigest = keymasterDigests[0];
- int digestOutputSizeBits = getDigestOutputSizeBits(keymasterDigest);
- if (digestOutputSizeBits == -1) {
- throw new ProviderException(
- "HMAC key authorized for unsupported digest: "
- + KeyProperties.Digest.fromKeymaster(keymasterDigest));
- }
- args.addUnsignedInt(KeymasterDefs.KM_TAG_MIN_MAC_LENGTH, digestOutputSizeBits);
- break;
- }
- }
-
static String getEcCurveFromKeymaster(int ecCurve) {
switch (ecCurve) {
case android.hardware.security.keymint.EcCurve.P_224:
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index 394093c6ab30..ab2f3ef94eb6 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -1,7 +1,7 @@
-xutan@google.com
+jorgegil@google.com
pbdr@google.com
pragyabajoria@google.com
# Give submodule owners in shell resource approval
-per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com
+per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com
per-file res*/*/tv_*.xml = bronger@google.com
diff --git a/libs/WindowManager/Shell/multivalentTests/Android.bp b/libs/WindowManager/Shell/multivalentTests/Android.bp
index 41d1b5c15369..5ef1565b10fc 100644
--- a/libs/WindowManager/Shell/multivalentTests/Android.bp
+++ b/libs/WindowManager/Shell/multivalentTests/Android.bp
@@ -35,7 +35,6 @@ android_app {
android_robolectric_test {
name: "WMShellRobolectricTests",
instrumentation_for: "WindowManagerShellRobolectric",
- upstream: true,
java_resource_dirs: [
"robolectric/config",
],
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS
index 6207e5b020f7..7e557860365e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apptoweb/OWNERS
@@ -4,5 +4,4 @@ madym@google.com
mattsziklay@google.com
mdehaini@google.com
pbdr@google.com
-tkachenkoi@google.com
vaniadesmonda@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index bcd40a9a9765..c4696d5f44f4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -192,15 +192,22 @@ public final class SyncTransactionQueue {
throw new IllegalStateException("Sync Transactions must be serialized. In Flight: "
+ mInFlight.mId + " - " + mInFlight.mWCT);
}
- mInFlight = this;
if (DEBUG) Slog.d(TAG, "Sending sync transaction: " + mWCT);
- if (mLegacyTransition != null) {
- mId = new WindowOrganizer().startLegacyTransition(mLegacyTransition.getType(),
- mLegacyTransition.getAdapter(), this, mWCT);
- } else {
- mId = new WindowOrganizer().applySyncTransaction(mWCT, this);
+ try {
+ if (mLegacyTransition != null) {
+ mId = new WindowOrganizer().startLegacyTransition(mLegacyTransition.getType(),
+ mLegacyTransition.getAdapter(), this, mWCT);
+ } else {
+ mId = new WindowOrganizer().applySyncTransaction(mWCT, this);
+ }
+ } catch (RuntimeException e) {
+ Slog.e(TAG, "Send failed", e);
+ // Finish current sync callback immediately.
+ onTransactionReady(mId, new SurfaceControl.Transaction());
+ return;
}
if (DEBUG) Slog.d(TAG, " Sent sync transaction. Got id=" + mId);
+ mInFlight = this;
mMainExecutor.executeDelayed(mOnReplyTimeout, REPLY_TIMEOUT);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
index afdda8ff865e..47b3ae8fc11b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
@@ -3,7 +3,6 @@ atsjenk@google.com
jorgegil@google.com
madym@google.com
pbdr@google.com
-tkachenkoi@google.com
vaniadesmonda@google.com
pragyabajoria@google.com
uysalorhan@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
index 83b5bf658459..7a63ec5eeda3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
@@ -2,9 +2,7 @@
atsjenk@google.com
jorgegil@google.com
madym@google.com
-nmusgrave@google.com
pbdr@google.com
-tkachenkoi@google.com
vaniadesmonda@google.com
pragyabajoria@google.com
uysalorhan@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
index 5aa3c4e2abef..245669b644db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
@@ -1,3 +1,2 @@
# WM shell sub-module TV pip owner
-galinap@google.com
bronger@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 032dac9ff3a2..1345896547a1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -1145,9 +1145,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler,
change, layer, info, t, mLeashMap);
appearedTargets[nextTargetIdx++] = target;
// reparent into the original `mInfo` since that's where we are animating.
- final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
+ final TransitionInfo.Root root = TransitionUtil.getRootFor(change, mInfo);
final boolean wasClosing = closingIdx >= 0;
- t.reparent(target.leash, mInfo.getRoot(rootIdx).getLeash());
+ t.reparent(target.leash, root.getLeash());
+ t.setPosition(target.leash,
+ change.getStartAbsBounds().left - root.getOffset().x,
+ change.getStartAbsBounds().top - root.getOffset().y);
t.setLayer(target.leash, layer);
if (wasClosing) {
// App was previously visible and is closing
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index ba724edb9747..beb54baab3ed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -2963,7 +2963,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitLayout.update(startTransaction, false /* resetImePosition */);
}
- if (mMixedHandler.isEnteringPip(change, transitType)) {
+ if (mMixedHandler.isEnteringPip(change, transitType)
+ && getSplitItemStage(change.getLastParent()) != STAGE_TYPE_UNDEFINED) {
pipChange = change;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS
index 28be0efc38f6..9dc0ebbb8e56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/OWNERS
@@ -1,3 +1,2 @@
# WM shell sub-module TV splitscreen owner
-galinap@google.com
bronger@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
index eaeedba8ef9c..831eb4d0b055 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTaskController.java
@@ -535,9 +535,12 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
}
return;
}
+ // Cache it to avoid NPE and make sure to remove it from recents history.
+ // mTaskToken can be cleared in onTaskVanished() when the task is removed.
+ final WindowContainerToken taskToken = mTaskToken;
mShellExecutor.execute(() -> {
WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.removeTask(mTaskToken);
+ wct.removeTask(taskToken);
mTaskViewTransitions.closeTaskView(wct, this);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
index 3f828f547920..992402528f4f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
@@ -1,3 +1,2 @@
-jorgegil@google.com
mattsziklay@google.com
mdehaini@google.com
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index 19829e7e5677..bac8e5062128 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -12,7 +12,6 @@ atsjenk@google.com
jorgegil@google.com
vaniadesmonda@google.com
pbdr@google.com
-tkachenkoi@google.com
mpodolian@google.com
jeremysim@google.com
peanutbutter@google.com
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/OWNERS b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/OWNERS
index 736d4cff6ce8..a7d1890a0286 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/OWNERS
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/OWNERS
@@ -1,3 +1,2 @@
# WM shell sub-module TV pip owners
-galinap@google.com
-bronger@google.com \ No newline at end of file
+bronger@google.com
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 1bc15d72bacc..104ba018fb62 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -80,6 +80,7 @@ cc_library {
"LoadedArsc.cpp",
"Locale.cpp",
"LocaleData.cpp",
+ "LocaleDataLookup.cpp",
"misc.cpp",
"NinePatch.cpp",
"ObbFile.cpp",
@@ -224,6 +225,7 @@ cc_test {
"tests/Idmap_test.cpp",
"tests/LoadedArsc_test.cpp",
"tests/Locale_test.cpp",
+ "tests/LocaleDataLookup_test.cpp",
"tests/NinePatch_test.cpp",
"tests/ResourceTimer_test.cpp",
"tests/ResourceUtils_test.cpp",
@@ -285,6 +287,7 @@ cc_benchmark {
"tests/AttributeResolution_bench.cpp",
"tests/CursorWindow_bench.cpp",
"tests/Generic_bench.cpp",
+ "tests/LocaleDataLookup_bench.cpp",
"tests/SparseEntry_bench.cpp",
"tests/Theme_bench.cpp",
],
diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp
index 020cef6012e9..1b23d90c5ab3 100644
--- a/libs/androidfw/LocaleData.cpp
+++ b/libs/androidfw/LocaleData.cpp
@@ -23,39 +23,18 @@
#include <unordered_set>
#include <androidfw/LocaleData.h>
+#include <androidfw/LocaleDataLookup.h>
namespace android {
-#include "LocaleDataTables.cpp"
-
-inline uint32_t packLocale(const char* language, const char* region) {
- return (((uint8_t) language[0]) << 24u) | (((uint8_t) language[1]) << 16u) |
- (((uint8_t) region[0]) << 8u) | ((uint8_t) region[1]);
-}
-
-inline uint32_t dropRegion(uint32_t packed_locale) {
- return packed_locale & 0xFFFF0000LU;
-}
-
-inline bool hasRegion(uint32_t packed_locale) {
- return (packed_locale & 0x0000FFFFLU) != 0;
-}
-
-const size_t SCRIPT_LENGTH = 4;
-const size_t SCRIPT_PARENTS_COUNT = sizeof(SCRIPT_PARENTS)/sizeof(SCRIPT_PARENTS[0]);
const uint32_t PACKED_ROOT = 0; // to represent the root locale
+const uint32_t MAX_PARENT_DEPTH = getMaxAncestorTreeDepth();
uint32_t findParent(uint32_t packed_locale, const char* script) {
if (hasRegion(packed_locale)) {
- for (size_t i = 0; i < SCRIPT_PARENTS_COUNT; i++) {
- if (memcmp(script, SCRIPT_PARENTS[i].script, SCRIPT_LENGTH) == 0) {
- auto map = SCRIPT_PARENTS[i].map;
- auto lookup_result = map->find(packed_locale);
- if (lookup_result != map->end()) {
- return lookup_result->second;
- }
- break;
- }
+ auto parent_key = findParentLocalePackedKey(script, packed_locale);
+ if (parent_key != 0) {
+ return parent_key;
}
return dropRegion(packed_locale);
}
@@ -111,17 +90,6 @@ size_t findDistance(uint32_t supported,
return supported_ancestor_count + request_ancestors_index - 1;
}
-inline bool isRepresentative(uint32_t language_and_region, const char* script) {
- const uint64_t packed_locale = (
- (((uint64_t) language_and_region) << 32u) |
- (((uint64_t) script[0]) << 24u) |
- (((uint64_t) script[1]) << 16u) |
- (((uint64_t) script[2]) << 8u) |
- ((uint64_t) script[3]));
-
- return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);
-}
-
const uint32_t US_SPANISH = 0x65735553LU; // es-US
const uint32_t MEXICAN_SPANISH = 0x65734D58LU; // es-MX
const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424LU; // es-419
@@ -185,8 +153,8 @@ int localeDataCompareRegions(
// If we are here, left and right are equidistant from the request. We will
// try and see if any of them is a representative locale.
- const bool left_is_representative = isRepresentative(left, requested_script);
- const bool right_is_representative = isRepresentative(right, requested_script);
+ const bool left_is_representative = isLocaleRepresentative(left, requested_script);
+ const bool right_is_representative = isLocaleRepresentative(right, requested_script);
if (left_is_representative != right_is_representative) {
return (int) left_is_representative - (int) right_is_representative;
}
@@ -204,14 +172,14 @@ void localeDataComputeScript(char out[4], const char* language, const char* regi
return;
}
uint32_t lookup_key = packLocale(language, region);
- auto lookup_result = LIKELY_SCRIPTS.find(lookup_key);
- if (lookup_result == LIKELY_SCRIPTS.end()) {
+ auto lookup_result = lookupLikelyScript(lookup_key);
+ if (lookup_result == nullptr) {
// We couldn't find the locale. Let's try without the region
if (region[0] != '\0') {
lookup_key = dropRegion(lookup_key);
- lookup_result = LIKELY_SCRIPTS.find(lookup_key);
- if (lookup_result != LIKELY_SCRIPTS.end()) {
- memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+ lookup_result = lookupLikelyScript(lookup_key);
+ if (lookup_result != nullptr) {
+ memcpy(out, lookup_result, SCRIPT_LENGTH);
return;
}
}
@@ -220,7 +188,7 @@ void localeDataComputeScript(char out[4], const char* language, const char* regi
return;
} else {
// We found the locale.
- memcpy(out, SCRIPT_CODES[lookup_result->second], SCRIPT_LENGTH);
+ memcpy(out, lookup_result, SCRIPT_LENGTH);
}
}
diff --git a/libs/androidfw/LocaleDataLookup.cpp b/libs/androidfw/LocaleDataLookup.cpp
new file mode 100644
index 000000000000..9aacdcb9ca92
--- /dev/null
+++ b/libs/androidfw/LocaleDataLookup.cpp
@@ -0,0 +1,14964 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+
+
+// Auto-generated by ./tools/localedata/extract_icu_data.py
+
+#include <androidfw/LocaleDataLookup.h>
+
+namespace android {
+
+constexpr const char SCRIPT_CODES[][4] = {
+ /* 0 */ {'A', 'g', 'h', 'b'},
+ /* 1 */ {'A', 'h', 'o', 'm'},
+ /* 2 */ {'A', 'r', 'a', 'b'},
+ /* 3 */ {'A', 'r', 'm', 'i'},
+ /* 4 */ {'A', 'r', 'm', 'n'},
+ /* 5 */ {'A', 'v', 's', 't'},
+ /* 6 */ {'B', 'a', 'm', 'u'},
+ /* 7 */ {'B', 'a', 's', 's'},
+ /* 8 */ {'B', 'a', 't', 'k'},
+ /* 9 */ {'B', 'e', 'n', 'g'},
+ /* 10 */ {'B', 'o', 'p', 'o'},
+ /* 11 */ {'B', 'r', 'a', 'h'},
+ /* 12 */ {'C', 'a', 'k', 'm'},
+ /* 13 */ {'C', 'a', 'n', 's'},
+ /* 14 */ {'C', 'a', 'r', 'i'},
+ /* 15 */ {'C', 'h', 'a', 'm'},
+ /* 16 */ {'C', 'h', 'e', 'r'},
+ /* 17 */ {'C', 'h', 'r', 's'},
+ /* 18 */ {'C', 'o', 'p', 't'},
+ /* 19 */ {'C', 'p', 'r', 't'},
+ /* 20 */ {'C', 'y', 'r', 'l'},
+ /* 21 */ {'D', 'e', 'v', 'a'},
+ /* 22 */ {'E', 'g', 'y', 'p'},
+ /* 23 */ {'E', 'l', 'y', 'm'},
+ /* 24 */ {'E', 't', 'h', 'i'},
+ /* 25 */ {'G', 'e', 'o', 'r'},
+ /* 26 */ {'G', 'o', 'n', 'g'},
+ /* 27 */ {'G', 'o', 'n', 'm'},
+ /* 28 */ {'G', 'o', 't', 'h'},
+ /* 29 */ {'G', 'r', 'a', 'n'},
+ /* 30 */ {'G', 'r', 'e', 'k'},
+ /* 31 */ {'G', 'u', 'j', 'r'},
+ /* 32 */ {'G', 'u', 'r', 'u'},
+ /* 33 */ {'H', 'a', 'n', 'g'},
+ /* 34 */ {'H', 'a', 'n', 'i'},
+ /* 35 */ {'H', 'a', 'n', 's'},
+ /* 36 */ {'H', 'a', 'n', 't'},
+ /* 37 */ {'H', 'e', 'b', 'r'},
+ /* 38 */ {'H', 'l', 'u', 'w'},
+ /* 39 */ {'H', 'm', 'n', 'p'},
+ /* 40 */ {'I', 't', 'a', 'l'},
+ /* 41 */ {'J', 'a', 'v', 'a'},
+ /* 42 */ {'J', 'p', 'a', 'n'},
+ /* 43 */ {'K', 'a', 'l', 'i'},
+ /* 44 */ {'K', 'a', 'n', 'a'},
+ /* 45 */ {'K', 'a', 'w', 'i'},
+ /* 46 */ {'K', 'h', 'a', 'r'},
+ /* 47 */ {'K', 'h', 'm', 'r'},
+ /* 48 */ {'K', 'i', 't', 's'},
+ /* 49 */ {'K', 'n', 'd', 'a'},
+ /* 50 */ {'K', 'o', 'r', 'e'},
+ /* 51 */ {'L', 'a', 'n', 'a'},
+ /* 52 */ {'L', 'a', 'o', 'o'},
+ /* 53 */ {'L', 'a', 't', 'f'},
+ /* 54 */ {'L', 'a', 't', 'g'},
+ /* 55 */ {'L', 'a', 't', 'n'},
+ /* 56 */ {'L', 'e', 'p', 'c'},
+ /* 57 */ {'L', 'i', 'n', 'a'},
+ /* 58 */ {'L', 'i', 'n', 'b'},
+ /* 59 */ {'L', 'i', 's', 'u'},
+ /* 60 */ {'L', 'y', 'c', 'i'},
+ /* 61 */ {'L', 'y', 'd', 'i'},
+ /* 62 */ {'M', 'a', 'n', 'd'},
+ /* 63 */ {'M', 'a', 'n', 'i'},
+ /* 64 */ {'M', 'a', 'r', 'c'},
+ /* 65 */ {'M', 'e', 'd', 'f'},
+ /* 66 */ {'M', 'e', 'r', 'c'},
+ /* 67 */ {'M', 'l', 'y', 'm'},
+ /* 68 */ {'M', 'o', 'd', 'i'},
+ /* 69 */ {'M', 'o', 'n', 'g'},
+ /* 70 */ {'M', 'r', 'o', 'o'},
+ /* 71 */ {'M', 't', 'e', 'i'},
+ /* 72 */ {'M', 'y', 'm', 'r'},
+ /* 73 */ {'N', 'a', 'r', 'b'},
+ /* 74 */ {'N', 'e', 'w', 'a'},
+ /* 75 */ {'N', 'k', 'o', 'o'},
+ /* 76 */ {'N', 's', 'h', 'u'},
+ /* 77 */ {'O', 'g', 'a', 'm'},
+ /* 78 */ {'O', 'l', 'c', 'k'},
+ /* 79 */ {'O', 'r', 'k', 'h'},
+ /* 80 */ {'O', 'r', 'y', 'a'},
+ /* 81 */ {'O', 's', 'g', 'e'},
+ /* 82 */ {'O', 'u', 'g', 'r'},
+ /* 83 */ {'P', 'a', 'u', 'c'},
+ /* 84 */ {'P', 'h', 'l', 'i'},
+ /* 85 */ {'P', 'h', 'n', 'x'},
+ /* 86 */ {'P', 'l', 'r', 'd'},
+ /* 87 */ {'P', 'r', 't', 'i'},
+ /* 88 */ {'R', 'j', 'n', 'g'},
+ /* 89 */ {'R', 'o', 'h', 'g'},
+ /* 90 */ {'R', 'u', 'n', 'r'},
+ /* 91 */ {'S', 'a', 'm', 'r'},
+ /* 92 */ {'S', 'a', 'r', 'b'},
+ /* 93 */ {'S', 'a', 'u', 'r'},
+ /* 94 */ {'S', 'g', 'n', 'w'},
+ /* 95 */ {'S', 'i', 'n', 'h'},
+ /* 96 */ {'S', 'o', 'g', 'd'},
+ /* 97 */ {'S', 'o', 'r', 'a'},
+ /* 98 */ {'S', 'o', 'y', 'o'},
+ /* 99 */ {'S', 'u', 'n', 'u'},
+ /* 100 */ {'S', 'y', 'r', 'c'},
+ /* 101 */ {'T', 'a', 'g', 'b'},
+ /* 102 */ {'T', 'a', 'k', 'r'},
+ /* 103 */ {'T', 'a', 'l', 'e'},
+ /* 104 */ {'T', 'a', 'l', 'u'},
+ /* 105 */ {'T', 'a', 'm', 'l'},
+ /* 106 */ {'T', 'a', 'n', 'g'},
+ /* 107 */ {'T', 'a', 'v', 't'},
+ /* 108 */ {'T', 'e', 'l', 'u'},
+ /* 109 */ {'T', 'f', 'n', 'g'},
+ /* 110 */ {'T', 'h', 'a', 'a'},
+ /* 111 */ {'T', 'h', 'a', 'i'},
+ /* 112 */ {'T', 'i', 'b', 't'},
+ /* 113 */ {'T', 'n', 's', 'a'},
+ /* 114 */ {'T', 'o', 't', 'o'},
+ /* 115 */ {'U', 'g', 'a', 'r'},
+ /* 116 */ {'V', 'a', 'i', 'i'},
+ /* 117 */ {'W', 'c', 'h', 'o'},
+ /* 118 */ {'X', 'p', 'e', 'o'},
+ /* 119 */ {'X', 's', 'u', 'x'},
+ /* 120 */ {'Y', 'i', 'i', 'i'},
+ /* 121 */ {'~', '~', '~', 'A'},
+ /* 122 */ {'~', '~', '~', 'B'},
+};
+
+
+const char* lookupLikelyScript(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x98170000u: // xag -> Aghb
+ return SCRIPT_CODES[ 0u];
+ case 0xB8E00000u: // aho -> Ahom
+ return SCRIPT_CODES[ 1u];
+ case 0xB8000000u: // aao -> Arab
+ case 0x9C200000u: // abh -> Arab
+ case 0xD4200000u: // abv -> Arab
+ case 0xB0400000u: // acm -> Arab
+ case 0xC0400000u: // acq -> Arab
+ case 0xD8400000u: // acw -> Arab
+ case 0xDC400000u: // acx -> Arab
+ case 0x94600000u: // adf -> Arab
+ case 0x84800000u: // aeb -> Arab
+ case 0x88800000u: // aec -> Arab
+ case 0x90800000u: // aee -> Arab
+ case 0xC0800000u: // aeq -> Arab
+ case 0x84A00000u: // afb -> Arab
+ case 0x85000000u: // aib -> Arab
+ case 0xC1000000u: // aiq -> Arab
+ case 0x89E00000u: // apc -> Arab
+ case 0x8DE00000u: // apd -> Arab
+ case 0x61720000u: // ar -> Arab
+ case 0xC2200000u: // arq -> Arab
+ case 0xCA200000u: // ars -> Arab
+ case 0xE2200000u: // ary -> Arab
+ case 0xE6200000u: // arz -> Arab
+ case 0xAA400000u: // ask -> Arab
+ case 0xB6600000u: // atn -> Arab
+ case 0xA6800000u: // auj -> Arab
+ case 0xE6800000u: // auz -> Arab
+ case 0x8EA00000u: // avd -> Arab
+ case 0xAEA00000u: // avl -> Arab
+ case 0x9F000000u: // ayh -> Arab
+ case 0xAF000000u: // ayl -> Arab
+ case 0xB7000000u: // ayn -> Arab
+ case 0xBF000000u: // ayp -> Arab
+ case 0x617A4951u: // az-IQ -> Arab
+ case 0x617A4952u: // az-IR -> Arab
+ case 0x87200000u: // azb -> Arab
+ case 0xAC010000u: // bal -> Arab
+ case 0xE4610000u: // bdz -> Arab
+ case 0xA4810000u: // bej -> Arab
+ case 0xCCA10000u: // bft -> Arab
+ case 0xB4C10000u: // bgn -> Arab
+ case 0xBCC10000u: // bgp -> Arab
+ case 0x90E10000u: // bhe -> Arab
+ case 0xB0E10000u: // bhm -> Arab
+ case 0xB1210000u: // bjm -> Arab
+ case 0xA2010000u: // bqi -> Arab
+ case 0x9E210000u: // brh -> Arab
+ case 0xAA210000u: // brk -> Arab
+ case 0x9E410000u: // bsh -> Arab
+ case 0xAA410000u: // bsk -> Arab
+ case 0x98E20000u: // chg -> Arab
+ case 0x81220000u: // cja -> Arab
+ case 0x85420000u: // ckb -> Arab
+ case 0x9D620000u: // clh -> Arab
+ case 0x88430000u: // dcc -> Arab
+ case 0x94830000u: // def -> Arab
+ case 0x9C830000u: // deh -> Arab
+ case 0xACC30000u: // dgl -> Arab
+ case 0xA9830000u: // dmk -> Arab
+ case 0xAD830000u: // dml -> Arab
+ case 0x9E440000u: // esh -> Arab
+ case 0x66610000u: // fa -> Arab
+ case 0xE0050000u: // fay -> Arab
+ case 0xE4050000u: // faz -> Arab
+ case 0x81050000u: // fia -> Arab
+ case 0x86850000u: // fub -> Arab
+ case 0xE4260000u: // gbz -> Arab
+ case 0x98C60000u: // ggg -> Arab
+ case 0x80E60000u: // gha -> Arab
+ case 0xC4E60000u: // ghr -> Arab
+ case 0x99060000u: // gig -> Arab
+ case 0xA9260000u: // gjk -> Arab
+ case 0xD1260000u: // gju -> Arab
+ case 0x9D660000u: // glh -> Arab
+ case 0xA9660000u: // glk -> Arab
+ case 0x8AC60000u: // gwc -> Arab
+ case 0x96C60000u: // gwf -> Arab
+ case 0xCEC60000u: // gwt -> Arab
+ case 0xA3260000u: // gzi -> Arab
+ case 0x6861434Du: // ha-CM -> Arab
+ case 0x68615344u: // ha-SD -> Arab
+ case 0x88070000u: // hac -> Arab
+ case 0xE4070000u: // haz -> Arab
+ case 0x9D470000u: // hkh -> Arab
+ case 0x8DA70000u: // hnd -> Arab
+ case 0xB9A70000u: // hno -> Arab
+ case 0x9DC70000u: // hoh -> Arab
+ case 0xE6270000u: // hrz -> Arab
+ case 0xCA470000u: // hss -> Arab
+ case 0xAA480000u: // isk -> Arab
+ case 0x8C090000u: // jad -> Arab
+ case 0xCC090000u: // jat -> Arab
+ case 0xB4290000u: // jbn -> Arab
+ case 0x98690000u: // jdg -> Arab
+ case 0x8DA90000u: // jnd -> Arab
+ case 0x99C90000u: // jog -> Arab
+ case 0xD02A0000u: // kbu -> Arab
+ case 0xE02A0000u: // kby -> Arab
+ case 0xE04A0000u: // kcy -> Arab
+ case 0xB0AA0000u: // kfm -> Arab
+ case 0xD8EA0000u: // khw -> Arab
+ case 0x6B6B4146u: // kk-AF -> Arab
+ case 0x6B6B434Eu: // kk-CN -> Arab
+ case 0x6B6B4952u: // kk-IR -> Arab
+ case 0x6B6B4D4Eu: // kk-MN -> Arab
+ case 0xA56A0000u: // klj -> Arab
+ case 0xE58A0000u: // kmz -> Arab
+ case 0x6B730000u: // ks -> Arab
+ case 0xAE6A0000u: // ktl -> Arab
+ case 0x6B754C42u: // ku-LB -> Arab
+ case 0xDEAA0000u: // kvx -> Arab
+ case 0xBEEA0000u: // kxp -> Arab
+ case 0x6B79434Eu: // ky-CN -> Arab
+ case 0x9C0B0000u: // lah -> Arab
+ case 0xA14B0000u: // lki -> Arab
+ case 0x8A2B0000u: // lrc -> Arab
+ case 0xAA2B0000u: // lrk -> Arab
+ case 0xAE2B0000u: // lrl -> Arab
+ case 0x824B0000u: // lsa -> Arab
+ case 0xCA4B0000u: // lss -> Arab
+ case 0xD68B0000u: // luv -> Arab
+ case 0xE68B0000u: // luz -> Arab
+ case 0xE02C0000u: // mby -> Arab
+ case 0x906C0000u: // mde -> Arab
+ case 0x80AC0000u: // mfa -> Arab
+ case 0xA0AC0000u: // mfi -> Arab
+ case 0xA4EC0000u: // mhj -> Arab
+ case 0xA14C0000u: // mki -> Arab
+ case 0xA5AC0000u: // mnj -> Arab
+ case 0x6D734343u: // ms-CC -> Arab
+ case 0x92AC0000u: // mve -> Arab
+ case 0xE2AC0000u: // mvy -> Arab
+ case 0xB72C0000u: // mzn -> Arab
+ case 0xA16D0000u: // nli -> Arab
+ case 0xB16D0000u: // nlm -> Arab
+ case 0xE66D0000u: // ntz -> Arab
+ case 0xC30D0000u: // nyq -> Arab
+ case 0xA86E0000u: // odk -> Arab
+ case 0xD22E0000u: // oru -> Arab
+ case 0x826E0000u: // ota -> Arab
+ case 0x7061504Bu: // pa-PK -> Arab
+ case 0xCC2F0000u: // pbt -> Arab
+ case 0xACEF0000u: // phl -> Arab
+ case 0xC4EF0000u: // phr -> Arab
+ case 0xD4EF0000u: // phv -> Arab
+ case 0xA96F0000u: // plk -> Arab
+ case 0x8A2F0000u: // prc -> Arab
+ case 0x8E2F0000u: // prd -> Arab
+ case 0xDE2F0000u: // prx -> Arab
+ case 0x70730000u: // ps -> Arab
+ case 0x9E4F0000u: // psh -> Arab
+ case 0xA24F0000u: // psi -> Arab
+ case 0xCE4F0000u: // pst -> Arab
+ case 0xC2F00000u: // qxq -> Arab
+ case 0x84710000u: // rdb -> Arab
+ case 0xCD910000u: // rmt -> Arab
+ case 0xB4320000u: // sbn -> Arab
+ case 0xAC520000u: // scl -> Arab
+ case 0x73640000u: // sd -> Arab
+ case 0x84720000u: // sdb -> Arab
+ case 0x94720000u: // sdf -> Arab
+ case 0x98720000u: // sdg -> Arab
+ case 0x9C720000u: // sdh -> Arab
+ case 0xC8720000u: // sds -> Arab
+ case 0xC4D20000u: // sgr -> Arab
+ case 0xE0D20000u: // sgy -> Arab
+ case 0x8CF20000u: // shd -> Arab
+ case 0xB0F20000u: // shm -> Arab
+ case 0xD0F20000u: // shu -> Arab
+ case 0xD4F20000u: // shv -> Arab
+ case 0xE1120000u: // siy -> Arab
+ case 0xE5120000u: // siz -> Arab
+ case 0xC5520000u: // skr -> Arab
+ case 0xE1920000u: // smy -> Arab
+ case 0xBA120000u: // sqo -> Arab
+ case 0xCE120000u: // sqt -> Arab
+ case 0x9E320000u: // srh -> Arab
+ case 0xE6320000u: // srz -> Arab
+ case 0x9E520000u: // ssh -> Arab
+ case 0xCA720000u: // sts -> Arab
+ case 0x86D20000u: // swb -> Arab
+ case 0x7467504Bu: // tg-PK -> Arab
+ case 0xB9330000u: // tjo -> Arab
+ case 0xC9530000u: // tks -> Arab
+ case 0xD5D30000u: // tov -> Arab
+ case 0x82330000u: // tra -> Arab
+ case 0xB2330000u: // trm -> Arab
+ case 0xDA330000u: // trw -> Arab
+ case 0x75670000u: // ug -> Arab
+ case 0x75720000u: // ur -> Arab
+ case 0x9E540000u: // ush -> Arab
+ case 0x757A4146u: // uz-AF -> Arab
+ case 0xCB340000u: // uzs -> Arab
+ case 0x94150000u: // vaf -> Arab
+ case 0xC4D50000u: // vgr -> Arab
+ case 0x9D950000u: // vmh -> Arab
+ case 0xA8360000u: // wbk -> Arab
+ case 0xB9760000u: // wlo -> Arab
+ case 0x91B60000u: // wne -> Arab
+ case 0xA1B60000u: // wni -> Arab
+ case 0xD6560000u: // wsv -> Arab
+ case 0x90F70000u: // xhe -> Arab
+ case 0x81570000u: // xka -> Arab
+ case 0x89570000u: // xkc -> Arab
+ case 0xA5570000u: // xkj -> Arab
+ case 0xBD570000u: // xkp -> Arab
+ case 0xA2B70000u: // xvi -> Arab
+ case 0x98780000u: // ydg -> Arab
+ case 0x80390000u: // zba -> Arab
+ case 0xA4790000u: // zdj -> Arab
+ case 0xB2990000u: // zum -> Arab
+ return SCRIPT_CODES[ 2u];
+ case 0x8A200000u: // arc -> Armi
+ return SCRIPT_CODES[ 3u];
+ case 0xB2E00000u: // axm -> Armn
+ case 0x68790000u: // hy -> Armn
+ case 0xDB070000u: // hyw -> Armn
+ case 0xA1910000u: // rmi -> Armn
+ return SCRIPT_CODES[ 4u];
+ case 0x61650000u: // ae -> Avst
+ return SCRIPT_CODES[ 5u];
+ case 0xDC010000u: // bax -> Bamu
+ return SCRIPT_CODES[ 6u];
+ case 0xC2410000u: // bsq -> Bass
+ return SCRIPT_CODES[ 7u];
+ case 0x8E610000u: // btd -> Batk
+ case 0xB2610000u: // btm -> Batk
+ return SCRIPT_CODES[ 8u];
+ case 0xCDC00000u: // aot -> Beng
+ case 0x61730000u: // as -> Beng
+ case 0x626E0000u: // bn -> Beng
+ case 0xE1E10000u: // bpy -> Beng
+ case 0xE4620000u: // cdz -> Beng
+ case 0x9A620000u: // ctg -> Beng
+ case 0xC4830000u: // der -> Beng
+ case 0xCE260000u: // grt -> Beng
+ case 0xC06A0000u: // kdq -> Beng
+ case 0xA1AC0000u: // mni -> Beng
+ case 0x9C110000u: // rah -> Beng
+ case 0xCD510000u: // rkt -> Beng
+ case 0xC4720000u: // sdr -> Beng
+ case 0xAF120000u: // syl -> Beng
+ case 0xC5B40000u: // unr -> Beng
+ case 0xDDB40000u: // unx -> Beng
+ return SCRIPT_CODES[ 9u];
+ case 0xA5870000u: // hmj -> Bopo
+ case 0xC1870000u: // hmq -> Bopo
+ return SCRIPT_CODES[10u];
+ case 0xB8EA0000u: // kho -> Brah
+ case 0x814F0000u: // pka -> Brah
+ case 0x9D8F0000u: // pmh -> Brah
+ case 0xD24F0000u: // psu -> Brah
+ case 0xC2770000u: // xtq -> Brah
+ return SCRIPT_CODES[11u];
+ case 0xBC420000u: // ccp -> Cakm
+ case 0xD5B30000u: // tnv -> Cakm
+ return SCRIPT_CODES[12u];
+ case 0x63720000u: // cr -> Cans
+ case 0xA6220000u: // crj -> Cans
+ case 0xAA220000u: // crk -> Cans
+ case 0xAE220000u: // crl -> Cans
+ case 0xB2220000u: // crm -> Cans
+ case 0xDA420000u: // csw -> Cans
+ case 0x69750000u: // iu -> Cans
+ case 0xAA4D0000u: // nsk -> Cans
+ case 0x6F6A0000u: // oj -> Cans
+ case 0xC92E0000u: // ojs -> Cans
+ return SCRIPT_CODES[13u];
+ case 0xC4570000u: // xcr -> Cari
+ return SCRIPT_CODES[14u];
+ case 0xB1220000u: // cjm -> Cham
+ return SCRIPT_CODES[15u];
+ case 0xC4E20000u: // chr -> Cher
+ return SCRIPT_CODES[16u];
+ case 0xB8570000u: // xco -> Chrs
+ return SCRIPT_CODES[17u];
+ case 0xBDC20000u: // cop -> Copt
+ return SCRIPT_CODES[18u];
+ case 0xE0440000u: // ecy -> Cprt
+ case 0x8A260000u: // grc -> Cprt
+ return SCRIPT_CODES[19u];
+ case 0x61620000u: // ab -> Cyrl
+ case 0xE0600000u: // ady -> Cyrl
+ case 0xDCC00000u: // agx -> Cyrl
+ case 0xD5400000u: // akv -> Cyrl
+ case 0xC5600000u: // alr -> Cyrl
+ case 0xCD600000u: // alt -> Cyrl
+ case 0xA1A00000u: // ani -> Cyrl
+ case 0x8A000000u: // aqc -> Cyrl
+ case 0xD6600000u: // atv -> Cyrl
+ case 0x61760000u: // av -> Cyrl
+ case 0x617A5255u: // az-RU -> Cyrl
+ case 0x62610000u: // ba -> Cyrl
+ case 0x62650000u: // be -> Cyrl
+ case 0x62670000u: // bg -> Cyrl
+ case 0x9CE10000u: // bhh -> Cyrl
+ case 0x9DE10000u: // bph -> Cyrl
+ case 0x82810000u: // bua -> Cyrl
+ case 0xB2E10000u: // bxm -> Cyrl
+ case 0x63650000u: // ce -> Cyrl
+ case 0xB0E20000u: // chm -> Cyrl
+ case 0xA1220000u: // cji -> Cyrl
+ case 0xCD420000u: // ckt -> Cyrl
+ case 0xD9620000u: // clw -> Cyrl
+ case 0x9E220000u: // crh -> Cyrl
+ case 0x63750000u: // cu -> Cyrl
+ case 0x63760000u: // cv -> Cyrl
+ case 0xC4030000u: // dar -> Cyrl
+ case 0xB8630000u: // ddo -> Cyrl
+ case 0x99630000u: // dlg -> Cyrl
+ case 0x99A30000u: // dng -> Cyrl
+ case 0x95A40000u: // enf -> Cyrl
+ case 0x9DA40000u: // enh -> Cyrl
+ case 0x92A40000u: // eve -> Cyrl
+ case 0xB6A40000u: // evn -> Cyrl
+ case 0xB8660000u: // gdo -> Cyrl
+ case 0xB5060000u: // gin -> Cyrl
+ case 0x8D660000u: // gld -> Cyrl
+ case 0xE6870000u: // huz -> Cyrl
+ case 0x9DA80000u: // inh -> Cyrl
+ case 0xAE680000u: // itl -> Cyrl
+ case 0xCC490000u: // jct -> Cyrl
+ case 0xCC690000u: // jdt -> Cyrl
+ case 0x800A0000u: // kaa -> Cyrl
+ case 0xBC0A0000u: // kap -> Cyrl
+ case 0x8C2A0000u: // kbd -> Cyrl
+ case 0x804A0000u: // kca -> Cyrl
+ case 0xCC8A0000u: // ket -> Cyrl
+ case 0xD4EA0000u: // khv -> Cyrl
+ case 0xB10A0000u: // kim -> Cyrl
+ case 0x9D2A0000u: // kjh -> Cyrl
+ case 0x6B6B0000u: // kk -> Cyrl
+ case 0xA1CA0000u: // koi -> Cyrl
+ case 0xCDEA0000u: // kpt -> Cyrl
+ case 0xE1EA0000u: // kpy -> Cyrl
+ case 0x8A2A0000u: // krc -> Cyrl
+ case 0xAA2A0000u: // krk -> Cyrl
+ case 0xB28A0000u: // kum -> Cyrl
+ case 0x6B760000u: // kv -> Cyrl
+ case 0x82AA0000u: // kva -> Cyrl
+ case 0x6B790000u: // ky -> Cyrl
+ case 0x902B0000u: // lbe -> Cyrl
+ case 0xE48B0000u: // lez -> Cyrl
+ case 0x946C0000u: // mdf -> Cyrl
+ case 0x6D6B0000u: // mk -> Cyrl
+ case 0x6D6E0000u: // mn -> Cyrl
+ case 0xC9AC0000u: // mns -> Cyrl
+ case 0xA62C0000u: // mrj -> Cyrl
+ case 0xB26C0000u: // mtm -> Cyrl
+ case 0x8E8C0000u: // mud -> Cyrl
+ case 0xD70C0000u: // myv -> Cyrl
+ case 0x946D0000u: // ndf -> Cyrl
+ case 0x988D0000u: // neg -> Cyrl
+ case 0xB90D0000u: // nio -> Cyrl
+ case 0xD50D0000u: // niv -> Cyrl
+ case 0x99CD0000u: // nog -> Cyrl
+ case 0x800E0000u: // oaa -> Cyrl
+ case 0x880E0000u: // oac -> Cyrl
+ case 0xA98E0000u: // omk -> Cyrl
+ case 0xD62E0000u: // orv -> Cyrl
+ case 0x6F730000u: // os -> Cyrl
+ case 0xC00F0000u: // paq -> Cyrl
+ case 0xAA510000u: // rsk -> Cyrl
+ case 0x72750000u: // ru -> Cyrl
+ case 0x92910000u: // rue -> Cyrl
+ case 0xCE910000u: // rut -> Cyrl
+ case 0x9C120000u: // sah -> Cyrl
+ case 0xAC920000u: // sel -> Cyrl
+ case 0x9CD20000u: // sgh -> Cyrl
+ case 0x81120000u: // sia -> Cyrl
+ case 0x8D320000u: // sjd -> Cyrl
+ case 0xCD320000u: // sjt -> Cyrl
+ case 0x73720000u: // sr -> Cyrl
+ case 0xE2720000u: // sty -> Cyrl
+ case 0x84130000u: // tab -> Cyrl
+ case 0x74670000u: // tg -> Cyrl
+ case 0xB5130000u: // tin -> Cyrl
+ case 0x74740000u: // tt -> Cyrl
+ case 0xD7130000u: // tyv -> Cyrl
+ case 0x90740000u: // ude -> Cyrl
+ case 0xA0740000u: // udi -> Cyrl
+ case 0xB0740000u: // udm -> Cyrl
+ case 0x75674B5Au: // ug-KZ -> Cyrl
+ case 0x75674D4Eu: // ug-MN -> Cyrl
+ case 0x9CD40000u: // ugh -> Cyrl
+ case 0x756B0000u: // uk -> Cyrl
+ case 0x89740000u: // ulc -> Cyrl
+ case 0x757A434Eu: // uz-CN -> Cyrl
+ case 0xAC170000u: // xal -> Cyrl
+ case 0xC8170000u: // xas -> Cyrl
+ case 0xC0770000u: // xdq -> Cyrl
+ case 0xB1F70000u: // xpm -> Cyrl
+ case 0xB2370000u: // xrm -> Cyrl
+ case 0xB6370000u: // xrn -> Cyrl
+ case 0xBAD70000u: // xwo -> Cyrl
+ case 0xA0180000u: // yai -> Cyrl
+ case 0x99580000u: // ykg -> Cyrl
+ case 0x9D580000u: // ykh -> Cyrl
+ case 0xA9B80000u: // ynk -> Cyrl
+ case 0xAA380000u: // yrk -> Cyrl
+ case 0xC6580000u: // ysr -> Cyrl
+ case 0x9A980000u: // yug -> Cyrl
+ case 0xDE980000u: // yux -> Cyrl
+ case 0xB9590000u: // zko -> Cyrl
+ case 0xE5590000u: // zkz -> Cyrl
+ return SCRIPT_CODES[20u];
+ case 0xA0C00000u: // agi -> Deva
+ case 0xC4E00000u: // ahr -> Deva
+ case 0xBDA00000u: // anp -> Deva
+ case 0xC1A00000u: // anq -> Deva
+ case 0xC5A00000u: // anr -> Deva
+ case 0x9DE00000u: // aph -> Deva
+ case 0xC6400000u: // asr -> Deva
+ case 0x82C00000u: // awa -> Deva
+ case 0xBC010000u: // bap -> Deva
+ case 0x90810000u: // bee -> Deva
+ case 0x84A10000u: // bfb -> Deva
+ case 0xE0A10000u: // bfy -> Deva
+ case 0xE4A10000u: // bfz -> Deva
+ case 0x88C10000u: // bgc -> Deva
+ case 0x8CC10000u: // bgd -> Deva
+ case 0xC0C10000u: // bgq -> Deva
+ case 0xD8C10000u: // bgw -> Deva
+ case 0x80E10000u: // bha -> Deva
+ case 0x84E10000u: // bhb -> Deva
+ case 0x8CE10000u: // bhd -> Deva
+ case 0xA0E10000u: // bhi -> Deva
+ case 0xA4E10000u: // bhj -> Deva
+ case 0xB8E10000u: // bho -> Deva
+ case 0xCCE10000u: // bht -> Deva
+ case 0xD0E10000u: // bhu -> Deva
+ case 0xE1010000u: // biy -> Deva
+ case 0xA5210000u: // bjj -> Deva
+ case 0xA5810000u: // bmj -> Deva
+ case 0xC9A10000u: // bns -> Deva
+ case 0xDDE10000u: // bpx -> Deva
+ case 0x82210000u: // bra -> Deva
+ case 0x8E210000u: // brd -> Deva
+ case 0xDE210000u: // brx -> Deva
+ case 0xD6610000u: // btv -> Deva
+ case 0x9F010000u: // byh -> Deva
+ case 0xDB010000u: // byw -> Deva
+ case 0x9C620000u: // cdh -> Deva
+ case 0xA4620000u: // cdj -> Deva
+ case 0xB0620000u: // cdm -> Deva
+ case 0xDCE20000u: // chx -> Deva
+ case 0x9D020000u: // cih -> Deva
+ case 0xB6620000u: // ctn -> Deva
+ case 0xC0030000u: // daq -> Deva
+ case 0xA0E30000u: // dhi -> Deva
+ case 0xB8E30000u: // dho -> Deva
+ case 0xD8E30000u: // dhw -> Deva
+ case 0xA1C30000u: // doi -> Deva
+ case 0xC2230000u: // drq -> Deva
+ case 0xE2230000u: // dry -> Deva
+ case 0xE2630000u: // dty -> Deva
+ case 0x9E830000u: // duh -> Deva
+ case 0xCA830000u: // dus -> Deva
+ case 0xE6C30000u: // dwz -> Deva
+ case 0x99840000u: // emg -> Deva
+ case 0xD1840000u: // emu -> Deva
+ case 0xD1850000u: // fmu -> Deva
+ case 0xA8260000u: // gbk -> Deva
+ case 0xB0260000u: // gbm -> Deva
+ case 0xDC660000u: // gdx -> Deva
+ case 0x90E60000u: // ghe -> Deva
+ case 0xA5C60000u: // goj -> Deva
+ case 0xA9C60000u: // gok -> Deva
+ case 0xB5C60000u: // gon -> Deva
+ case 0x82260000u: // gra -> Deva
+ case 0xC6A60000u: // gvr -> Deva
+ case 0xBB060000u: // gyo -> Deva
+ case 0x68690000u: // hi -> Deva
+ case 0x95070000u: // hif -> Deva
+ case 0x85670000u: // hlb -> Deva
+ case 0x91A70000u: // hne -> Deva
+ case 0x89C70000u: // hoc -> Deva
+ case 0xA5C70000u: // hoj -> Deva
+ case 0xE1C70000u: // hoy -> Deva
+ case 0xCE870000u: // hut -> Deva
+ case 0x90890000u: // jee -> Deva
+ case 0xAD890000u: // jml -> Deva
+ case 0xADA90000u: // jnl -> Deva
+ case 0xC9A90000u: // jns -> Deva
+ case 0xAE890000u: // jul -> Deva
+ case 0xDC8A0000u: // kex -> Deva
+ case 0x84AA0000u: // kfb -> Deva
+ case 0xA8AA0000u: // kfk -> Deva
+ case 0xBCAA0000u: // kfp -> Deva
+ case 0xC0AA0000u: // kfq -> Deva
+ case 0xC4AA0000u: // kfr -> Deva
+ case 0xC8AA0000u: // kfs -> Deva
+ case 0xD0AA0000u: // kfu -> Deva
+ case 0xDCAA0000u: // kfx -> Deva
+ case 0xE0AA0000u: // kfy -> Deva
+ case 0xA4CA0000u: // kgj -> Deva
+ case 0xE0CA0000u: // kgy -> Deva
+ case 0xB4EA0000u: // khn -> Deva
+ case 0x950A0000u: // kif -> Deva
+ case 0xBD0A0000u: // kip -> Deva
+ case 0xAD2A0000u: // kjl -> Deva
+ case 0xB92A0000u: // kjo -> Deva
+ case 0xCD4A0000u: // kkt -> Deva
+ case 0x916A0000u: // kle -> Deva
+ case 0xC56A0000u: // klr -> Deva
+ case 0xA58A0000u: // kmj -> Deva
+ case 0xB5AA0000u: // knn -> Deva
+ case 0xA9CA0000u: // kok -> Deva
+ case 0x822A0000u: // kra -> Deva
+ case 0xD22A0000u: // kru -> Deva
+ case 0xE64A0000u: // ksz -> Deva
+ case 0x926A0000u: // kte -> Deva
+ case 0xD70A0000u: // kyv -> Deva
+ case 0xDB0A0000u: // kyw -> Deva
+ case 0x900B0000u: // lae -> Deva
+ case 0x942B0000u: // lbf -> Deva
+ case 0xB02B0000u: // lbm -> Deva
+ case 0xC42B0000u: // lbr -> Deva
+ case 0xB0EB0000u: // lhm -> Deva
+ case 0x950B0000u: // lif -> Deva
+ case 0x9D8B0000u: // lmh -> Deva
+ case 0xE1CB0000u: // loy -> Deva
+ case 0xD28B0000u: // luu -> Deva
+ case 0x980C0000u: // mag -> Deva
+ case 0xA00C0000u: // mai -> Deva
+ case 0xBCCC0000u: // mgp -> Deva
+ case 0xAD2C0000u: // mjl -> Deva
+ case 0xCD2C0000u: // mjt -> Deva
+ case 0xE52C0000u: // mjz -> Deva
+ case 0x854C0000u: // mkb -> Deva
+ case 0x914C0000u: // mke -> Deva
+ case 0x6D720000u: // mr -> Deva
+ case 0x8E2C0000u: // mrd -> Deva
+ case 0xC62C0000u: // mrr -> Deva
+ case 0xC66C0000u: // mtr -> Deva
+ case 0xCE8C0000u: // mut -> Deva
+ case 0xC6CC0000u: // mwr -> Deva
+ case 0xB80D0000u: // nao -> Deva
+ case 0x8C4D0000u: // ncd -> Deva
+ case 0x6E650000u: // ne -> Deva
+ case 0xD88D0000u: // new -> Deva
+ case 0xDD6D0000u: // nlx -> Deva
+ case 0xB18D0000u: // nmm -> Deva
+ case 0x91CD0000u: // noe -> Deva
+ case 0xA1CD0000u: // noi -> Deva
+ case 0xDECD0000u: // nwx -> Deva
+ case 0x816E0000u: // ola -> Deva
+ case 0xB5CE0000u: // oon -> Deva
+ case 0x9C4F0000u: // pch -> Deva
+ case 0xA04F0000u: // pci -> Deva
+ case 0x98CF0000u: // pgg -> Deva
+ case 0x8CEF0000u: // phd -> Deva
+ case 0xD8EF0000u: // phw -> Deva
+ case 0xB28F0000u: // pum -> Deva
+ case 0xC6CF0000u: // pwr -> Deva
+ case 0x80110000u: // raa -> Deva
+ case 0x84110000u: // rab -> Deva
+ case 0x94110000u: // raf -> Deva
+ case 0xA4110000u: // raj -> Deva
+ case 0xD4110000u: // rav -> Deva
+ case 0xA1310000u: // rji -> Deva
+ case 0xC9310000u: // rjs -> Deva
+ case 0xDA710000u: // rtw -> Deva
+ case 0xC6D10000u: // rwr -> Deva
+ case 0x73610000u: // sa -> Deva
+ case 0xA8520000u: // sck -> Deva
+ case 0xBC520000u: // scp -> Deva
+ case 0x7364494Eu: // sd-IN -> Deva
+ case 0xA4D20000u: // sgj -> Deva
+ case 0xBD320000u: // sjp -> Deva
+ case 0xA5520000u: // skj -> Deva
+ case 0xA1D20000u: // soi -> Deva
+ case 0xDE320000u: // srx -> Deva
+ case 0xD6D20000u: // swv -> Deva
+ case 0xDB120000u: // syw -> Deva
+ case 0xA4130000u: // taj -> Deva
+ case 0x84730000u: // tdb -> Deva
+ case 0x98730000u: // tdg -> Deva
+ case 0x9C730000u: // tdh -> Deva
+ case 0x90D30000u: // tge -> Deva
+ case 0x90F30000u: // the -> Deva
+ case 0x94F30000u: // thf -> Deva
+ case 0xACF30000u: // thl -> Deva
+ case 0xC0F30000u: // thq -> Deva
+ case 0xC4F30000u: // thr -> Deva
+ case 0xC8F30000u: // ths -> Deva
+ case 0xA5130000u: // tij -> Deva
+ case 0x85530000u: // tkb -> Deva
+ case 0xCD530000u: // tkt -> Deva
+ case 0xE6730000u: // ttz -> Deva
+ case 0xB2D30000u: // twm -> Deva
+ case 0xC5B44E50u: // unr-NP -> Deva
+ case 0x9C150000u: // vah -> Deva
+ case 0xC8150000u: // vas -> Deva
+ case 0xD4150000u: // vav -> Deva
+ case 0xE0150000u: // vay -> Deva
+ case 0xA9350000u: // vjk -> Deva
+ case 0xC4360000u: // wbr -> Deva
+ case 0x91960000u: // wme -> Deva
+ case 0xB2760000u: // wtm -> Deva
+ case 0xC5B70000u: // xnr -> Deva
+ case 0xC6570000u: // xsr -> Deva
+ case 0x9C380000u: // ybh -> Deva
+ case 0xA0380000u: // ybi -> Deva
+ return SCRIPT_CODES[21u];
+ case 0xE0C40000u: // egy -> Egyp
+ return SCRIPT_CODES[22u];
+ case 0xE1770000u: // xly -> Elym
+ return SCRIPT_CODES[23u];
+ case 0xA4C00000u: // agj -> Ethi
+ case 0x98E00000u: // ahg -> Ethi
+ case 0xD9600000u: // alw -> Ethi
+ case 0x616D0000u: // am -> Ethi
+ case 0xD1A00000u: // anu -> Ethi
+ case 0xB6C00000u: // awn -> Ethi
+ case 0xC0410000u: // bcq -> Ethi
+ case 0xCE410000u: // bst -> Ethi
+ case 0xB7010000u: // byn -> Ethi
+ case 0xDDC30000u: // dox -> Ethi
+ case 0xCA230000u: // drs -> Ethi
+ case 0xE4860000u: // gez -> Ethi
+ case 0xD5860000u: // gmv -> Ethi
+ case 0x95C60000u: // gof -> Ethi
+ case 0xD2260000u: // gru -> Ethi
+ case 0xC4070000u: // har -> Ethi
+ case 0xE0670000u: // hdy -> Ethi
+ case 0xC5C80000u: // ior -> Ethi
+ case 0xE20A0000u: // kqy -> Ethi
+ case 0x866A0000u: // ktb -> Ethi
+ case 0xDC6C0000u: // mdx -> Ethi
+ case 0xE06C0000u: // mdy -> Ethi
+ case 0xE68C0000u: // muz -> Ethi
+ case 0xE6AC0000u: // mvz -> Ethi
+ case 0xB30C0000u: // mym -> Ethi
+ case 0xD8D20000u: // sgw -> Ethi
+ case 0xD6720000u: // stv -> Ethi
+ case 0x74690000u: // ti -> Ethi
+ case 0x99130000u: // tig -> Ethi
+ case 0xAC160000u: // wal -> Ethi
+ case 0x91760000u: // wle -> Ethi
+ case 0xB4170000u: // xan -> Ethi
+ case 0x82D90000u: // zwa -> Ethi
+ return SCRIPT_CODES[24u];
+ case 0xAC210000u: // bbl -> Geor
+ case 0x90C90000u: // jge -> Geor
+ case 0x6B610000u: // ka -> Geor
+ case 0xD40E0000u: // oav -> Geor
+ case 0x82B20000u: // sva -> Geor
+ case 0x95970000u: // xmf -> Geor
+ return SCRIPT_CODES[25u];
+ case 0x9A560000u: // wsg -> Gong
+ return SCRIPT_CODES[26u];
+ case 0x9A440000u: // esg -> Gonm
+ return SCRIPT_CODES[27u];
+ case 0xCDC60000u: // got -> Goth
+ return SCRIPT_CODES[28u];
+ case 0xE26E0000u: // oty -> Gran
+ return SCRIPT_CODES[29u];
+ case 0xCC000000u: // aat -> Grek
+ case 0xDCC10000u: // bgx -> Grek
+ case 0x99E20000u: // cpg -> Grek
+ case 0xC4440000u: // ecr -> Grek
+ case 0x656C0000u: // el -> Grek
+ case 0xCDAF0000u: // pnt -> Grek
+ case 0xDC520000u: // scx -> Grek
+ case 0x8E530000u: // tsd -> Grek
+ case 0xB2940000u: // uum -> Grek
+ case 0x99F70000u: // xpg -> Grek
+ case 0xA4980000u: // yej -> Grek
+ return SCRIPT_CODES[30u];
+ case 0xA0620000u: // cdi -> Gujr
+ case 0xB4E30000u: // dhn -> Gujr
+ case 0x86830000u: // dub -> Gujr
+ case 0xC8060000u: // gas -> Gujr
+ case 0xAC260000u: // gbl -> Gujr
+ case 0x67750000u: // gu -> Gujr
+ return SCRIPT_CODES[31u];
+ case 0x70610000u: // pa -> Guru
+ return SCRIPT_CODES[32u];
+ case 0x91290000u: // jje -> Hang
+ case 0xB14E0000u: // okm -> Hang
+ return SCRIPT_CODES[33u];
+ case 0xD9C70000u: // how -> Hani
+ case 0xB94E0000u: // oko -> Hani
+ case 0xA2D20000u: // swi -> Hani
+ case 0x9C590000u: // zch -> Hani
+ case 0x9C990000u: // zeh -> Hani
+ case 0x84D90000u: // zgb -> Hani
+ case 0xB0D90000u: // zgm -> Hani
+ case 0xB4D90000u: // zgn -> Hani
+ case 0x8CF90000u: // zhd -> Hani
+ case 0xA5790000u: // zlj -> Hani
+ case 0xB5790000u: // zln -> Hani
+ case 0xC1790000u: // zlq -> Hani
+ case 0x92190000u: // zqe -> Hani
+ case 0x9B190000u: // zyg -> Hani
+ case 0xB7190000u: // zyn -> Hani
+ case 0xA7390000u: // zzj -> Hani
+ return SCRIPT_CODES[34u];
+ case 0xB8620000u: // cdo -> Hans
+ case 0xE1220000u: // cjy -> Hans
+ case 0xBDA20000u: // cnp -> Hans
+ case 0xBE420000u: // csp -> Hans
+ case 0x9F220000u: // czh -> Hans
+ case 0xB4060000u: // gan -> Hans
+ case 0xA8070000u: // hak -> Hans
+ case 0xB6470000u: // hsn -> Hans
+ case 0x9F2B0000u: // lzh -> Hans
+ case 0xB40D0000u: // nan -> Hans
+ case 0xD2960000u: // wuu -> Hans
+ case 0x9298434Eu: // yue-CN -> Hans
+ case 0x7A680000u: // zh -> Hans
+ return SCRIPT_CODES[35u];
+ case 0x8A6B0000u: // ltc -> Hant
+ case 0x92980000u: // yue -> Hant
+ case 0x7A684155u: // zh-AU -> Hant
+ case 0x7A68424Eu: // zh-BN -> Hant
+ case 0x7A684742u: // zh-GB -> Hant
+ case 0x7A684746u: // zh-GF -> Hant
+ case 0x7A68484Bu: // zh-HK -> Hant
+ case 0x7A684944u: // zh-ID -> Hant
+ case 0x7A684D4Fu: // zh-MO -> Hant
+ case 0x7A685041u: // zh-PA -> Hant
+ case 0x7A685046u: // zh-PF -> Hant
+ case 0x7A685048u: // zh-PH -> Hant
+ case 0x7A685352u: // zh-SR -> Hant
+ case 0x7A685448u: // zh-TH -> Hant
+ case 0x7A685457u: // zh-TW -> Hant
+ case 0x7A685553u: // zh-US -> Hant
+ case 0x7A68564Eu: // zh-VN -> Hant
+ return SCRIPT_CODES[36u];
+ case 0xA5000000u: // aij -> Hebr
+ case 0xAB220000u: // czk -> Hebr
+ case 0xB8270000u: // hbo -> Hebr
+ case 0x68650000u: // he -> Hebr
+ case 0xE2870000u: // huy -> Hebr
+ case 0xAA680000u: // itk -> Hebr
+ case 0x69770000u: // iw -> Hebr
+ case 0x90290000u: // jbe -> Hebr
+ case 0x6A690000u: // ji -> Hebr
+ case 0x81E90000u: // jpa -> Hebr
+ case 0xC5E90000u: // jpr -> Hebr
+ case 0x86290000u: // jrb -> Hebr
+ case 0x93090000u: // jye -> Hebr
+ case 0x8C0B0000u: // lad -> Hebr
+ case 0x8E4B0000u: // lsd -> Hebr
+ case 0x9A330000u: // trg -> Hebr
+ case 0x8CF80000u: // yhd -> Hebr
+ case 0x79690000u: // yi -> Hebr
+ case 0x9D180000u: // yih -> Hebr
+ case 0x8E980000u: // yud -> Hebr
+ case 0xBE390000u: // zrp -> Hebr
+ return SCRIPT_CODES[37u];
+ case 0xD1670000u: // hlu -> Hluw
+ return SCRIPT_CODES[38u];
+ case 0xA5A70000u: // hnj -> Hmnp
+ case 0xDACC0000u: // mww -> Hmnp
+ return SCRIPT_CODES[39u];
+ case 0xCE640000u: // ett -> Ital
+ case 0x8A4E0000u: // osc -> Ital
+ case 0xB4CF0000u: // pgn -> Ital
+ case 0x92B70000u: // xve -> Ital
+ return SCRIPT_CODES[40u];
+ case 0xA24E0000u: // osi -> Java
+ case 0xC8930000u: // tes -> Java
+ return SCRIPT_CODES[41u];
+ case 0xC9800000u: // ams -> Jpan
+ case 0x6A610000u: // ja -> Jpan
+ case 0xA1D80000u: // yoi -> Jpan
+ return SCRIPT_CODES[42u];
+ case 0xE1440000u: // eky -> Kali
+ case 0xE2AA0000u: // kvy -> Kali
+ case 0xD30A0000u: // kyu -> Kali
+ return SCRIPT_CODES[43u];
+ case 0xB5000000u: // ain -> Kana
+ case 0xD3110000u: // ryu -> Kana
+ return SCRIPT_CODES[44u];
+ case 0xD80A0000u: // kaw -> Kawi
+ return SCRIPT_CODES[45u];
+ case 0x8CCF0000u: // pgd -> Khar
+ case 0x822F0000u: // pra -> Khar
+ return SCRIPT_CODES[46u];
+ case 0x86210000u: // brb -> Khmr
+ case 0x6B6D0000u: // km -> Khmr
+ case 0xC62A0000u: // krr -> Khmr
+ case 0xD62A0000u: // krv -> Khmr
+ case 0xE54E0000u: // okz -> Khmr
+ case 0x844F0000u: // pcb -> Khmr
+ case 0x81510000u: // rka -> Khmr
+ case 0xD1920000u: // smu -> Khmr
+ case 0xD1F30000u: // tpu -> Khmr
+ case 0xB0F70000u: // xhm -> Khmr
+ return SCRIPT_CODES[47u];
+ case 0xCD590000u: // zkt -> Kits
+ return SCRIPT_CODES[48u];
+ case 0xDA210000u: // brw -> Knda
+ case 0x80AA0000u: // kfa -> Knda
+ case 0x8CAA0000u: // kfd -> Knda
+ case 0x98AA0000u: // kfg -> Knda
+ case 0x6B6E0000u: // kn -> Knda
+ case 0xE0530000u: // tcy -> Knda
+ case 0x8D950000u: // vmd -> Knda
+ return SCRIPT_CODES[49u];
+ case 0x6B6F0000u: // ko -> Kore
+ return SCRIPT_CODES[50u];
+ case 0xD2820000u: // cuu -> Lana
+ case 0x9D4A0000u: // kkh -> Lana
+ case 0x8DCD0000u: // nod -> Lana
+ return SCRIPT_CODES[51u];
+ case 0xA9600000u: // alk -> Laoo
+ case 0xD6210000u: // brv -> Laoo
+ case 0x992A0000u: // kjg -> Laoo
+ case 0x968A0000u: // kuf -> Laoo
+ case 0xB82B0000u: // lbo -> Laoo
+ case 0x6C6F0000u: // lo -> Laoo
+ case 0xC04D0000u: // ncq -> Laoo
+ case 0xCCCD0000u: // ngt -> Laoo
+ case 0xB8EF0000u: // pho -> Laoo
+ case 0xCC520000u: // sct -> Laoo
+ case 0xC2120000u: // sqq -> Laoo
+ case 0xCA520000u: // sss -> Laoo
+ case 0x9E730000u: // tth -> Laoo
+ case 0xBA730000u: // tto -> Laoo
+ return SCRIPT_CODES[52u];
+ case 0xAD860000u: // gml -> Latf
+ return SCRIPT_CODES[53u];
+ case 0x80CC0000u: // mga -> Latg
+ return SCRIPT_CODES[54u];
+ case 0x61610000u: // aa -> Latn
+ case 0x80000000u: // aaa -> Latn
+ case 0x84000000u: // aab -> Latn
+ case 0x88000000u: // aac -> Latn
+ case 0x8C000000u: // aad -> Latn
+ case 0x90000000u: // aae -> Latn
+ case 0x98000000u: // aag -> Latn
+ case 0x9C000000u: // aah -> Latn
+ case 0xA0000000u: // aai -> Latn
+ case 0xA8000000u: // aak -> Latn
+ case 0xAC000000u: // aal -> Latn
+ case 0xB4000000u: // aan -> Latn
+ case 0xBC000000u: // aap -> Latn
+ case 0xC0000000u: // aaq -> Latn
+ case 0xC8000000u: // aas -> Latn
+ case 0xD0000000u: // aau -> Latn
+ case 0xD8000000u: // aaw -> Latn
+ case 0xDC000000u: // aax -> Latn
+ case 0xE4000000u: // aaz -> Latn
+ case 0x80200000u: // aba -> Latn
+ case 0x84200000u: // abb -> Latn
+ case 0x88200000u: // abc -> Latn
+ case 0x8C200000u: // abd -> Latn
+ case 0x90200000u: // abe -> Latn
+ case 0x94200000u: // abf -> Latn
+ case 0x98200000u: // abg -> Latn
+ case 0xA0200000u: // abi -> Latn
+ case 0xB0200000u: // abm -> Latn
+ case 0xB4200000u: // abn -> Latn
+ case 0xB8200000u: // abo -> Latn
+ case 0xBC200000u: // abp -> Latn
+ case 0xC4200000u: // abr -> Latn
+ case 0xC8200000u: // abs -> Latn
+ case 0xCC200000u: // abt -> Latn
+ case 0xD0200000u: // abu -> Latn
+ case 0xD8200000u: // abw -> Latn
+ case 0xDC200000u: // abx -> Latn
+ case 0xE0200000u: // aby -> Latn
+ case 0xE4200000u: // abz -> Latn
+ case 0x80400000u: // aca -> Latn
+ case 0x84400000u: // acb -> Latn
+ case 0x8C400000u: // acd -> Latn
+ case 0x90400000u: // ace -> Latn
+ case 0x94400000u: // acf -> Latn
+ case 0x9C400000u: // ach -> Latn
+ case 0xB4400000u: // acn -> Latn
+ case 0xBC400000u: // acp -> Latn
+ case 0xC4400000u: // acr -> Latn
+ case 0xC8400000u: // acs -> Latn
+ case 0xCC400000u: // act -> Latn
+ case 0xD0400000u: // acu -> Latn
+ case 0xD4400000u: // acv -> Latn
+ case 0xE0400000u: // acy -> Latn
+ case 0xE4400000u: // acz -> Latn
+ case 0x80600000u: // ada -> Latn
+ case 0x84600000u: // adb -> Latn
+ case 0x8C600000u: // add -> Latn
+ case 0x90600000u: // ade -> Latn
+ case 0x98600000u: // adg -> Latn
+ case 0x9C600000u: // adh -> Latn
+ case 0xA0600000u: // adi -> Latn
+ case 0xA4600000u: // adj -> Latn
+ case 0xAC600000u: // adl -> Latn
+ case 0xB4600000u: // adn -> Latn
+ case 0xB8600000u: // ado -> Latn
+ case 0xC0600000u: // adq -> Latn
+ case 0xC4600000u: // adr -> Latn
+ case 0xCC600000u: // adt -> Latn
+ case 0xD0600000u: // adu -> Latn
+ case 0xD8600000u: // adw -> Latn
+ case 0xE4600000u: // adz -> Latn
+ case 0x80800000u: // aea -> Latn
+ case 0xA8800000u: // aek -> Latn
+ case 0xAC800000u: // ael -> Latn
+ case 0xB0800000u: // aem -> Latn
+ case 0xC4800000u: // aer -> Latn
+ case 0xD0800000u: // aeu -> Latn
+ case 0xD8800000u: // aew -> Latn
+ case 0xE0800000u: // aey -> Latn
+ case 0xE4800000u: // aez -> Latn
+ case 0x61660000u: // af -> Latn
+ case 0x8CA00000u: // afd -> Latn
+ case 0x90A00000u: // afe -> Latn
+ case 0x9CA00000u: // afh -> Latn
+ case 0xA0A00000u: // afi -> Latn
+ case 0xA8A00000u: // afk -> Latn
+ case 0xB4A00000u: // afn -> Latn
+ case 0xB8A00000u: // afo -> Latn
+ case 0xBCA00000u: // afp -> Latn
+ case 0xC8A00000u: // afs -> Latn
+ case 0xD0A00000u: // afu -> Latn
+ case 0xE4A00000u: // afz -> Latn
+ case 0x80C00000u: // aga -> Latn
+ case 0x84C00000u: // agb -> Latn
+ case 0x88C00000u: // agc -> Latn
+ case 0x8CC00000u: // agd -> Latn
+ case 0x90C00000u: // age -> Latn
+ case 0x94C00000u: // agf -> Latn
+ case 0x98C00000u: // agg -> Latn
+ case 0x9CC00000u: // agh -> Latn
+ case 0xA8C00000u: // agk -> Latn
+ case 0xACC00000u: // agl -> Latn
+ case 0xB0C00000u: // agm -> Latn
+ case 0xB4C00000u: // agn -> Latn
+ case 0xB8C00000u: // ago -> Latn
+ case 0xC0C00000u: // agq -> Latn
+ case 0xC4C00000u: // agr -> Latn
+ case 0xC8C00000u: // ags -> Latn
+ case 0xCCC00000u: // agt -> Latn
+ case 0xD0C00000u: // agu -> Latn
+ case 0xD4C00000u: // agv -> Latn
+ case 0xD8C00000u: // agw -> Latn
+ case 0xE0C00000u: // agy -> Latn
+ case 0xE4C00000u: // agz -> Latn
+ case 0x80E00000u: // aha -> Latn
+ case 0x84E00000u: // ahb -> Latn
+ case 0x9CE00000u: // ahh -> Latn
+ case 0xA0E00000u: // ahi -> Latn
+ case 0xA8E00000u: // ahk -> Latn
+ case 0xACE00000u: // ahl -> Latn
+ case 0xB0E00000u: // ahm -> Latn
+ case 0xB4E00000u: // ahn -> Latn
+ case 0xBCE00000u: // ahp -> Latn
+ case 0xC8E00000u: // ahs -> Latn
+ case 0xCCE00000u: // aht -> Latn
+ case 0x81000000u: // aia -> Latn
+ case 0x89000000u: // aic -> Latn
+ case 0x8D000000u: // aid -> Latn
+ case 0x91000000u: // aie -> Latn
+ case 0x95000000u: // aif -> Latn
+ case 0x99000000u: // aig -> Latn
+ case 0xA9000000u: // aik -> Latn
+ case 0xAD000000u: // ail -> Latn
+ case 0xB1000000u: // aim -> Latn
+ case 0xBD000000u: // aip -> Latn
+ case 0xC5000000u: // air -> Latn
+ case 0xCD000000u: // ait -> Latn
+ case 0xD9000000u: // aiw -> Latn
+ case 0xDD000000u: // aix -> Latn
+ case 0xE1000000u: // aiy -> Latn
+ case 0x81200000u: // aja -> Latn
+ case 0x99200000u: // ajg -> Latn
+ case 0xA1200000u: // aji -> Latn
+ case 0xB5200000u: // ajn -> Latn
+ case 0xD9200000u: // ajw -> Latn
+ case 0xE5200000u: // ajz -> Latn
+ case 0x616B0000u: // ak -> Latn
+ case 0x85400000u: // akb -> Latn
+ case 0x89400000u: // akc -> Latn
+ case 0x8D400000u: // akd -> Latn
+ case 0x91400000u: // ake -> Latn
+ case 0x95400000u: // akf -> Latn
+ case 0x99400000u: // akg -> Latn
+ case 0x9D400000u: // akh -> Latn
+ case 0xA1400000u: // aki -> Latn
+ case 0xAD400000u: // akl -> Latn
+ case 0xB9400000u: // ako -> Latn
+ case 0xBD400000u: // akp -> Latn
+ case 0xC1400000u: // akq -> Latn
+ case 0xC5400000u: // akr -> Latn
+ case 0xC9400000u: // aks -> Latn
+ case 0xCD400000u: // akt -> Latn
+ case 0xD1400000u: // aku -> Latn
+ case 0xD9400000u: // akw -> Latn
+ case 0xE5400000u: // akz -> Latn
+ case 0x81600000u: // ala -> Latn
+ case 0x89600000u: // alc -> Latn
+ case 0x8D600000u: // ald -> Latn
+ case 0x91600000u: // ale -> Latn
+ case 0x95600000u: // alf -> Latn
+ case 0x9D600000u: // alh -> Latn
+ case 0xA1600000u: // ali -> Latn
+ case 0xA5600000u: // alj -> Latn
+ case 0xB1600000u: // alm -> Latn
+ case 0xB5600000u: // aln -> Latn
+ case 0xB9600000u: // alo -> Latn
+ case 0xBD600000u: // alp -> Latn
+ case 0xC1600000u: // alq -> Latn
+ case 0xD1600000u: // alu -> Latn
+ case 0xDD600000u: // alx -> Latn
+ case 0xE1600000u: // aly -> Latn
+ case 0xE5600000u: // alz -> Latn
+ case 0x81800000u: // ama -> Latn
+ case 0x85800000u: // amb -> Latn
+ case 0x89800000u: // amc -> Latn
+ case 0x91800000u: // ame -> Latn
+ case 0x95800000u: // amf -> Latn
+ case 0x99800000u: // amg -> Latn
+ case 0xA1800000u: // ami -> Latn
+ case 0xA5800000u: // amj -> Latn
+ case 0xA9800000u: // amk -> Latn
+ case 0xB1800000u: // amm -> Latn
+ case 0xB5800000u: // amn -> Latn
+ case 0xB9800000u: // amo -> Latn
+ case 0xBD800000u: // amp -> Latn
+ case 0xC1800000u: // amq -> Latn
+ case 0xC5800000u: // amr -> Latn
+ case 0xCD800000u: // amt -> Latn
+ case 0xD1800000u: // amu -> Latn
+ case 0xD5800000u: // amv -> Latn
+ case 0xDD800000u: // amx -> Latn
+ case 0xE1800000u: // amy -> Latn
+ case 0xE5800000u: // amz -> Latn
+ case 0x616E0000u: // an -> Latn
+ case 0x81A00000u: // ana -> Latn
+ case 0x85A00000u: // anb -> Latn
+ case 0x89A00000u: // anc -> Latn
+ case 0x8DA00000u: // and -> Latn
+ case 0x91A00000u: // ane -> Latn
+ case 0x95A00000u: // anf -> Latn
+ case 0x99A00000u: // ang -> Latn
+ case 0x9DA00000u: // anh -> Latn
+ case 0xA5A00000u: // anj -> Latn
+ case 0xA9A00000u: // ank -> Latn
+ case 0xADA00000u: // anl -> Latn
+ case 0xB1A00000u: // anm -> Latn
+ case 0xB5A00000u: // ann -> Latn
+ case 0xB9A00000u: // ano -> Latn
+ case 0xC9A00000u: // ans -> Latn
+ case 0xCDA00000u: // ant -> Latn
+ case 0xD5A00000u: // anv -> Latn
+ case 0xD9A00000u: // anw -> Latn
+ case 0xDDA00000u: // anx -> Latn
+ case 0xE1A00000u: // any -> Latn
+ case 0xE5A00000u: // anz -> Latn
+ case 0x81C00000u: // aoa -> Latn
+ case 0x85C00000u: // aob -> Latn
+ case 0x89C00000u: // aoc -> Latn
+ case 0x8DC00000u: // aod -> Latn
+ case 0x91C00000u: // aoe -> Latn
+ case 0x95C00000u: // aof -> Latn
+ case 0x99C00000u: // aog -> Latn
+ case 0xA1C00000u: // aoi -> Latn
+ case 0xA5C00000u: // aoj -> Latn
+ case 0xA9C00000u: // aok -> Latn
+ case 0xADC00000u: // aol -> Latn
+ case 0xB1C00000u: // aom -> Latn
+ case 0xB5C00000u: // aon -> Latn
+ case 0xC5C00000u: // aor -> Latn
+ case 0xC9C00000u: // aos -> Latn
+ case 0xDDC00000u: // aox -> Latn
+ case 0xE5C00000u: // aoz -> Latn
+ case 0x85E00000u: // apb -> Latn
+ case 0x91E00000u: // ape -> Latn
+ case 0x95E00000u: // apf -> Latn
+ case 0x99E00000u: // apg -> Latn
+ case 0xA1E00000u: // api -> Latn
+ case 0xA5E00000u: // apj -> Latn
+ case 0xA9E00000u: // apk -> Latn
+ case 0xADE00000u: // apl -> Latn
+ case 0xB1E00000u: // apm -> Latn
+ case 0xB5E00000u: // apn -> Latn
+ case 0xB9E00000u: // apo -> Latn
+ case 0xBDE00000u: // app -> Latn
+ case 0xC5E00000u: // apr -> Latn
+ case 0xC9E00000u: // aps -> Latn
+ case 0xCDE00000u: // apt -> Latn
+ case 0xD1E00000u: // apu -> Latn
+ case 0xD5E00000u: // apv -> Latn
+ case 0xD9E00000u: // apw -> Latn
+ case 0xDDE00000u: // apx -> Latn
+ case 0xE1E00000u: // apy -> Latn
+ case 0xE5E00000u: // apz -> Latn
+ case 0x8E000000u: // aqd -> Latn
+ case 0x9A000000u: // aqg -> Latn
+ case 0xAA000000u: // aqk -> Latn
+ case 0xB2000000u: // aqm -> Latn
+ case 0xB6000000u: // aqn -> Latn
+ case 0xC6000000u: // aqr -> Latn
+ case 0xCE000000u: // aqt -> Latn
+ case 0xE6000000u: // aqz -> Latn
+ case 0x8E200000u: // ard -> Latn
+ case 0x92200000u: // are -> Latn
+ case 0x9E200000u: // arh -> Latn
+ case 0xA2200000u: // ari -> Latn
+ case 0xA6200000u: // arj -> Latn
+ case 0xAA200000u: // ark -> Latn
+ case 0xAE200000u: // arl -> Latn
+ case 0xB6200000u: // arn -> Latn
+ case 0xBA200000u: // aro -> Latn
+ case 0xBE200000u: // arp -> Latn
+ case 0xC6200000u: // arr -> Latn
+ case 0xD2200000u: // aru -> Latn
+ case 0xDA200000u: // arw -> Latn
+ case 0xDE200000u: // arx -> Latn
+ case 0x82400000u: // asa -> Latn
+ case 0x86400000u: // asb -> Latn
+ case 0x8A400000u: // asc -> Latn
+ case 0x9A400000u: // asg -> Latn
+ case 0x9E400000u: // ash -> Latn
+ case 0xA2400000u: // asi -> Latn
+ case 0xA6400000u: // asj -> Latn
+ case 0xAE400000u: // asl -> Latn
+ case 0xB6400000u: // asn -> Latn
+ case 0xBA400000u: // aso -> Latn
+ case 0xCA400000u: // ass -> Latn
+ case 0xCE400000u: // ast -> Latn
+ case 0xD2400000u: // asu -> Latn
+ case 0xD6400000u: // asv -> Latn
+ case 0xDE400000u: // asx -> Latn
+ case 0xE2400000u: // asy -> Latn
+ case 0xE6400000u: // asz -> Latn
+ case 0x82600000u: // ata -> Latn
+ case 0x86600000u: // atb -> Latn
+ case 0x8A600000u: // atc -> Latn
+ case 0x8E600000u: // atd -> Latn
+ case 0x92600000u: // ate -> Latn
+ case 0x9A600000u: // atg -> Latn
+ case 0xA2600000u: // ati -> Latn
+ case 0xA6600000u: // atj -> Latn
+ case 0xAA600000u: // atk -> Latn
+ case 0xAE600000u: // atl -> Latn
+ case 0xB2600000u: // atm -> Latn
+ case 0xBA600000u: // ato -> Latn
+ case 0xBE600000u: // atp -> Latn
+ case 0xC2600000u: // atq -> Latn
+ case 0xC6600000u: // atr -> Latn
+ case 0xCA600000u: // ats -> Latn
+ case 0xCE600000u: // att -> Latn
+ case 0xD2600000u: // atu -> Latn
+ case 0xDA600000u: // atw -> Latn
+ case 0xDE600000u: // atx -> Latn
+ case 0xE2600000u: // aty -> Latn
+ case 0xE6600000u: // atz -> Latn
+ case 0x82800000u: // aua -> Latn
+ case 0x8A800000u: // auc -> Latn
+ case 0x8E800000u: // aud -> Latn
+ case 0x9A800000u: // aug -> Latn
+ case 0x9E800000u: // auh -> Latn
+ case 0xA2800000u: // aui -> Latn
+ case 0xAA800000u: // auk -> Latn
+ case 0xAE800000u: // aul -> Latn
+ case 0xB2800000u: // aum -> Latn
+ case 0xB6800000u: // aun -> Latn
+ case 0xBA800000u: // auo -> Latn
+ case 0xBE800000u: // aup -> Latn
+ case 0xC2800000u: // auq -> Latn
+ case 0xC6800000u: // aur -> Latn
+ case 0xCE800000u: // aut -> Latn
+ case 0xD2800000u: // auu -> Latn
+ case 0xDA800000u: // auw -> Latn
+ case 0xE2800000u: // auy -> Latn
+ case 0x86A00000u: // avb -> Latn
+ case 0xA2A00000u: // avi -> Latn
+ case 0xAAA00000u: // avk -> Latn
+ case 0xB2A00000u: // avm -> Latn
+ case 0xB6A00000u: // avn -> Latn
+ case 0xBAA00000u: // avo -> Latn
+ case 0xCAA00000u: // avs -> Latn
+ case 0xCEA00000u: // avt -> Latn
+ case 0xD2A00000u: // avu -> Latn
+ case 0xD6A00000u: // avv -> Latn
+ case 0x86C00000u: // awb -> Latn
+ case 0x8AC00000u: // awc -> Latn
+ case 0x92C00000u: // awe -> Latn
+ case 0x9AC00000u: // awg -> Latn
+ case 0x9EC00000u: // awh -> Latn
+ case 0xA2C00000u: // awi -> Latn
+ case 0xAAC00000u: // awk -> Latn
+ case 0xB2C00000u: // awm -> Latn
+ case 0xBAC00000u: // awo -> Latn
+ case 0xC6C00000u: // awr -> Latn
+ case 0xCAC00000u: // aws -> Latn
+ case 0xCEC00000u: // awt -> Latn
+ case 0xD2C00000u: // awu -> Latn
+ case 0xD6C00000u: // awv -> Latn
+ case 0xDAC00000u: // aww -> Latn
+ case 0xDEC00000u: // awx -> Latn
+ case 0xE2C00000u: // awy -> Latn
+ case 0x86E00000u: // axb -> Latn
+ case 0x92E00000u: // axe -> Latn
+ case 0x9AE00000u: // axg -> Latn
+ case 0xAAE00000u: // axk -> Latn
+ case 0xAEE00000u: // axl -> Latn
+ case 0xDEE00000u: // axx -> Latn
+ case 0x61790000u: // ay -> Latn
+ case 0x83000000u: // aya -> Latn
+ case 0x87000000u: // ayb -> Latn
+ case 0x8B000000u: // ayc -> Latn
+ case 0x8F000000u: // ayd -> Latn
+ case 0x93000000u: // aye -> Latn
+ case 0x9B000000u: // ayg -> Latn
+ case 0xA3000000u: // ayi -> Latn
+ case 0xAB000000u: // ayk -> Latn
+ case 0xBB000000u: // ayo -> Latn
+ case 0xC3000000u: // ayq -> Latn
+ case 0xCB000000u: // ays -> Latn
+ case 0xCF000000u: // ayt -> Latn
+ case 0xD3000000u: // ayu -> Latn
+ case 0xE7000000u: // ayz -> Latn
+ case 0x617A0000u: // az -> Latn
+ case 0x8F200000u: // azd -> Latn
+ case 0x9B200000u: // azg -> Latn
+ case 0xB3200000u: // azm -> Latn
+ case 0xB7200000u: // azn -> Latn
+ case 0xBB200000u: // azo -> Latn
+ case 0xCF200000u: // azt -> Latn
+ case 0xE7200000u: // azz -> Latn
+ case 0x80010000u: // baa -> Latn
+ case 0x84010000u: // bab -> Latn
+ case 0x88010000u: // bac -> Latn
+ case 0x90010000u: // bae -> Latn
+ case 0x94010000u: // baf -> Latn
+ case 0x98010000u: // bag -> Latn
+ case 0x9C010000u: // bah -> Latn
+ case 0xA4010000u: // baj -> Latn
+ case 0xB4010000u: // ban -> Latn
+ case 0xB8010000u: // bao -> Latn
+ case 0xC4010000u: // bar -> Latn
+ case 0xC8010000u: // bas -> Latn
+ case 0xD0010000u: // bau -> Latn
+ case 0xD4010000u: // bav -> Latn
+ case 0xD8010000u: // baw -> Latn
+ case 0xE0010000u: // bay -> Latn
+ case 0x80210000u: // bba -> Latn
+ case 0x84210000u: // bbb -> Latn
+ case 0x88210000u: // bbc -> Latn
+ case 0x8C210000u: // bbd -> Latn
+ case 0x90210000u: // bbe -> Latn
+ case 0x94210000u: // bbf -> Latn
+ case 0x98210000u: // bbg -> Latn
+ case 0xA0210000u: // bbi -> Latn
+ case 0xA4210000u: // bbj -> Latn
+ case 0xA8210000u: // bbk -> Latn
+ case 0xB0210000u: // bbm -> Latn
+ case 0xB4210000u: // bbn -> Latn
+ case 0xB8210000u: // bbo -> Latn
+ case 0xBC210000u: // bbp -> Latn
+ case 0xC0210000u: // bbq -> Latn
+ case 0xC4210000u: // bbr -> Latn
+ case 0xC8210000u: // bbs -> Latn
+ case 0xCC210000u: // bbt -> Latn
+ case 0xD0210000u: // bbu -> Latn
+ case 0xD4210000u: // bbv -> Latn
+ case 0xD8210000u: // bbw -> Latn
+ case 0xDC210000u: // bbx -> Latn
+ case 0xE0210000u: // bby -> Latn
+ case 0x80410000u: // bca -> Latn
+ case 0x84410000u: // bcb -> Latn
+ case 0x8C410000u: // bcd -> Latn
+ case 0x90410000u: // bce -> Latn
+ case 0x94410000u: // bcf -> Latn
+ case 0x98410000u: // bcg -> Latn
+ case 0x9C410000u: // bch -> Latn
+ case 0xA0410000u: // bci -> Latn
+ case 0xA4410000u: // bcj -> Latn
+ case 0xA8410000u: // bck -> Latn
+ case 0xB0410000u: // bcm -> Latn
+ case 0xB4410000u: // bcn -> Latn
+ case 0xB8410000u: // bco -> Latn
+ case 0xBC410000u: // bcp -> Latn
+ case 0xC4410000u: // bcr -> Latn
+ case 0xC8410000u: // bcs -> Latn
+ case 0xCC410000u: // bct -> Latn
+ case 0xD0410000u: // bcu -> Latn
+ case 0xD4410000u: // bcv -> Latn
+ case 0xD8410000u: // bcw -> Latn
+ case 0xE0410000u: // bcy -> Latn
+ case 0xE4410000u: // bcz -> Latn
+ case 0x80610000u: // bda -> Latn
+ case 0x84610000u: // bdb -> Latn
+ case 0x88610000u: // bdc -> Latn
+ case 0x8C610000u: // bdd -> Latn
+ case 0x90610000u: // bde -> Latn
+ case 0x94610000u: // bdf -> Latn
+ case 0x98610000u: // bdg -> Latn
+ case 0x9C610000u: // bdh -> Latn
+ case 0xA0610000u: // bdi -> Latn
+ case 0xA4610000u: // bdj -> Latn
+ case 0xA8610000u: // bdk -> Latn
+ case 0xAC610000u: // bdl -> Latn
+ case 0xB0610000u: // bdm -> Latn
+ case 0xB4610000u: // bdn -> Latn
+ case 0xB8610000u: // bdo -> Latn
+ case 0xBC610000u: // bdp -> Latn
+ case 0xC0610000u: // bdq -> Latn
+ case 0xC4610000u: // bdr -> Latn
+ case 0xC8610000u: // bds -> Latn
+ case 0xCC610000u: // bdt -> Latn
+ case 0xD0610000u: // bdu -> Latn
+ case 0xD8610000u: // bdw -> Latn
+ case 0xDC610000u: // bdx -> Latn
+ case 0xE0610000u: // bdy -> Latn
+ case 0x80810000u: // bea -> Latn
+ case 0x84810000u: // beb -> Latn
+ case 0x88810000u: // bec -> Latn
+ case 0x8C810000u: // bed -> Latn
+ case 0x94810000u: // bef -> Latn
+ case 0x9C810000u: // beh -> Latn
+ case 0xA0810000u: // bei -> Latn
+ case 0xA8810000u: // bek -> Latn
+ case 0xB0810000u: // bem -> Latn
+ case 0xB8810000u: // beo -> Latn
+ case 0xBC810000u: // bep -> Latn
+ case 0xC0810000u: // beq -> Latn
+ case 0xC8810000u: // bes -> Latn
+ case 0xCC810000u: // bet -> Latn
+ case 0xD0810000u: // beu -> Latn
+ case 0xD4810000u: // bev -> Latn
+ case 0xD8810000u: // bew -> Latn
+ case 0xDC810000u: // bex -> Latn
+ case 0xE0810000u: // bey -> Latn
+ case 0xE4810000u: // bez -> Latn
+ case 0x80A10000u: // bfa -> Latn
+ case 0x88A10000u: // bfc -> Latn
+ case 0x8CA10000u: // bfd -> Latn
+ case 0x90A10000u: // bfe -> Latn
+ case 0x94A10000u: // bff -> Latn
+ case 0x98A10000u: // bfg -> Latn
+ case 0x9CA10000u: // bfh -> Latn
+ case 0xA4A10000u: // bfj -> Latn
+ case 0xACA10000u: // bfl -> Latn
+ case 0xB0A10000u: // bfm -> Latn
+ case 0xB4A10000u: // bfn -> Latn
+ case 0xB8A10000u: // bfo -> Latn
+ case 0xBCA10000u: // bfp -> Latn
+ case 0xC8A10000u: // bfs -> Latn
+ case 0xDCA10000u: // bfx -> Latn
+ case 0x80C10000u: // bga -> Latn
+ case 0x84C10000u: // bgb -> Latn
+ case 0x94C10000u: // bgf -> Latn
+ case 0x98C10000u: // bgg -> Latn
+ case 0xA0C10000u: // bgi -> Latn
+ case 0xA4C10000u: // bgj -> Latn
+ case 0xB8C10000u: // bgo -> Latn
+ case 0xC4C10000u: // bgr -> Latn
+ case 0xC8C10000u: // bgs -> Latn
+ case 0xCCC10000u: // bgt -> Latn
+ case 0xD0C10000u: // bgu -> Latn
+ case 0xD4C10000u: // bgv -> Latn
+ case 0xE0C10000u: // bgy -> Latn
+ case 0xE4C10000u: // bgz -> Latn
+ case 0x88E10000u: // bhc -> Latn
+ case 0x94E10000u: // bhf -> Latn
+ case 0x98E10000u: // bhg -> Latn
+ case 0xACE10000u: // bhl -> Latn
+ case 0xBCE10000u: // bhp -> Latn
+ case 0xC0E10000u: // bhq -> Latn
+ case 0xC4E10000u: // bhr -> Latn
+ case 0xC8E10000u: // bhs -> Latn
+ case 0xD4E10000u: // bhv -> Latn
+ case 0xD8E10000u: // bhw -> Latn
+ case 0xE0E10000u: // bhy -> Latn
+ case 0xE4E10000u: // bhz -> Latn
+ case 0x62690000u: // bi -> Latn
+ case 0x81010000u: // bia -> Latn
+ case 0x85010000u: // bib -> Latn
+ case 0x8D010000u: // bid -> Latn
+ case 0x91010000u: // bie -> Latn
+ case 0x95010000u: // bif -> Latn
+ case 0x99010000u: // big -> Latn
+ case 0xA9010000u: // bik -> Latn
+ case 0xAD010000u: // bil -> Latn
+ case 0xB1010000u: // bim -> Latn
+ case 0xB5010000u: // bin -> Latn
+ case 0xB9010000u: // bio -> Latn
+ case 0xBD010000u: // bip -> Latn
+ case 0xC1010000u: // biq -> Latn
+ case 0xC5010000u: // bir -> Latn
+ case 0xCD010000u: // bit -> Latn
+ case 0xD1010000u: // biu -> Latn
+ case 0xD5010000u: // biv -> Latn
+ case 0xD9010000u: // biw -> Latn
+ case 0xE5010000u: // biz -> Latn
+ case 0x81210000u: // bja -> Latn
+ case 0x85210000u: // bjb -> Latn
+ case 0x89210000u: // bjc -> Latn
+ case 0x99210000u: // bjg -> Latn
+ case 0x9D210000u: // bjh -> Latn
+ case 0xA1210000u: // bji -> Latn
+ case 0xA9210000u: // bjk -> Latn
+ case 0xAD210000u: // bjl -> Latn
+ case 0xB5210000u: // bjn -> Latn
+ case 0xB9210000u: // bjo -> Latn
+ case 0xBD210000u: // bjp -> Latn
+ case 0xC5210000u: // bjr -> Latn
+ case 0xC9210000u: // bjs -> Latn
+ case 0xCD210000u: // bjt -> Latn
+ case 0xD1210000u: // bju -> Latn
+ case 0xD5210000u: // bjv -> Latn
+ case 0xD9210000u: // bjw -> Latn
+ case 0xDD210000u: // bjx -> Latn
+ case 0xE1210000u: // bjy -> Latn
+ case 0xE5210000u: // bjz -> Latn
+ case 0x81410000u: // bka -> Latn
+ case 0x89410000u: // bkc -> Latn
+ case 0x8D410000u: // bkd -> Latn
+ case 0x95410000u: // bkf -> Latn
+ case 0x99410000u: // bkg -> Latn
+ case 0x9D410000u: // bkh -> Latn
+ case 0xA1410000u: // bki -> Latn
+ case 0xA5410000u: // bkj -> Latn
+ case 0xAD410000u: // bkl -> Latn
+ case 0xB1410000u: // bkm -> Latn
+ case 0xB5410000u: // bkn -> Latn
+ case 0xB9410000u: // bko -> Latn
+ case 0xBD410000u: // bkp -> Latn
+ case 0xC1410000u: // bkq -> Latn
+ case 0xC5410000u: // bkr -> Latn
+ case 0xC9410000u: // bks -> Latn
+ case 0xCD410000u: // bkt -> Latn
+ case 0xD1410000u: // bku -> Latn
+ case 0xD5410000u: // bkv -> Latn
+ case 0xD9410000u: // bkw -> Latn
+ case 0xDD410000u: // bkx -> Latn
+ case 0xE1410000u: // bky -> Latn
+ case 0xE5410000u: // bkz -> Latn
+ case 0x81610000u: // bla -> Latn
+ case 0x85610000u: // blb -> Latn
+ case 0x89610000u: // blc -> Latn
+ case 0x8D610000u: // bld -> Latn
+ case 0x91610000u: // ble -> Latn
+ case 0x95610000u: // blf -> Latn
+ case 0x9D610000u: // blh -> Latn
+ case 0xA1610000u: // bli -> Latn
+ case 0xA5610000u: // blj -> Latn
+ case 0xB1610000u: // blm -> Latn
+ case 0xB5610000u: // bln -> Latn
+ case 0xB9610000u: // blo -> Latn
+ case 0xBD610000u: // blp -> Latn
+ case 0xC1610000u: // blq -> Latn
+ case 0xC5610000u: // blr -> Latn
+ case 0xC9610000u: // bls -> Latn
+ case 0xD5610000u: // blv -> Latn
+ case 0xD9610000u: // blw -> Latn
+ case 0xDD610000u: // blx -> Latn
+ case 0xE1610000u: // bly -> Latn
+ case 0xE5610000u: // blz -> Latn
+ case 0x626D0000u: // bm -> Latn
+ case 0x81810000u: // bma -> Latn
+ case 0x85810000u: // bmb -> Latn
+ case 0x89810000u: // bmc -> Latn
+ case 0x8D810000u: // bmd -> Latn
+ case 0x91810000u: // bme -> Latn
+ case 0x95810000u: // bmf -> Latn
+ case 0x99810000u: // bmg -> Latn
+ case 0x9D810000u: // bmh -> Latn
+ case 0xA1810000u: // bmi -> Latn
+ case 0xA9810000u: // bmk -> Latn
+ case 0xAD810000u: // bml -> Latn
+ case 0xB1810000u: // bmm -> Latn
+ case 0xB5810000u: // bmn -> Latn
+ case 0xB9810000u: // bmo -> Latn
+ case 0xBD810000u: // bmp -> Latn
+ case 0xC1810000u: // bmq -> Latn
+ case 0xC5810000u: // bmr -> Latn
+ case 0xC9810000u: // bms -> Latn
+ case 0xD1810000u: // bmu -> Latn
+ case 0xD5810000u: // bmv -> Latn
+ case 0xD9810000u: // bmw -> Latn
+ case 0xDD810000u: // bmx -> Latn
+ case 0xE5810000u: // bmz -> Latn
+ case 0x81A10000u: // bna -> Latn
+ case 0x85A10000u: // bnb -> Latn
+ case 0x89A10000u: // bnc -> Latn
+ case 0x8DA10000u: // bnd -> Latn
+ case 0x91A10000u: // bne -> Latn
+ case 0x95A10000u: // bnf -> Latn
+ case 0x99A10000u: // bng -> Latn
+ case 0xA1A10000u: // bni -> Latn
+ case 0xA5A10000u: // bnj -> Latn
+ case 0xA9A10000u: // bnk -> Latn
+ case 0xB1A10000u: // bnm -> Latn
+ case 0xB5A10000u: // bnn -> Latn
+ case 0xB9A10000u: // bno -> Latn
+ case 0xBDA10000u: // bnp -> Latn
+ case 0xC1A10000u: // bnq -> Latn
+ case 0xC5A10000u: // bnr -> Latn
+ case 0xD1A10000u: // bnu -> Latn
+ case 0xD5A10000u: // bnv -> Latn
+ case 0xD9A10000u: // bnw -> Latn
+ case 0xDDA10000u: // bnx -> Latn
+ case 0xE1A10000u: // bny -> Latn
+ case 0xE5A10000u: // bnz -> Latn
+ case 0x81C10000u: // boa -> Latn
+ case 0x85C10000u: // bob -> Latn
+ case 0x91C10000u: // boe -> Latn
+ case 0x95C10000u: // bof -> Latn
+ case 0x9DC10000u: // boh -> Latn
+ case 0xA5C10000u: // boj -> Latn
+ case 0xA9C10000u: // bok -> Latn
+ case 0xADC10000u: // bol -> Latn
+ case 0xB1C10000u: // bom -> Latn
+ case 0xB5C10000u: // bon -> Latn
+ case 0xB9C10000u: // boo -> Latn
+ case 0xBDC10000u: // bop -> Latn
+ case 0xC1C10000u: // boq -> Latn
+ case 0xC5C10000u: // bor -> Latn
+ case 0xCDC10000u: // bot -> Latn
+ case 0xD1C10000u: // bou -> Latn
+ case 0xD5C10000u: // bov -> Latn
+ case 0xD9C10000u: // bow -> Latn
+ case 0xDDC10000u: // box -> Latn
+ case 0xE1C10000u: // boy -> Latn
+ case 0xE5C10000u: // boz -> Latn
+ case 0x81E10000u: // bpa -> Latn
+ case 0x89E10000u: // bpc -> Latn
+ case 0x8DE10000u: // bpd -> Latn
+ case 0x91E10000u: // bpe -> Latn
+ case 0x99E10000u: // bpg -> Latn
+ case 0xA1E10000u: // bpi -> Latn
+ case 0xA5E10000u: // bpj -> Latn
+ case 0xA9E10000u: // bpk -> Latn
+ case 0xADE10000u: // bpl -> Latn
+ case 0xB1E10000u: // bpm -> Latn
+ case 0xB9E10000u: // bpo -> Latn
+ case 0xBDE10000u: // bpp -> Latn
+ case 0xC1E10000u: // bpq -> Latn
+ case 0xC5E10000u: // bpr -> Latn
+ case 0xC9E10000u: // bps -> Latn
+ case 0xCDE10000u: // bpt -> Latn
+ case 0xD1E10000u: // bpu -> Latn
+ case 0xD5E10000u: // bpv -> Latn
+ case 0xD9E10000u: // bpw -> Latn
+ case 0xE5E10000u: // bpz -> Latn
+ case 0x82010000u: // bqa -> Latn
+ case 0x86010000u: // bqb -> Latn
+ case 0x8A010000u: // bqc -> Latn
+ case 0x8E010000u: // bqd -> Latn
+ case 0x96010000u: // bqf -> Latn
+ case 0x9A010000u: // bqg -> Latn
+ case 0xA6010000u: // bqj -> Latn
+ case 0xAA010000u: // bqk -> Latn
+ case 0xAE010000u: // bql -> Latn
+ case 0xB2010000u: // bqm -> Latn
+ case 0xBA010000u: // bqo -> Latn
+ case 0xBE010000u: // bqp -> Latn
+ case 0xC2010000u: // bqq -> Latn
+ case 0xC6010000u: // bqr -> Latn
+ case 0xCA010000u: // bqs -> Latn
+ case 0xCE010000u: // bqt -> Latn
+ case 0xD2010000u: // bqu -> Latn
+ case 0xD6010000u: // bqv -> Latn
+ case 0xDA010000u: // bqw -> Latn
+ case 0xDE010000u: // bqx -> Latn
+ case 0xE6010000u: // bqz -> Latn
+ case 0x62720000u: // br -> Latn
+ case 0x8A210000u: // brc -> Latn
+ case 0x96210000u: // brf -> Latn
+ case 0x9A210000u: // brg -> Latn
+ case 0xA2210000u: // bri -> Latn
+ case 0xA6210000u: // brj -> Latn
+ case 0xAE210000u: // brl -> Latn
+ case 0xB2210000u: // brm -> Latn
+ case 0xB6210000u: // brn -> Latn
+ case 0xBE210000u: // brp -> Latn
+ case 0xC2210000u: // brq -> Latn
+ case 0xC6210000u: // brr -> Latn
+ case 0xCA210000u: // brs -> Latn
+ case 0xCE210000u: // brt -> Latn
+ case 0xD2210000u: // bru -> Latn
+ case 0xE2210000u: // bry -> Latn
+ case 0xE6210000u: // brz -> Latn
+ case 0x62730000u: // bs -> Latn
+ case 0x82410000u: // bsa -> Latn
+ case 0x86410000u: // bsb -> Latn
+ case 0x8A410000u: // bsc -> Latn
+ case 0x92410000u: // bse -> Latn
+ case 0x96410000u: // bsf -> Latn
+ case 0xA2410000u: // bsi -> Latn
+ case 0xA6410000u: // bsj -> Latn
+ case 0xAE410000u: // bsl -> Latn
+ case 0xB2410000u: // bsm -> Latn
+ case 0xB6410000u: // bsn -> Latn
+ case 0xBA410000u: // bso -> Latn
+ case 0xBE410000u: // bsp -> Latn
+ case 0xC6410000u: // bsr -> Latn
+ case 0xCA410000u: // bss -> Latn
+ case 0xD2410000u: // bsu -> Latn
+ case 0xD6410000u: // bsv -> Latn
+ case 0xDA410000u: // bsw -> Latn
+ case 0xDE410000u: // bsx -> Latn
+ case 0xE2410000u: // bsy -> Latn
+ case 0x82610000u: // bta -> Latn
+ case 0x8A610000u: // btc -> Latn
+ case 0x92610000u: // bte -> Latn
+ case 0x96610000u: // btf -> Latn
+ case 0x9A610000u: // btg -> Latn
+ case 0x9E610000u: // bth -> Latn
+ case 0xA2610000u: // bti -> Latn
+ case 0xA6610000u: // btj -> Latn
+ case 0xB6610000u: // btn -> Latn
+ case 0xBA610000u: // bto -> Latn
+ case 0xBE610000u: // btp -> Latn
+ case 0xC2610000u: // btq -> Latn
+ case 0xC6610000u: // btr -> Latn
+ case 0xCA610000u: // bts -> Latn
+ case 0xCE610000u: // btt -> Latn
+ case 0xD2610000u: // btu -> Latn
+ case 0xDA610000u: // btw -> Latn
+ case 0xDE610000u: // btx -> Latn
+ case 0xE2610000u: // bty -> Latn
+ case 0xE6610000u: // btz -> Latn
+ case 0x86810000u: // bub -> Latn
+ case 0x8A810000u: // buc -> Latn
+ case 0x8E810000u: // bud -> Latn
+ case 0x92810000u: // bue -> Latn
+ case 0x96810000u: // buf -> Latn
+ case 0x9A810000u: // bug -> Latn
+ case 0x9E810000u: // buh -> Latn
+ case 0xA2810000u: // bui -> Latn
+ case 0xA6810000u: // buj -> Latn
+ case 0xAA810000u: // buk -> Latn
+ case 0xB2810000u: // bum -> Latn
+ case 0xB6810000u: // bun -> Latn
+ case 0xBA810000u: // buo -> Latn
+ case 0xBE810000u: // bup -> Latn
+ case 0xC2810000u: // buq -> Latn
+ case 0xCA810000u: // bus -> Latn
+ case 0xCE810000u: // but -> Latn
+ case 0xD2810000u: // buu -> Latn
+ case 0xD6810000u: // buv -> Latn
+ case 0xDA810000u: // buw -> Latn
+ case 0xDE810000u: // bux -> Latn
+ case 0xE2810000u: // buy -> Latn
+ case 0xE6810000u: // buz -> Latn
+ case 0x82A10000u: // bva -> Latn
+ case 0x86A10000u: // bvb -> Latn
+ case 0x8AA10000u: // bvc -> Latn
+ case 0x8EA10000u: // bvd -> Latn
+ case 0x92A10000u: // bve -> Latn
+ case 0x96A10000u: // bvf -> Latn
+ case 0x9AA10000u: // bvg -> Latn
+ case 0x9EA10000u: // bvh -> Latn
+ case 0xA2A10000u: // bvi -> Latn
+ case 0xA6A10000u: // bvj -> Latn
+ case 0xAAA10000u: // bvk -> Latn
+ case 0xB2A10000u: // bvm -> Latn
+ case 0xB6A10000u: // bvn -> Latn
+ case 0xBAA10000u: // bvo -> Latn
+ case 0xC2A10000u: // bvq -> Latn
+ case 0xC6A10000u: // bvr -> Latn
+ case 0xCEA10000u: // bvt -> Latn
+ case 0xD2A10000u: // bvu -> Latn
+ case 0xD6A10000u: // bvv -> Latn
+ case 0xDAA10000u: // bvw -> Latn
+ case 0xDEA10000u: // bvx -> Latn
+ case 0xE2A10000u: // bvy -> Latn
+ case 0xE6A10000u: // bvz -> Latn
+ case 0x82C10000u: // bwa -> Latn
+ case 0x86C10000u: // bwb -> Latn
+ case 0x8AC10000u: // bwc -> Latn
+ case 0x8EC10000u: // bwd -> Latn
+ case 0x96C10000u: // bwf -> Latn
+ case 0x9AC10000u: // bwg -> Latn
+ case 0x9EC10000u: // bwh -> Latn
+ case 0xA2C10000u: // bwi -> Latn
+ case 0xA6C10000u: // bwj -> Latn
+ case 0xAAC10000u: // bwk -> Latn
+ case 0xAEC10000u: // bwl -> Latn
+ case 0xB2C10000u: // bwm -> Latn
+ case 0xBAC10000u: // bwo -> Latn
+ case 0xBEC10000u: // bwp -> Latn
+ case 0xC2C10000u: // bwq -> Latn
+ case 0xC6C10000u: // bwr -> Latn
+ case 0xCAC10000u: // bws -> Latn
+ case 0xCEC10000u: // bwt -> Latn
+ case 0xD2C10000u: // bwu -> Latn
+ case 0xDAC10000u: // bww -> Latn
+ case 0xDEC10000u: // bwx -> Latn
+ case 0xE2C10000u: // bwy -> Latn
+ case 0xE6C10000u: // bwz -> Latn
+ case 0x82E10000u: // bxa -> Latn
+ case 0x86E10000u: // bxb -> Latn
+ case 0x8AE10000u: // bxc -> Latn
+ case 0x96E10000u: // bxf -> Latn
+ case 0x9AE10000u: // bxg -> Latn
+ case 0x9EE10000u: // bxh -> Latn
+ case 0xA2E10000u: // bxi -> Latn
+ case 0xA6E10000u: // bxj -> Latn
+ case 0xAEE10000u: // bxl -> Latn
+ case 0xB6E10000u: // bxn -> Latn
+ case 0xBAE10000u: // bxo -> Latn
+ case 0xBEE10000u: // bxp -> Latn
+ case 0xC2E10000u: // bxq -> Latn
+ case 0xCAE10000u: // bxs -> Latn
+ case 0xD6E10000u: // bxv -> Latn
+ case 0xDAE10000u: // bxw -> Latn
+ case 0xE6E10000u: // bxz -> Latn
+ case 0x83010000u: // bya -> Latn
+ case 0x87010000u: // byb -> Latn
+ case 0x8B010000u: // byc -> Latn
+ case 0x8F010000u: // byd -> Latn
+ case 0x93010000u: // bye -> Latn
+ case 0x97010000u: // byf -> Latn
+ case 0xA3010000u: // byi -> Latn
+ case 0xA7010000u: // byj -> Latn
+ case 0xAB010000u: // byk -> Latn
+ case 0xAF010000u: // byl -> Latn
+ case 0xB3010000u: // bym -> Latn
+ case 0xBF010000u: // byp -> Latn
+ case 0xC7010000u: // byr -> Latn
+ case 0xCB010000u: // bys -> Latn
+ case 0xD7010000u: // byv -> Latn
+ case 0xDF010000u: // byx -> Latn
+ case 0xE7010000u: // byz -> Latn
+ case 0x83210000u: // bza -> Latn
+ case 0x87210000u: // bzb -> Latn
+ case 0x8B210000u: // bzc -> Latn
+ case 0x8F210000u: // bzd -> Latn
+ case 0x93210000u: // bze -> Latn
+ case 0x97210000u: // bzf -> Latn
+ case 0x9F210000u: // bzh -> Latn
+ case 0xA7210000u: // bzj -> Latn
+ case 0xAB210000u: // bzk -> Latn
+ case 0xAF210000u: // bzl -> Latn
+ case 0xB3210000u: // bzm -> Latn
+ case 0xB7210000u: // bzn -> Latn
+ case 0xBB210000u: // bzo -> Latn
+ case 0xBF210000u: // bzp -> Latn
+ case 0xC3210000u: // bzq -> Latn
+ case 0xC7210000u: // bzr -> Latn
+ case 0xCF210000u: // bzt -> Latn
+ case 0xD3210000u: // bzu -> Latn
+ case 0xD7210000u: // bzv -> Latn
+ case 0xDB210000u: // bzw -> Latn
+ case 0xDF210000u: // bzx -> Latn
+ case 0xE3210000u: // bzy -> Latn
+ case 0xE7210000u: // bzz -> Latn
+ case 0x63610000u: // ca -> Latn
+ case 0x80020000u: // caa -> Latn
+ case 0x84020000u: // cab -> Latn
+ case 0x88020000u: // cac -> Latn
+ case 0x8C020000u: // cad -> Latn
+ case 0x90020000u: // cae -> Latn
+ case 0x94020000u: // caf -> Latn
+ case 0x98020000u: // cag -> Latn
+ case 0x9C020000u: // cah -> Latn
+ case 0xA4020000u: // caj -> Latn
+ case 0xA8020000u: // cak -> Latn
+ case 0xAC020000u: // cal -> Latn
+ case 0xB0020000u: // cam -> Latn
+ case 0xB4020000u: // can -> Latn
+ case 0xB8020000u: // cao -> Latn
+ case 0xBC020000u: // cap -> Latn
+ case 0xC0020000u: // caq -> Latn
+ case 0xC4020000u: // car -> Latn
+ case 0xC8020000u: // cas -> Latn
+ case 0xD4020000u: // cav -> Latn
+ case 0xD8020000u: // caw -> Latn
+ case 0xDC020000u: // cax -> Latn
+ case 0xE0020000u: // cay -> Latn
+ case 0xE4020000u: // caz -> Latn
+ case 0x84220000u: // cbb -> Latn
+ case 0x88220000u: // cbc -> Latn
+ case 0x8C220000u: // cbd -> Latn
+ case 0x98220000u: // cbg -> Latn
+ case 0xA0220000u: // cbi -> Latn
+ case 0xA4220000u: // cbj -> Latn
+ case 0xA8220000u: // cbk -> Latn
+ case 0xAC220000u: // cbl -> Latn
+ case 0xB8220000u: // cbo -> Latn
+ case 0xC0220000u: // cbq -> Latn
+ case 0xC4220000u: // cbr -> Latn
+ case 0xC8220000u: // cbs -> Latn
+ case 0xCC220000u: // cbt -> Latn
+ case 0xD0220000u: // cbu -> Latn
+ case 0xD4220000u: // cbv -> Latn
+ case 0xD8220000u: // cbw -> Latn
+ case 0xE0220000u: // cby -> Latn
+ case 0x88420000u: // ccc -> Latn
+ case 0x8C420000u: // ccd -> Latn
+ case 0x90420000u: // cce -> Latn
+ case 0x98420000u: // ccg -> Latn
+ case 0x9C420000u: // cch -> Latn
+ case 0xA4420000u: // ccj -> Latn
+ case 0xAC420000u: // ccl -> Latn
+ case 0xB0420000u: // ccm -> Latn
+ case 0xB8420000u: // cco -> Latn
+ case 0xC4420000u: // ccr -> Latn
+ case 0x94620000u: // cdf -> Latn
+ case 0xC4620000u: // cdr -> Latn
+ case 0x80820000u: // cea -> Latn
+ case 0x84820000u: // ceb -> Latn
+ case 0x98820000u: // ceg -> Latn
+ case 0xA8820000u: // cek -> Latn
+ case 0xB4820000u: // cen -> Latn
+ case 0xCC820000u: // cet -> Latn
+ case 0xE0820000u: // cey -> Latn
+ case 0x80A20000u: // cfa -> Latn
+ case 0x8CA20000u: // cfd -> Latn
+ case 0x98A20000u: // cfg -> Latn
+ case 0xB0A20000u: // cfm -> Latn
+ case 0x80C20000u: // cga -> Latn
+ case 0x88C20000u: // cgc -> Latn
+ case 0x98C20000u: // cgg -> Latn
+ case 0x63680000u: // ch -> Latn
+ case 0x84E20000u: // chb -> Latn
+ case 0x8CE20000u: // chd -> Latn
+ case 0x94E20000u: // chf -> Latn
+ case 0x9CE20000u: // chh -> Latn
+ case 0xA4E20000u: // chj -> Latn
+ case 0xA8E20000u: // chk -> Latn
+ case 0xACE20000u: // chl -> Latn
+ case 0xB4E20000u: // chn -> Latn
+ case 0xB8E20000u: // cho -> Latn
+ case 0xBCE20000u: // chp -> Latn
+ case 0xC0E20000u: // chq -> Latn
+ case 0xCCE20000u: // cht -> Latn
+ case 0xD8E20000u: // chw -> Latn
+ case 0xE0E20000u: // chy -> Latn
+ case 0xE4E20000u: // chz -> Latn
+ case 0x81020000u: // cia -> Latn
+ case 0x85020000u: // cib -> Latn
+ case 0x89020000u: // cic -> Latn
+ case 0x91020000u: // cie -> Latn
+ case 0xB1020000u: // cim -> Latn
+ case 0xB5020000u: // cin -> Latn
+ case 0xBD020000u: // cip -> Latn
+ case 0xC5020000u: // cir -> Latn
+ case 0xD9020000u: // ciw -> Latn
+ case 0xE1020000u: // ciy -> Latn
+ case 0x91220000u: // cje -> Latn
+ case 0x9D220000u: // cjh -> Latn
+ case 0xA9220000u: // cjk -> Latn
+ case 0xB5220000u: // cjn -> Latn
+ case 0xB9220000u: // cjo -> Latn
+ case 0xBD220000u: // cjp -> Latn
+ case 0xC9220000u: // cjs -> Latn
+ case 0xD5220000u: // cjv -> Latn
+ case 0xAD420000u: // ckl -> Latn
+ case 0xB1420000u: // ckm -> Latn
+ case 0xB5420000u: // ckn -> Latn
+ case 0xB9420000u: // cko -> Latn
+ case 0xC1420000u: // ckq -> Latn
+ case 0xC5420000u: // ckr -> Latn
+ case 0xC9420000u: // cks -> Latn
+ case 0xD1420000u: // cku -> Latn
+ case 0xD5420000u: // ckv -> Latn
+ case 0xDD420000u: // ckx -> Latn
+ case 0xE1420000u: // cky -> Latn
+ case 0xE5420000u: // ckz -> Latn
+ case 0x81620000u: // cla -> Latn
+ case 0x89620000u: // clc -> Latn
+ case 0x91620000u: // cle -> Latn
+ case 0xA1620000u: // cli -> Latn
+ case 0xA5620000u: // clj -> Latn
+ case 0xA9620000u: // clk -> Latn
+ case 0xAD620000u: // cll -> Latn
+ case 0xB1620000u: // clm -> Latn
+ case 0xB9620000u: // clo -> Latn
+ case 0xCD620000u: // clt -> Latn
+ case 0xD1620000u: // clu -> Latn
+ case 0xE1620000u: // cly -> Latn
+ case 0x81820000u: // cma -> Latn
+ case 0x91820000u: // cme -> Latn
+ case 0xA1820000u: // cmi -> Latn
+ case 0xAD820000u: // cml -> Latn
+ case 0xB9820000u: // cmo -> Latn
+ case 0xC5820000u: // cmr -> Latn
+ case 0xC9820000u: // cms -> Latn
+ case 0xCD820000u: // cmt -> Latn
+ case 0x85A20000u: // cnb -> Latn
+ case 0x89A20000u: // cnc -> Latn
+ case 0x99A20000u: // cng -> Latn
+ case 0x9DA20000u: // cnh -> Latn
+ case 0xA1A20000u: // cni -> Latn
+ case 0xA9A20000u: // cnk -> Latn
+ case 0xADA20000u: // cnl -> Latn
+ case 0xC1A20000u: // cnq -> Latn
+ case 0xC9A20000u: // cns -> Latn
+ case 0xCDA20000u: // cnt -> Latn
+ case 0xD9A20000u: // cnw -> Latn
+ case 0xDDA20000u: // cnx -> Latn
+ case 0x636F0000u: // co -> Latn
+ case 0x81C20000u: // coa -> Latn
+ case 0x85C20000u: // cob -> Latn
+ case 0x89C20000u: // coc -> Latn
+ case 0x8DC20000u: // cod -> Latn
+ case 0x91C20000u: // coe -> Latn
+ case 0x95C20000u: // cof -> Latn
+ case 0x9DC20000u: // coh -> Latn
+ case 0xA5C20000u: // coj -> Latn
+ case 0xA9C20000u: // cok -> Latn
+ case 0xADC20000u: // col -> Latn
+ case 0xB1C20000u: // com -> Latn
+ case 0xB9C20000u: // coo -> Latn
+ case 0xC1C20000u: // coq -> Latn
+ case 0xCDC20000u: // cot -> Latn
+ case 0xD1C20000u: // cou -> Latn
+ case 0xDDC20000u: // cox -> Latn
+ case 0xE5C20000u: // coz -> Latn
+ case 0x81E20000u: // cpa -> Latn
+ case 0x85E20000u: // cpb -> Latn
+ case 0x89E20000u: // cpc -> Latn
+ case 0xA1E20000u: // cpi -> Latn
+ case 0xB5E20000u: // cpn -> Latn
+ case 0xB9E20000u: // cpo -> Latn
+ case 0xC9E20000u: // cps -> Latn
+ case 0xD1E20000u: // cpu -> Latn
+ case 0xDDE20000u: // cpx -> Latn
+ case 0xE1E20000u: // cpy -> Latn
+ case 0x8E020000u: // cqd -> Latn
+ case 0x82220000u: // cra -> Latn
+ case 0x86220000u: // crb -> Latn
+ case 0x8A220000u: // crc -> Latn
+ case 0x8E220000u: // crd -> Latn
+ case 0x96220000u: // crf -> Latn
+ case 0x9A220000u: // crg -> Latn
+ case 0xA2220000u: // cri -> Latn
+ case 0xB6220000u: // crn -> Latn
+ case 0xBA220000u: // cro -> Latn
+ case 0xC2220000u: // crq -> Latn
+ case 0xCA220000u: // crs -> Latn
+ case 0xCE220000u: // crt -> Latn
+ case 0xD6220000u: // crv -> Latn
+ case 0xDA220000u: // crw -> Latn
+ case 0xDE220000u: // crx -> Latn
+ case 0xE2220000u: // cry -> Latn
+ case 0xE6220000u: // crz -> Latn
+ case 0x63730000u: // cs -> Latn
+ case 0x82420000u: // csa -> Latn
+ case 0x86420000u: // csb -> Latn
+ case 0xA6420000u: // csj -> Latn
+ case 0xAA420000u: // csk -> Latn
+ case 0xB2420000u: // csm -> Latn
+ case 0xBA420000u: // cso -> Latn
+ case 0xCA420000u: // css -> Latn
+ case 0xCE420000u: // cst -> Latn
+ case 0xD6420000u: // csv -> Latn
+ case 0xE2420000u: // csy -> Latn
+ case 0xE6420000u: // csz -> Latn
+ case 0x82620000u: // cta -> Latn
+ case 0x8A620000u: // ctc -> Latn
+ case 0x92620000u: // cte -> Latn
+ case 0x9E620000u: // cth -> Latn
+ case 0xAE620000u: // ctl -> Latn
+ case 0xB2620000u: // ctm -> Latn
+ case 0xBA620000u: // cto -> Latn
+ case 0xBE620000u: // ctp -> Latn
+ case 0xCA620000u: // cts -> Latn
+ case 0xD2620000u: // ctu -> Latn
+ case 0xE6620000u: // ctz -> Latn
+ case 0x82820000u: // cua -> Latn
+ case 0x86820000u: // cub -> Latn
+ case 0x8A820000u: // cuc -> Latn
+ case 0x9E820000u: // cuh -> Latn
+ case 0xA2820000u: // cui -> Latn
+ case 0xA6820000u: // cuj -> Latn
+ case 0xAA820000u: // cuk -> Latn
+ case 0xAE820000u: // cul -> Latn
+ case 0xBA820000u: // cuo -> Latn
+ case 0xBE820000u: // cup -> Latn
+ case 0xCE820000u: // cut -> Latn
+ case 0xD6820000u: // cuv -> Latn
+ case 0xDE820000u: // cux -> Latn
+ case 0xE2820000u: // cuy -> Latn
+ case 0x9AA20000u: // cvg -> Latn
+ case 0xB6A20000u: // cvn -> Latn
+ case 0x82C20000u: // cwa -> Latn
+ case 0x86C20000u: // cwb -> Latn
+ case 0x92C20000u: // cwe -> Latn
+ case 0x9AC20000u: // cwg -> Latn
+ case 0xCEC20000u: // cwt -> Latn
+ case 0x9EE20000u: // cxh -> Latn
+ case 0x63790000u: // cy -> Latn
+ case 0x83020000u: // cya -> Latn
+ case 0x87020000u: // cyb -> Latn
+ case 0xBB020000u: // cyo -> Latn
+ case 0xB7220000u: // czn -> Latn
+ case 0xCF220000u: // czt -> Latn
+ case 0x64610000u: // da -> Latn
+ case 0x80030000u: // daa -> Latn
+ case 0x88030000u: // dac -> Latn
+ case 0x8C030000u: // dad -> Latn
+ case 0x90030000u: // dae -> Latn
+ case 0x98030000u: // dag -> Latn
+ case 0x9C030000u: // dah -> Latn
+ case 0xA0030000u: // dai -> Latn
+ case 0xA4030000u: // daj -> Latn
+ case 0xA8030000u: // dak -> Latn
+ case 0xAC030000u: // dal -> Latn
+ case 0xB0030000u: // dam -> Latn
+ case 0xB8030000u: // dao -> Latn
+ case 0xC8030000u: // das -> Latn
+ case 0xD0030000u: // dau -> Latn
+ case 0xD4030000u: // dav -> Latn
+ case 0xD8030000u: // daw -> Latn
+ case 0xDC030000u: // dax -> Latn
+ case 0xE4030000u: // daz -> Latn
+ case 0x80230000u: // dba -> Latn
+ case 0x84230000u: // dbb -> Latn
+ case 0x8C230000u: // dbd -> Latn
+ case 0x90230000u: // dbe -> Latn
+ case 0x94230000u: // dbf -> Latn
+ case 0x98230000u: // dbg -> Latn
+ case 0xA0230000u: // dbi -> Latn
+ case 0xA4230000u: // dbj -> Latn
+ case 0xAC230000u: // dbl -> Latn
+ case 0xB0230000u: // dbm -> Latn
+ case 0xB4230000u: // dbn -> Latn
+ case 0xB8230000u: // dbo -> Latn
+ case 0xBC230000u: // dbp -> Latn
+ case 0xC0230000u: // dbq -> Latn
+ case 0xCC230000u: // dbt -> Latn
+ case 0xD0230000u: // dbu -> Latn
+ case 0xD4230000u: // dbv -> Latn
+ case 0xD8230000u: // dbw -> Latn
+ case 0xE0230000u: // dby -> Latn
+ case 0xC4430000u: // dcr -> Latn
+ case 0x80630000u: // dda -> Latn
+ case 0x8C630000u: // ddd -> Latn
+ case 0x90630000u: // dde -> Latn
+ case 0x98630000u: // ddg -> Latn
+ case 0xA0630000u: // ddi -> Latn
+ case 0xA4630000u: // ddj -> Latn
+ case 0xB4630000u: // ddn -> Latn
+ case 0xC4630000u: // ddr -> Latn
+ case 0xC8630000u: // dds -> Latn
+ case 0xD8630000u: // ddw -> Latn
+ case 0x64650000u: // de -> Latn
+ case 0x88830000u: // dec -> Latn
+ case 0x8C830000u: // ded -> Latn
+ case 0x90830000u: // dee -> Latn
+ case 0x98830000u: // deg -> Latn
+ case 0xA0830000u: // dei -> Latn
+ case 0xA8830000u: // dek -> Latn
+ case 0xAC830000u: // del -> Latn
+ case 0xB0830000u: // dem -> Latn
+ case 0xB4830000u: // den -> Latn
+ case 0xC0830000u: // deq -> Latn
+ case 0xC8830000u: // des -> Latn
+ case 0xD4830000u: // dev -> Latn
+ case 0xE4830000u: // dez -> Latn
+ case 0x80C30000u: // dga -> Latn
+ case 0x84C30000u: // dgb -> Latn
+ case 0x88C30000u: // dgc -> Latn
+ case 0x8CC30000u: // dgd -> Latn
+ case 0x90C30000u: // dge -> Latn
+ case 0x98C30000u: // dgg -> Latn
+ case 0x9CC30000u: // dgh -> Latn
+ case 0xA0C30000u: // dgi -> Latn
+ case 0xA8C30000u: // dgk -> Latn
+ case 0xB4C30000u: // dgn -> Latn
+ case 0xC4C30000u: // dgr -> Latn
+ case 0xC8C30000u: // dgs -> Latn
+ case 0xCCC30000u: // dgt -> Latn
+ case 0xD8C30000u: // dgw -> Latn
+ case 0xDCC30000u: // dgx -> Latn
+ case 0xE4C30000u: // dgz -> Latn
+ case 0x98E30000u: // dhg -> Latn
+ case 0xACE30000u: // dhl -> Latn
+ case 0xB0E30000u: // dhm -> Latn
+ case 0xC4E30000u: // dhr -> Latn
+ case 0xC8E30000u: // dhs -> Latn
+ case 0xD0E30000u: // dhu -> Latn
+ case 0xD4E30000u: // dhv -> Latn
+ case 0xDCE30000u: // dhx -> Latn
+ case 0x81030000u: // dia -> Latn
+ case 0x85030000u: // dib -> Latn
+ case 0x89030000u: // dic -> Latn
+ case 0x8D030000u: // did -> Latn
+ case 0x95030000u: // dif -> Latn
+ case 0x99030000u: // dig -> Latn
+ case 0x9D030000u: // dih -> Latn
+ case 0xA1030000u: // dii -> Latn
+ case 0xA5030000u: // dij -> Latn
+ case 0xAD030000u: // dil -> Latn
+ case 0xB5030000u: // din -> Latn
+ case 0xB9030000u: // dio -> Latn
+ case 0xBD030000u: // dip -> Latn
+ case 0xC5030000u: // dir -> Latn
+ case 0xC9030000u: // dis -> Latn
+ case 0xD1030000u: // diu -> Latn
+ case 0xD9030000u: // diw -> Latn
+ case 0xDD030000u: // dix -> Latn
+ case 0xE1030000u: // diy -> Latn
+ case 0xE5030000u: // diz -> Latn
+ case 0x81230000u: // dja -> Latn
+ case 0x85230000u: // djb -> Latn
+ case 0x89230000u: // djc -> Latn
+ case 0x8D230000u: // djd -> Latn
+ case 0x91230000u: // dje -> Latn
+ case 0x95230000u: // djf -> Latn
+ case 0xA1230000u: // dji -> Latn
+ case 0xA5230000u: // djj -> Latn
+ case 0xA9230000u: // djk -> Latn
+ case 0xB1230000u: // djm -> Latn
+ case 0xB5230000u: // djn -> Latn
+ case 0xB9230000u: // djo -> Latn
+ case 0xC5230000u: // djr -> Latn
+ case 0xD1230000u: // dju -> Latn
+ case 0xD9230000u: // djw -> Latn
+ case 0x99430000u: // dkg -> Latn
+ case 0xA9430000u: // dkk -> Latn
+ case 0xC5430000u: // dkr -> Latn
+ case 0xC9430000u: // dks -> Latn
+ case 0xDD430000u: // dkx -> Latn
+ case 0xB1630000u: // dlm -> Latn
+ case 0xB5630000u: // dln -> Latn
+ case 0x81830000u: // dma -> Latn
+ case 0x85830000u: // dmb -> Latn
+ case 0x89830000u: // dmc -> Latn
+ case 0x8D830000u: // dmd -> Latn
+ case 0x91830000u: // dme -> Latn
+ case 0x99830000u: // dmg -> Latn
+ case 0xB1830000u: // dmm -> Latn
+ case 0xB9830000u: // dmo -> Latn
+ case 0xC5830000u: // dmr -> Latn
+ case 0xC9830000u: // dms -> Latn
+ case 0xD1830000u: // dmu -> Latn
+ case 0xD5830000u: // dmv -> Latn
+ case 0xD9830000u: // dmw -> Latn
+ case 0xDD830000u: // dmx -> Latn
+ case 0xE1830000u: // dmy -> Latn
+ case 0x81A30000u: // dna -> Latn
+ case 0x8DA30000u: // dnd -> Latn
+ case 0x91A30000u: // dne -> Latn
+ case 0xA1A30000u: // dni -> Latn
+ case 0xA5A30000u: // dnj -> Latn
+ case 0xA9A30000u: // dnk -> Latn
+ case 0xB5A30000u: // dnn -> Latn
+ case 0xB9A30000u: // dno -> Latn
+ case 0xC5A30000u: // dnr -> Latn
+ case 0xCDA30000u: // dnt -> Latn
+ case 0xD9A30000u: // dnw -> Latn
+ case 0xE1A30000u: // dny -> Latn
+ case 0x81C30000u: // doa -> Latn
+ case 0x85C30000u: // dob -> Latn
+ case 0x89C30000u: // doc -> Latn
+ case 0x91C30000u: // doe -> Latn
+ case 0x95C30000u: // dof -> Latn
+ case 0x9DC30000u: // doh -> Latn
+ case 0xA9C30000u: // dok -> Latn
+ case 0xADC30000u: // dol -> Latn
+ case 0xB5C30000u: // don -> Latn
+ case 0xB9C30000u: // doo -> Latn
+ case 0xBDC30000u: // dop -> Latn
+ case 0xC5C30000u: // dor -> Latn
+ case 0xC9C30000u: // dos -> Latn
+ case 0xCDC30000u: // dot -> Latn
+ case 0xD5C30000u: // dov -> Latn
+ case 0xD9C30000u: // dow -> Latn
+ case 0xE1C30000u: // doy -> Latn
+ case 0xBDE30000u: // dpp -> Latn
+ case 0x8A230000u: // drc -> Latn
+ case 0x9A230000u: // drg -> Latn
+ case 0xA2230000u: // dri -> Latn
+ case 0xAE230000u: // drl -> Latn
+ case 0xB6230000u: // drn -> Latn
+ case 0xBA230000u: // dro -> Latn
+ case 0xCE230000u: // drt -> Latn
+ case 0xD2230000u: // dru -> Latn
+ case 0x86430000u: // dsb -> Latn
+ case 0x9E430000u: // dsh -> Latn
+ case 0xA2430000u: // dsi -> Latn
+ case 0xAA430000u: // dsk -> Latn
+ case 0xB6430000u: // dsn -> Latn
+ case 0xC2430000u: // dsq -> Latn
+ case 0x82630000u: // dta -> Latn
+ case 0x86630000u: // dtb -> Latn
+ case 0x8E630000u: // dtd -> Latn
+ case 0x9E630000u: // dth -> Latn
+ case 0xA2630000u: // dti -> Latn
+ case 0xAA630000u: // dtk -> Latn
+ case 0xB2630000u: // dtm -> Latn
+ case 0xBA630000u: // dto -> Latn
+ case 0xBE630000u: // dtp -> Latn
+ case 0xC6630000u: // dtr -> Latn
+ case 0xCA630000u: // dts -> Latn
+ case 0xCE630000u: // dtt -> Latn
+ case 0xD2630000u: // dtu -> Latn
+ case 0x82830000u: // dua -> Latn
+ case 0x8A830000u: // duc -> Latn
+ case 0x92830000u: // due -> Latn
+ case 0x96830000u: // duf -> Latn
+ case 0x9A830000u: // dug -> Latn
+ case 0xA2830000u: // dui -> Latn
+ case 0xAA830000u: // duk -> Latn
+ case 0xAE830000u: // dul -> Latn
+ case 0xB2830000u: // dum -> Latn
+ case 0xB6830000u: // dun -> Latn
+ case 0xBA830000u: // duo -> Latn
+ case 0xBE830000u: // dup -> Latn
+ case 0xC2830000u: // duq -> Latn
+ case 0xC6830000u: // dur -> Latn
+ case 0xD2830000u: // duu -> Latn
+ case 0xD6830000u: // duv -> Latn
+ case 0xDA830000u: // duw -> Latn
+ case 0xDE830000u: // dux -> Latn
+ case 0xE2830000u: // duy -> Latn
+ case 0xE6830000u: // duz -> Latn
+ case 0x82A30000u: // dva -> Latn
+ case 0x82C30000u: // dwa -> Latn
+ case 0xC6C30000u: // dwr -> Latn
+ case 0xCAC30000u: // dws -> Latn
+ case 0xD2C30000u: // dwu -> Latn
+ case 0xDAC30000u: // dww -> Latn
+ case 0xE2C30000u: // dwy -> Latn
+ case 0x83030000u: // dya -> Latn
+ case 0x87030000u: // dyb -> Latn
+ case 0x8F030000u: // dyd -> Latn
+ case 0x9B030000u: // dyg -> Latn
+ case 0xA3030000u: // dyi -> Latn
+ case 0xB3030000u: // dym -> Latn
+ case 0xB7030000u: // dyn -> Latn
+ case 0xBB030000u: // dyo -> Latn
+ case 0xC7030000u: // dyr -> Latn
+ case 0xD3030000u: // dyu -> Latn
+ case 0xE3030000u: // dyy -> Latn
+ case 0x83230000u: // dza -> Latn
+ case 0x8F230000u: // dzd -> Latn
+ case 0x93230000u: // dze -> Latn
+ case 0x9B230000u: // dzg -> Latn
+ case 0xB7230000u: // dzn -> Latn
+ case 0x80040000u: // eaa -> Latn
+ case 0x88240000u: // ebc -> Latn
+ case 0x98240000u: // ebg -> Latn
+ case 0xA8240000u: // ebk -> Latn
+ case 0xB8240000u: // ebo -> Latn
+ case 0xC4240000u: // ebr -> Latn
+ case 0xD0240000u: // ebu -> Latn
+ case 0x65650000u: // ee -> Latn
+ case 0x80A40000u: // efa -> Latn
+ case 0x90A40000u: // efe -> Latn
+ case 0xA0A40000u: // efi -> Latn
+ case 0x80C40000u: // ega -> Latn
+ case 0xACC40000u: // egl -> Latn
+ case 0xB0C40000u: // egm -> Latn
+ case 0xB8C40000u: // ego -> Latn
+ case 0xD0E40000u: // ehu -> Latn
+ case 0xBD040000u: // eip -> Latn
+ case 0xCD040000u: // eit -> Latn
+ case 0xD5040000u: // eiv -> Latn
+ case 0x81240000u: // eja -> Latn
+ case 0x81440000u: // eka -> Latn
+ case 0x91440000u: // eke -> Latn
+ case 0x99440000u: // ekg -> Latn
+ case 0xA1440000u: // eki -> Latn
+ case 0xAD440000u: // ekl -> Latn
+ case 0xB1440000u: // ekm -> Latn
+ case 0xB9440000u: // eko -> Latn
+ case 0xBD440000u: // ekp -> Latn
+ case 0xC5440000u: // ekr -> Latn
+ case 0x91640000u: // ele -> Latn
+ case 0xA9640000u: // elk -> Latn
+ case 0xB1640000u: // elm -> Latn
+ case 0xB9640000u: // elo -> Latn
+ case 0xD1640000u: // elu -> Latn
+ case 0x81840000u: // ema -> Latn
+ case 0x85840000u: // emb -> Latn
+ case 0x91840000u: // eme -> Latn
+ case 0xA1840000u: // emi -> Latn
+ case 0xB1840000u: // emm -> Latn
+ case 0xB5840000u: // emn -> Latn
+ case 0xBD840000u: // emp -> Latn
+ case 0xC9840000u: // ems -> Latn
+ case 0xD9840000u: // emw -> Latn
+ case 0xDD840000u: // emx -> Latn
+ case 0xE5840000u: // emz -> Latn
+ case 0x656E0000u: // en -> Latn
+ case 0x81A40000u: // ena -> Latn
+ case 0x85A40000u: // enb -> Latn
+ case 0x89A40000u: // enc -> Latn
+ case 0x8DA40000u: // end -> Latn
+ case 0xADA40000u: // enl -> Latn
+ case 0xB1A40000u: // enm -> Latn
+ case 0xB5A40000u: // enn -> Latn
+ case 0xB9A40000u: // eno -> Latn
+ case 0xC1A40000u: // enq -> Latn
+ case 0xC5A40000u: // enr -> Latn
+ case 0xD5A40000u: // env -> Latn
+ case 0xD9A40000u: // enw -> Latn
+ case 0xDDA40000u: // enx -> Latn
+ case 0x656F0000u: // eo -> Latn
+ case 0xCDC40000u: // eot -> Latn
+ case 0xA1E40000u: // epi -> Latn
+ case 0x9A240000u: // erg -> Latn
+ case 0x9E240000u: // erh -> Latn
+ case 0xA2240000u: // eri -> Latn
+ case 0xAA240000u: // erk -> Latn
+ case 0xC6240000u: // err -> Latn
+ case 0xCA240000u: // ers -> Latn
+ case 0xCE240000u: // ert -> Latn
+ case 0xDA240000u: // erw -> Latn
+ case 0x65730000u: // es -> Latn
+ case 0x92440000u: // ese -> Latn
+ case 0xA2440000u: // esi -> Latn
+ case 0xB2440000u: // esm -> Latn
+ case 0xCA440000u: // ess -> Latn
+ case 0xD2440000u: // esu -> Latn
+ case 0xE2440000u: // esy -> Latn
+ case 0x65740000u: // et -> Latn
+ case 0x86640000u: // etb -> Latn
+ case 0xB6640000u: // etn -> Latn
+ case 0xBA640000u: // eto -> Latn
+ case 0xC6640000u: // etr -> Latn
+ case 0xCA640000u: // ets -> Latn
+ case 0xD2640000u: // etu -> Latn
+ case 0xDE640000u: // etx -> Latn
+ case 0xE6640000u: // etz -> Latn
+ case 0x65750000u: // eu -> Latn
+ case 0x8E840000u: // eud -> Latn
+ case 0x9EA40000u: // evh -> Latn
+ case 0xBAC40000u: // ewo -> Latn
+ case 0xCEE40000u: // ext -> Latn
+ case 0x83040000u: // eya -> Latn
+ case 0xBB040000u: // eyo -> Latn
+ case 0x83240000u: // eza -> Latn
+ case 0x93240000u: // eze -> Latn
+ case 0x80050000u: // faa -> Latn
+ case 0x84050000u: // fab -> Latn
+ case 0x8C050000u: // fad -> Latn
+ case 0x94050000u: // faf -> Latn
+ case 0x98050000u: // fag -> Latn
+ case 0x9C050000u: // fah -> Latn
+ case 0xA0050000u: // fai -> Latn
+ case 0xA4050000u: // faj -> Latn
+ case 0xA8050000u: // fak -> Latn
+ case 0xAC050000u: // fal -> Latn
+ case 0xB0050000u: // fam -> Latn
+ case 0xB4050000u: // fan -> Latn
+ case 0xBC050000u: // fap -> Latn
+ case 0xC4050000u: // far -> Latn
+ case 0xD0050000u: // fau -> Latn
+ case 0xDC050000u: // fax -> Latn
+ case 0xAC250000u: // fbl -> Latn
+ case 0xC4850000u: // fer -> Latn
+ case 0x66660000u: // ff -> Latn
+ case 0xA0A50000u: // ffi -> Latn
+ case 0xB0A50000u: // ffm -> Latn
+ case 0xC4C50000u: // fgr -> Latn
+ case 0x66690000u: // fi -> Latn
+ case 0x91050000u: // fie -> Latn
+ case 0x95050000u: // fif -> Latn
+ case 0xAD050000u: // fil -> Latn
+ case 0xBD050000u: // fip -> Latn
+ case 0xC5050000u: // fir -> Latn
+ case 0xCD050000u: // fit -> Latn
+ case 0xD9050000u: // fiw -> Latn
+ case 0x666A0000u: // fj -> Latn
+ case 0xA9450000u: // fkk -> Latn
+ case 0xD5450000u: // fkv -> Latn
+ case 0x81650000u: // fla -> Latn
+ case 0x9D650000u: // flh -> Latn
+ case 0xA1650000u: // fli -> Latn
+ case 0xAD650000u: // fll -> Latn
+ case 0xB5650000u: // fln -> Latn
+ case 0xC5650000u: // flr -> Latn
+ case 0xE1650000u: // fly -> Latn
+ case 0xBD850000u: // fmp -> Latn
+ case 0x85A50000u: // fnb -> Latn
+ case 0x99A50000u: // fng -> Latn
+ case 0xA1A50000u: // fni -> Latn
+ case 0x666F0000u: // fo -> Latn
+ case 0x8DC50000u: // fod -> Latn
+ case 0xA1C50000u: // foi -> Latn
+ case 0xB1C50000u: // fom -> Latn
+ case 0xB5C50000u: // fon -> Latn
+ case 0xC5C50000u: // for -> Latn
+ case 0xC9C50000u: // fos -> Latn
+ case 0x91E50000u: // fpe -> Latn
+ case 0xCA050000u: // fqs -> Latn
+ case 0x66720000u: // fr -> Latn
+ case 0x8A250000u: // frc -> Latn
+ case 0x8E250000u: // frd -> Latn
+ case 0xAA250000u: // frk -> Latn
+ case 0xB2250000u: // frm -> Latn
+ case 0xBA250000u: // fro -> Latn
+ case 0xBE250000u: // frp -> Latn
+ case 0xC2250000u: // frq -> Latn
+ case 0xC6250000u: // frr -> Latn
+ case 0xCA250000u: // frs -> Latn
+ case 0xCE250000u: // frt -> Latn
+ case 0x8E850000u: // fud -> Latn
+ case 0x92850000u: // fue -> Latn
+ case 0x96850000u: // fuf -> Latn
+ case 0x9E850000u: // fuh -> Latn
+ case 0xA2850000u: // fui -> Latn
+ case 0xB2850000u: // fum -> Latn
+ case 0xB6850000u: // fun -> Latn
+ case 0xC2850000u: // fuq -> Latn
+ case 0xC6850000u: // fur -> Latn
+ case 0xCE850000u: // fut -> Latn
+ case 0xD2850000u: // fuu -> Latn
+ case 0xD6850000u: // fuv -> Latn
+ case 0xE2850000u: // fuy -> Latn
+ case 0xC6A50000u: // fvr -> Latn
+ case 0x82C50000u: // fwa -> Latn
+ case 0x92C50000u: // fwe -> Latn
+ case 0x66790000u: // fy -> Latn
+ case 0x67610000u: // ga -> Latn
+ case 0x80060000u: // gaa -> Latn
+ case 0x84060000u: // gab -> Latn
+ case 0x88060000u: // gac -> Latn
+ case 0x8C060000u: // gad -> Latn
+ case 0x90060000u: // gae -> Latn
+ case 0x94060000u: // gaf -> Latn
+ case 0x98060000u: // gag -> Latn
+ case 0x9C060000u: // gah -> Latn
+ case 0xA0060000u: // gai -> Latn
+ case 0xA4060000u: // gaj -> Latn
+ case 0xA8060000u: // gak -> Latn
+ case 0xAC060000u: // gal -> Latn
+ case 0xB0060000u: // gam -> Latn
+ case 0xB8060000u: // gao -> Latn
+ case 0xBC060000u: // gap -> Latn
+ case 0xC4060000u: // gar -> Latn
+ case 0xCC060000u: // gat -> Latn
+ case 0xD8060000u: // gaw -> Latn
+ case 0xDC060000u: // gax -> Latn
+ case 0xE0060000u: // gay -> Latn
+ case 0x80260000u: // gba -> Latn
+ case 0x84260000u: // gbb -> Latn
+ case 0x8C260000u: // gbd -> Latn
+ case 0x90260000u: // gbe -> Latn
+ case 0x94260000u: // gbf -> Latn
+ case 0x98260000u: // gbg -> Latn
+ case 0x9C260000u: // gbh -> Latn
+ case 0xA0260000u: // gbi -> Latn
+ case 0xB4260000u: // gbn -> Latn
+ case 0xBC260000u: // gbp -> Latn
+ case 0xC0260000u: // gbq -> Latn
+ case 0xC4260000u: // gbr -> Latn
+ case 0xC8260000u: // gbs -> Latn
+ case 0xD0260000u: // gbu -> Latn
+ case 0xD4260000u: // gbv -> Latn
+ case 0xD8260000u: // gbw -> Latn
+ case 0xDC260000u: // gbx -> Latn
+ case 0xE0260000u: // gby -> Latn
+ case 0x88460000u: // gcc -> Latn
+ case 0x8C460000u: // gcd -> Latn
+ case 0x94460000u: // gcf -> Latn
+ case 0xAC460000u: // gcl -> Latn
+ case 0xB4460000u: // gcn -> Latn
+ case 0xC4460000u: // gcr -> Latn
+ case 0xCC460000u: // gct -> Latn
+ case 0x67640000u: // gd -> Latn
+ case 0x88660000u: // gdc -> Latn
+ case 0x8C660000u: // gdd -> Latn
+ case 0x90660000u: // gde -> Latn
+ case 0x94660000u: // gdf -> Latn
+ case 0x98660000u: // gdg -> Latn
+ case 0x9C660000u: // gdh -> Latn
+ case 0xA0660000u: // gdi -> Latn
+ case 0xA4660000u: // gdj -> Latn
+ case 0xA8660000u: // gdk -> Latn
+ case 0xAC660000u: // gdl -> Latn
+ case 0xB0660000u: // gdm -> Latn
+ case 0xB4660000u: // gdn -> Latn
+ case 0xC0660000u: // gdq -> Latn
+ case 0xC4660000u: // gdr -> Latn
+ case 0xCC660000u: // gdt -> Latn
+ case 0xD0660000u: // gdu -> Latn
+ case 0x80860000u: // gea -> Latn
+ case 0x84860000u: // geb -> Latn
+ case 0x88860000u: // gec -> Latn
+ case 0x8C860000u: // ged -> Latn
+ case 0x94860000u: // gef -> Latn
+ case 0x98860000u: // geg -> Latn
+ case 0x9C860000u: // geh -> Latn
+ case 0xA0860000u: // gei -> Latn
+ case 0xA4860000u: // gej -> Latn
+ case 0xA8860000u: // gek -> Latn
+ case 0xAC860000u: // gel -> Latn
+ case 0xC0860000u: // geq -> Latn
+ case 0xC8860000u: // ges -> Latn
+ case 0xD4860000u: // gev -> Latn
+ case 0xD8860000u: // gew -> Latn
+ case 0xDC860000u: // gex -> Latn
+ case 0xE0860000u: // gey -> Latn
+ case 0xA8A60000u: // gfk -> Latn
+ case 0x80C60000u: // gga -> Latn
+ case 0x84C60000u: // ggb -> Latn
+ case 0x8CC60000u: // ggd -> Latn
+ case 0x90C60000u: // gge -> Latn
+ case 0xA8C60000u: // ggk -> Latn
+ case 0xACC60000u: // ggl -> Latn
+ case 0xCCC60000u: // ggt -> Latn
+ case 0xD0C60000u: // ggu -> Latn
+ case 0xD8C60000u: // ggw -> Latn
+ case 0x88E60000u: // ghc -> Latn
+ case 0xA8E60000u: // ghk -> Latn
+ case 0xB4E60000u: // ghn -> Latn
+ case 0xC8E60000u: // ghs -> Latn
+ case 0x81060000u: // gia -> Latn
+ case 0x85060000u: // gib -> Latn
+ case 0x89060000u: // gic -> Latn
+ case 0x8D060000u: // gid -> Latn
+ case 0x91060000u: // gie -> Latn
+ case 0x9D060000u: // gih -> Latn
+ case 0xAD060000u: // gil -> Latn
+ case 0xB1060000u: // gim -> Latn
+ case 0xBD060000u: // gip -> Latn
+ case 0xC1060000u: // giq -> Latn
+ case 0xC5060000u: // gir -> Latn
+ case 0xC9060000u: // gis -> Latn
+ case 0xCD060000u: // git -> Latn
+ case 0xDD060000u: // gix -> Latn
+ case 0xE1060000u: // giy -> Latn
+ case 0xE5060000u: // giz -> Latn
+ case 0xB1260000u: // gjm -> Latn
+ case 0xB5260000u: // gjn -> Latn
+ case 0xC5260000u: // gjr -> Latn
+ case 0x81460000u: // gka -> Latn
+ case 0x8D460000u: // gkd -> Latn
+ case 0x91460000u: // gke -> Latn
+ case 0xB5460000u: // gkn -> Latn
+ case 0xB9460000u: // gko -> Latn
+ case 0xBD460000u: // gkp -> Latn
+ case 0xD1460000u: // gku -> Latn
+ case 0x676C0000u: // gl -> Latn
+ case 0x85660000u: // glb -> Latn
+ case 0x89660000u: // glc -> Latn
+ case 0xA5660000u: // glj -> Latn
+ case 0xAD660000u: // gll -> Latn
+ case 0xB9660000u: // glo -> Latn
+ case 0xC5660000u: // glr -> Latn
+ case 0xD1660000u: // glu -> Latn
+ case 0xD9660000u: // glw -> Latn
+ case 0x81860000u: // gma -> Latn
+ case 0x85860000u: // gmb -> Latn
+ case 0x8D860000u: // gmd -> Latn
+ case 0x99860000u: // gmg -> Latn
+ case 0x9D860000u: // gmh -> Latn
+ case 0xB1860000u: // gmm -> Latn
+ case 0xB5860000u: // gmn -> Latn
+ case 0xC5860000u: // gmr -> Latn
+ case 0xD1860000u: // gmu -> Latn
+ case 0xDD860000u: // gmx -> Latn
+ case 0xE5860000u: // gmz -> Latn
+ case 0x676E0000u: // gn -> Latn
+ case 0x81A60000u: // gna -> Latn
+ case 0x85A60000u: // gnb -> Latn
+ case 0x89A60000u: // gnc -> Latn
+ case 0x8DA60000u: // gnd -> Latn
+ case 0x91A60000u: // gne -> Latn
+ case 0x99A60000u: // gng -> Latn
+ case 0x9DA60000u: // gnh -> Latn
+ case 0xA1A60000u: // gni -> Latn
+ case 0xA5A60000u: // gnj -> Latn
+ case 0xA9A60000u: // gnk -> Latn
+ case 0xADA60000u: // gnl -> Latn
+ case 0xB1A60000u: // gnm -> Latn
+ case 0xB5A60000u: // gnn -> Latn
+ case 0xC1A60000u: // gnq -> Latn
+ case 0xC5A60000u: // gnr -> Latn
+ case 0xCDA60000u: // gnt -> Latn
+ case 0xD1A60000u: // gnu -> Latn
+ case 0xD9A60000u: // gnw -> Latn
+ case 0xE5A60000u: // gnz -> Latn
+ case 0x81C60000u: // goa -> Latn
+ case 0x85C60000u: // gob -> Latn
+ case 0x89C60000u: // goc -> Latn
+ case 0x8DC60000u: // god -> Latn
+ case 0x99C60000u: // gog -> Latn
+ case 0x9DC60000u: // goh -> Latn
+ case 0xA1C60000u: // goi -> Latn
+ case 0xADC60000u: // gol -> Latn
+ case 0xB9C60000u: // goo -> Latn
+ case 0xBDC60000u: // gop -> Latn
+ case 0xC1C60000u: // goq -> Latn
+ case 0xC5C60000u: // gor -> Latn
+ case 0xC9C60000u: // gos -> Latn
+ case 0xD1C60000u: // gou -> Latn
+ case 0xD5C60000u: // gov -> Latn
+ case 0xD9C60000u: // gow -> Latn
+ case 0xDDC60000u: // gox -> Latn
+ case 0xE1C60000u: // goy -> Latn
+ case 0x81E60000u: // gpa -> Latn
+ case 0x91E60000u: // gpe -> Latn
+ case 0xB5E60000u: // gpn -> Latn
+ case 0x82060000u: // gqa -> Latn
+ case 0xB6060000u: // gqn -> Latn
+ case 0xC6060000u: // gqr -> Latn
+ case 0x86260000u: // grb -> Latn
+ case 0x8E260000u: // grd -> Latn
+ case 0x9A260000u: // grg -> Latn
+ case 0x9E260000u: // grh -> Latn
+ case 0xA2260000u: // gri -> Latn
+ case 0xA6260000u: // grj -> Latn
+ case 0xB2260000u: // grm -> Latn
+ case 0xC2260000u: // grq -> Latn
+ case 0xCA260000u: // grs -> Latn
+ case 0xD6260000u: // grv -> Latn
+ case 0xDA260000u: // grw -> Latn
+ case 0xDE260000u: // grx -> Latn
+ case 0xE2260000u: // gry -> Latn
+ case 0xE6260000u: // grz -> Latn
+ case 0xAE460000u: // gsl -> Latn
+ case 0xB6460000u: // gsn -> Latn
+ case 0xBA460000u: // gso -> Latn
+ case 0xBE460000u: // gsp -> Latn
+ case 0xDA460000u: // gsw -> Latn
+ case 0x82660000u: // gta -> Latn
+ case 0xD2660000u: // gtu -> Latn
+ case 0x82860000u: // gua -> Latn
+ case 0x86860000u: // gub -> Latn
+ case 0x8A860000u: // guc -> Latn
+ case 0x8E860000u: // gud -> Latn
+ case 0x92860000u: // gue -> Latn
+ case 0x96860000u: // guf -> Latn
+ case 0x9E860000u: // guh -> Latn
+ case 0xA2860000u: // gui -> Latn
+ case 0xAA860000u: // guk -> Latn
+ case 0xAE860000u: // gul -> Latn
+ case 0xB2860000u: // gum -> Latn
+ case 0xB6860000u: // gun -> Latn
+ case 0xBA860000u: // guo -> Latn
+ case 0xBE860000u: // gup -> Latn
+ case 0xC2860000u: // guq -> Latn
+ case 0xC6860000u: // gur -> Latn
+ case 0xCE860000u: // gut -> Latn
+ case 0xD2860000u: // guu -> Latn
+ case 0xDA860000u: // guw -> Latn
+ case 0xDE860000u: // gux -> Latn
+ case 0xE6860000u: // guz -> Latn
+ case 0x67760000u: // gv -> Latn
+ case 0x82A60000u: // gva -> Latn
+ case 0x8AA60000u: // gvc -> Latn
+ case 0x92A60000u: // gve -> Latn
+ case 0x96A60000u: // gvf -> Latn
+ case 0xA6A60000u: // gvj -> Latn
+ case 0xAEA60000u: // gvl -> Latn
+ case 0xB2A60000u: // gvm -> Latn
+ case 0xB6A60000u: // gvn -> Latn
+ case 0xBAA60000u: // gvo -> Latn
+ case 0xBEA60000u: // gvp -> Latn
+ case 0xCAA60000u: // gvs -> Latn
+ case 0xE2A60000u: // gvy -> Latn
+ case 0x82C60000u: // gwa -> Latn
+ case 0x86C60000u: // gwb -> Latn
+ case 0x8EC60000u: // gwd -> Latn
+ case 0x92C60000u: // gwe -> Latn
+ case 0x9AC60000u: // gwg -> Latn
+ case 0xA2C60000u: // gwi -> Latn
+ case 0xA6C60000u: // gwj -> Latn
+ case 0xB2C60000u: // gwm -> Latn
+ case 0xB6C60000u: // gwn -> Latn
+ case 0xC6C60000u: // gwr -> Latn
+ case 0xD2C60000u: // gwu -> Latn
+ case 0xDAC60000u: // gww -> Latn
+ case 0xDEC60000u: // gwx -> Latn
+ case 0xDEE60000u: // gxx -> Latn
+ case 0x87060000u: // gyb -> Latn
+ case 0x8F060000u: // gyd -> Latn
+ case 0x93060000u: // gye -> Latn
+ case 0x97060000u: // gyf -> Latn
+ case 0x9B060000u: // gyg -> Latn
+ case 0xA3060000u: // gyi -> Latn
+ case 0xAF060000u: // gyl -> Latn
+ case 0xB3060000u: // gym -> Latn
+ case 0xB7060000u: // gyn -> Latn
+ case 0xC7060000u: // gyr -> Latn
+ case 0xE3060000u: // gyy -> Latn
+ case 0xE7060000u: // gyz -> Latn
+ case 0x83260000u: // gza -> Latn
+ case 0xB7260000u: // gzn -> Latn
+ case 0x68610000u: // ha -> Latn
+ case 0x80070000u: // haa -> Latn
+ case 0x8C070000u: // had -> Latn
+ case 0x90070000u: // hae -> Latn
+ case 0x98070000u: // hag -> Latn
+ case 0x9C070000u: // hah -> Latn
+ case 0xA0070000u: // hai -> Latn
+ case 0xA4070000u: // haj -> Latn
+ case 0xAC070000u: // hal -> Latn
+ case 0xB0070000u: // ham -> Latn
+ case 0xB4070000u: // han -> Latn
+ case 0xB8070000u: // hao -> Latn
+ case 0xBC070000u: // hap -> Latn
+ case 0xC0070000u: // haq -> Latn
+ case 0xC8070000u: // has -> Latn
+ case 0xD4070000u: // hav -> Latn
+ case 0xD8070000u: // haw -> Latn
+ case 0xDC070000u: // hax -> Latn
+ case 0xE0070000u: // hay -> Latn
+ case 0x80270000u: // hba -> Latn
+ case 0x84270000u: // hbb -> Latn
+ case 0xB4270000u: // hbn -> Latn
+ case 0xD0270000u: // hbu -> Latn
+ case 0x9C470000u: // hch -> Latn
+ case 0x8C870000u: // hed -> Latn
+ case 0x98870000u: // heg -> Latn
+ case 0x9C870000u: // heh -> Latn
+ case 0xA0870000u: // hei -> Latn
+ case 0xB0870000u: // hem -> Latn
+ case 0xB0C70000u: // hgm -> Latn
+ case 0xD8C70000u: // hgw -> Latn
+ case 0xA0E70000u: // hhi -> Latn
+ case 0xC4E70000u: // hhr -> Latn
+ case 0xE0E70000u: // hhy -> Latn
+ case 0x81070000u: // hia -> Latn
+ case 0x85070000u: // hib -> Latn
+ case 0x8D070000u: // hid -> Latn
+ case 0x99070000u: // hig -> Latn
+ case 0x9D070000u: // hih -> Latn
+ case 0xA5070000u: // hij -> Latn
+ case 0xA9070000u: // hik -> Latn
+ case 0xAD070000u: // hil -> Latn
+ case 0xB9070000u: // hio -> Latn
+ case 0xC5070000u: // hir -> Latn
+ case 0xD9070000u: // hiw -> Latn
+ case 0xDD070000u: // hix -> Latn
+ case 0xA1270000u: // hji -> Latn
+ case 0x81470000u: // hka -> Latn
+ case 0x91470000u: // hke -> Latn
+ case 0xA9470000u: // hkk -> Latn
+ case 0x81670000u: // hla -> Latn
+ case 0x8D670000u: // hld -> Latn
+ case 0xCD670000u: // hlt -> Latn
+ case 0x81870000u: // hma -> Latn
+ case 0x85870000u: // hmb -> Latn
+ case 0x95870000u: // hmf -> Latn
+ case 0xB1870000u: // hmm -> Latn
+ case 0xB5870000u: // hmn -> Latn
+ case 0xBD870000u: // hmp -> Latn
+ case 0xC5870000u: // hmr -> Latn
+ case 0xC9870000u: // hms -> Latn
+ case 0xCD870000u: // hmt -> Latn
+ case 0xD1870000u: // hmu -> Latn
+ case 0xD5870000u: // hmv -> Latn
+ case 0xD9870000u: // hmw -> Latn
+ case 0xE1870000u: // hmy -> Latn
+ case 0xE5870000u: // hmz -> Latn
+ case 0x81A70000u: // hna -> Latn
+ case 0x99A70000u: // hng -> Latn
+ case 0x9DA70000u: // hnh -> Latn
+ case 0xA1A70000u: // hni -> Latn
+ case 0xB5A70000u: // hnn -> Latn
+ case 0xC9A70000u: // hns -> Latn
+ case 0x686F0000u: // ho -> Latn
+ case 0x81C70000u: // hoa -> Latn
+ case 0x85C70000u: // hob -> Latn
+ case 0x8DC70000u: // hod -> Latn
+ case 0x91C70000u: // hoe -> Latn
+ case 0xA1C70000u: // hoi -> Latn
+ case 0xADC70000u: // hol -> Latn
+ case 0xB1C70000u: // hom -> Latn
+ case 0xB9C70000u: // hoo -> Latn
+ case 0xBDC70000u: // hop -> Latn
+ case 0xC5C70000u: // hor -> Latn
+ case 0xCDC70000u: // hot -> Latn
+ case 0xD5C70000u: // hov -> Latn
+ case 0x68720000u: // hr -> Latn
+ case 0x82270000u: // hra -> Latn
+ case 0x8A270000u: // hrc -> Latn
+ case 0x92270000u: // hre -> Latn
+ case 0xAA270000u: // hrk -> Latn
+ case 0xB2270000u: // hrm -> Latn
+ case 0xBA270000u: // hro -> Latn
+ case 0xBE270000u: // hrp -> Latn
+ case 0xD2270000u: // hru -> Latn
+ case 0xDA270000u: // hrw -> Latn
+ case 0xDE270000u: // hrx -> Latn
+ case 0x86470000u: // hsb -> Latn
+ case 0x68740000u: // ht -> Latn
+ case 0xA2670000u: // hti -> Latn
+ case 0xBA670000u: // hto -> Latn
+ case 0xCA670000u: // hts -> Latn
+ case 0xD2670000u: // htu -> Latn
+ case 0x68750000u: // hu -> Latn
+ case 0x86870000u: // hub -> Latn
+ case 0x8A870000u: // huc -> Latn
+ case 0x8E870000u: // hud -> Latn
+ case 0x92870000u: // hue -> Latn
+ case 0x96870000u: // huf -> Latn
+ case 0x9A870000u: // hug -> Latn
+ case 0x9E870000u: // huh -> Latn
+ case 0xA2870000u: // hui -> Latn
+ case 0xAA870000u: // huk -> Latn
+ case 0xAE870000u: // hul -> Latn
+ case 0xB2870000u: // hum -> Latn
+ case 0xBE870000u: // hup -> Latn
+ case 0xC6870000u: // hur -> Latn
+ case 0xCA870000u: // hus -> Latn
+ case 0xD2870000u: // huu -> Latn
+ case 0xD6870000u: // huv -> Latn
+ case 0xDA870000u: // huw -> Latn
+ case 0xDE870000u: // hux -> Latn
+ case 0x8AA70000u: // hvc -> Latn
+ case 0x92A70000u: // hve -> Latn
+ case 0xAAA70000u: // hvk -> Latn
+ case 0xB6A70000u: // hvn -> Latn
+ case 0xD6A70000u: // hvv -> Latn
+ case 0x82C70000u: // hwa -> Latn
+ case 0x8AC70000u: // hwc -> Latn
+ case 0xBAC70000u: // hwo -> Latn
+ case 0x83070000u: // hya -> Latn
+ case 0x687A0000u: // hz -> Latn
+ case 0x69610000u: // ia -> Latn
+ case 0xA0080000u: // iai -> Latn
+ case 0xB4080000u: // ian -> Latn
+ case 0xC4080000u: // iar -> Latn
+ case 0x80280000u: // iba -> Latn
+ case 0x84280000u: // ibb -> Latn
+ case 0x8C280000u: // ibd -> Latn
+ case 0x90280000u: // ibe -> Latn
+ case 0x98280000u: // ibg -> Latn
+ case 0x9C280000u: // ibh -> Latn
+ case 0xAC280000u: // ibl -> Latn
+ case 0xB0280000u: // ibm -> Latn
+ case 0xB4280000u: // ibn -> Latn
+ case 0xC4280000u: // ibr -> Latn
+ case 0xD0280000u: // ibu -> Latn
+ case 0xE0280000u: // iby -> Latn
+ case 0x80480000u: // ica -> Latn
+ case 0x9C480000u: // ich -> Latn
+ case 0xC4480000u: // icr -> Latn
+ case 0x69640000u: // id -> Latn
+ case 0x80680000u: // ida -> Latn
+ case 0x84680000u: // idb -> Latn
+ case 0x88680000u: // idc -> Latn
+ case 0x8C680000u: // idd -> Latn
+ case 0x90680000u: // ide -> Latn
+ case 0xA0680000u: // idi -> Latn
+ case 0xC4680000u: // idr -> Latn
+ case 0xC8680000u: // ids -> Latn
+ case 0xCC680000u: // idt -> Latn
+ case 0xD0680000u: // idu -> Latn
+ case 0x69650000u: // ie -> Latn
+ case 0x80A80000u: // ifa -> Latn
+ case 0x84A80000u: // ifb -> Latn
+ case 0x90A80000u: // ife -> Latn
+ case 0x94A80000u: // iff -> Latn
+ case 0xA8A80000u: // ifk -> Latn
+ case 0xB0A80000u: // ifm -> Latn
+ case 0xD0A80000u: // ifu -> Latn
+ case 0xE0A80000u: // ify -> Latn
+ case 0x69670000u: // ig -> Latn
+ case 0x84C80000u: // igb -> Latn
+ case 0x90C80000u: // ige -> Latn
+ case 0x98C80000u: // igg -> Latn
+ case 0xACC80000u: // igl -> Latn
+ case 0xB0C80000u: // igm -> Latn
+ case 0xB4C80000u: // ign -> Latn
+ case 0xB8C80000u: // igo -> Latn
+ case 0xC8C80000u: // igs -> Latn
+ case 0xD8C80000u: // igw -> Latn
+ case 0x84E80000u: // ihb -> Latn
+ case 0xA0E80000u: // ihi -> Latn
+ case 0xBCE80000u: // ihp -> Latn
+ case 0xD8E80000u: // ihw -> Latn
+ case 0xB5080000u: // iin -> Latn
+ case 0x89280000u: // ijc -> Latn
+ case 0x91280000u: // ije -> Latn
+ case 0xA5280000u: // ijj -> Latn
+ case 0xB5280000u: // ijn -> Latn
+ case 0xC9280000u: // ijs -> Latn
+ case 0x696B0000u: // ik -> Latn
+ case 0x9D480000u: // ikh -> Latn
+ case 0xA1480000u: // iki -> Latn
+ case 0xA9480000u: // ikk -> Latn
+ case 0xAD480000u: // ikl -> Latn
+ case 0xB9480000u: // iko -> Latn
+ case 0xBD480000u: // ikp -> Latn
+ case 0xC5480000u: // ikr -> Latn
+ case 0xCD480000u: // ikt -> Latn
+ case 0xD5480000u: // ikv -> Latn
+ case 0xD9480000u: // ikw -> Latn
+ case 0xDD480000u: // ikx -> Latn
+ case 0xE5480000u: // ikz -> Latn
+ case 0x81680000u: // ila -> Latn
+ case 0x85680000u: // ilb -> Latn
+ case 0x99680000u: // ilg -> Latn
+ case 0xA1680000u: // ili -> Latn
+ case 0xA9680000u: // ilk -> Latn
+ case 0xB1680000u: // ilm -> Latn
+ case 0xB9680000u: // ilo -> Latn
+ case 0xBD680000u: // ilp -> Latn
+ case 0xD1680000u: // ilu -> Latn
+ case 0xD5680000u: // ilv -> Latn
+ case 0xA1880000u: // imi -> Latn
+ case 0xAD880000u: // iml -> Latn
+ case 0xB5880000u: // imn -> Latn
+ case 0xB9880000u: // imo -> Latn
+ case 0xC5880000u: // imr -> Latn
+ case 0xC9880000u: // ims -> Latn
+ case 0xCD880000u: // imt -> Latn
+ case 0x696E0000u: // in -> Latn
+ case 0x85A80000u: // inb -> Latn
+ case 0x99A80000u: // ing -> Latn
+ case 0xA5A80000u: // inj -> Latn
+ case 0xB5A80000u: // inn -> Latn
+ case 0xB9A80000u: // ino -> Latn
+ case 0xBDA80000u: // inp -> Latn
+ case 0x696F0000u: // io -> Latn
+ case 0xD1C80000u: // iou -> Latn
+ case 0xD9C80000u: // iow -> Latn
+ case 0xA1E80000u: // ipi -> Latn
+ case 0xB9E80000u: // ipo -> Latn
+ case 0xD2080000u: // iqu -> Latn
+ case 0xDA080000u: // iqw -> Latn
+ case 0x92280000u: // ire -> Latn
+ case 0x9E280000u: // irh -> Latn
+ case 0xA2280000u: // iri -> Latn
+ case 0xAA280000u: // irk -> Latn
+ case 0xB6280000u: // irn -> Latn
+ case 0xDE280000u: // irx -> Latn
+ case 0xE2280000u: // iry -> Latn
+ case 0x69730000u: // is -> Latn
+ case 0x82480000u: // isa -> Latn
+ case 0x8A480000u: // isc -> Latn
+ case 0x8E480000u: // isd -> Latn
+ case 0x9E480000u: // ish -> Latn
+ case 0xA2480000u: // isi -> Latn
+ case 0xB2480000u: // ism -> Latn
+ case 0xB6480000u: // isn -> Latn
+ case 0xBA480000u: // iso -> Latn
+ case 0xCE480000u: // ist -> Latn
+ case 0xD2480000u: // isu -> Latn
+ case 0x69740000u: // it -> Latn
+ case 0x86680000u: // itb -> Latn
+ case 0x8E680000u: // itd -> Latn
+ case 0x92680000u: // ite -> Latn
+ case 0xA2680000u: // iti -> Latn
+ case 0xB2680000u: // itm -> Latn
+ case 0xBA680000u: // ito -> Latn
+ case 0xC6680000u: // itr -> Latn
+ case 0xCA680000u: // its -> Latn
+ case 0xCE680000u: // itt -> Latn
+ case 0xD6680000u: // itv -> Latn
+ case 0xDA680000u: // itw -> Latn
+ case 0xDE680000u: // itx -> Latn
+ case 0xE2680000u: // ity -> Latn
+ case 0xE6680000u: // itz -> Latn
+ case 0xB2880000u: // ium -> Latn
+ case 0x86A80000u: // ivb -> Latn
+ case 0xD6A80000u: // ivv -> Latn
+ case 0xAAC80000u: // iwk -> Latn
+ case 0xB2C80000u: // iwm -> Latn
+ case 0xBAC80000u: // iwo -> Latn
+ case 0xCAC80000u: // iws -> Latn
+ case 0x8AE80000u: // ixc -> Latn
+ case 0xAEE80000u: // ixl -> Latn
+ case 0x83080000u: // iya -> Latn
+ case 0xBB080000u: // iyo -> Latn
+ case 0xDF080000u: // iyx -> Latn
+ case 0x9F280000u: // izh -> Latn
+ case 0xB3280000u: // izm -> Latn
+ case 0xC7280000u: // izr -> Latn
+ case 0xE7280000u: // izz -> Latn
+ case 0x80090000u: // jaa -> Latn
+ case 0x84090000u: // jab -> Latn
+ case 0x88090000u: // jac -> Latn
+ case 0x90090000u: // jae -> Latn
+ case 0x94090000u: // jaf -> Latn
+ case 0x9C090000u: // jah -> Latn
+ case 0xA4090000u: // jaj -> Latn
+ case 0xA8090000u: // jak -> Latn
+ case 0xAC090000u: // jal -> Latn
+ case 0xB0090000u: // jam -> Latn
+ case 0xB4090000u: // jan -> Latn
+ case 0xB8090000u: // jao -> Latn
+ case 0xC0090000u: // jaq -> Latn
+ case 0xC8090000u: // jas -> Latn
+ case 0xD0090000u: // jau -> Latn
+ case 0xDC090000u: // jax -> Latn
+ case 0xE0090000u: // jay -> Latn
+ case 0xE4090000u: // jaz -> Latn
+ case 0xA0290000u: // jbi -> Latn
+ case 0xA4290000u: // jbj -> Latn
+ case 0xA8290000u: // jbk -> Latn
+ case 0xB0290000u: // jbm -> Latn
+ case 0xB8290000u: // jbo -> Latn
+ case 0xC4290000u: // jbr -> Latn
+ case 0xCC290000u: // jbt -> Latn
+ case 0xD0290000u: // jbu -> Latn
+ case 0xD8290000u: // jbw -> Latn
+ case 0x84890000u: // jeb -> Latn
+ case 0x9C890000u: // jeh -> Latn
+ case 0xA0890000u: // jei -> Latn
+ case 0xA8890000u: // jek -> Latn
+ case 0xAC890000u: // jel -> Latn
+ case 0xB4890000u: // jen -> Latn
+ case 0xC4890000u: // jer -> Latn
+ case 0xCC890000u: // jet -> Latn
+ case 0xD0890000u: // jeu -> Latn
+ case 0x84C90000u: // jgb -> Latn
+ case 0xA8C90000u: // jgk -> Latn
+ case 0xB8C90000u: // jgo -> Latn
+ case 0xA0E90000u: // jhi -> Latn
+ case 0x81090000u: // jia -> Latn
+ case 0x85090000u: // jib -> Latn
+ case 0x89090000u: // jic -> Latn
+ case 0x8D090000u: // jid -> Latn
+ case 0x91090000u: // jie -> Latn
+ case 0x99090000u: // jig -> Latn
+ case 0xAD090000u: // jil -> Latn
+ case 0xB1090000u: // jim -> Latn
+ case 0xCD090000u: // jit -> Latn
+ case 0xD1090000u: // jiu -> Latn
+ case 0xD5090000u: // jiv -> Latn
+ case 0xE1090000u: // jiy -> Latn
+ case 0xC5290000u: // jjr -> Latn
+ case 0x81490000u: // jka -> Latn
+ case 0xB9490000u: // jko -> Latn
+ case 0xD1490000u: // jku -> Latn
+ case 0x91690000u: // jle -> Latn
+ case 0x81890000u: // jma -> Latn
+ case 0x85890000u: // jmb -> Latn
+ case 0x89890000u: // jmc -> Latn
+ case 0x8D890000u: // jmd -> Latn
+ case 0xA1890000u: // jmi -> Latn
+ case 0xB5890000u: // jmn -> Latn
+ case 0xC5890000u: // jmr -> Latn
+ case 0xC9890000u: // jms -> Latn
+ case 0xD9890000u: // jmw -> Latn
+ case 0xDD890000u: // jmx -> Latn
+ case 0x99A90000u: // jng -> Latn
+ case 0xA1A90000u: // jni -> Latn
+ case 0xA5A90000u: // jnj -> Latn
+ case 0x85C90000u: // job -> Latn
+ case 0x8DC90000u: // jod -> Latn
+ case 0xC5C90000u: // jor -> Latn
+ case 0xD9C90000u: // jow -> Latn
+ case 0xC6090000u: // jqr -> Latn
+ case 0x82290000u: // jra -> Latn
+ case 0xC6290000u: // jrr -> Latn
+ case 0xCE290000u: // jrt -> Latn
+ case 0xD2290000u: // jru -> Latn
+ case 0x82890000u: // jua -> Latn
+ case 0x86890000u: // jub -> Latn
+ case 0x8E890000u: // jud -> Latn
+ case 0x9E890000u: // juh -> Latn
+ case 0xA2890000u: // jui -> Latn
+ case 0xAA890000u: // juk -> Latn
+ case 0xB2890000u: // jum -> Latn
+ case 0xBA890000u: // juo -> Latn
+ case 0xBE890000u: // jup -> Latn
+ case 0xC6890000u: // jur -> Latn
+ case 0xCE890000u: // jut -> Latn
+ case 0xD2890000u: // juu -> Latn
+ case 0xDA890000u: // juw -> Latn
+ case 0x6A760000u: // jv -> Latn
+ case 0x8EA90000u: // jvd -> Latn
+ case 0xB6A90000u: // jvn -> Latn
+ case 0x6A770000u: // jw -> Latn
+ case 0xA2C90000u: // jwi -> Latn
+ case 0xE3090000u: // jyy -> Latn
+ case 0x840A0000u: // kab -> Latn
+ case 0x880A0000u: // kac -> Latn
+ case 0x8C0A0000u: // kad -> Latn
+ case 0x980A0000u: // kag -> Latn
+ case 0x9C0A0000u: // kah -> Latn
+ case 0xA00A0000u: // kai -> Latn
+ case 0xA40A0000u: // kaj -> Latn
+ case 0xA80A0000u: // kak -> Latn
+ case 0xB00A0000u: // kam -> Latn
+ case 0xB80A0000u: // kao -> Latn
+ case 0xC00A0000u: // kaq -> Latn
+ case 0xD40A0000u: // kav -> Latn
+ case 0xDC0A0000u: // kax -> Latn
+ case 0xE00A0000u: // kay -> Latn
+ case 0x802A0000u: // kba -> Latn
+ case 0x842A0000u: // kbb -> Latn
+ case 0x882A0000u: // kbc -> Latn
+ case 0x902A0000u: // kbe -> Latn
+ case 0x9C2A0000u: // kbh -> Latn
+ case 0xA02A0000u: // kbi -> Latn
+ case 0xA42A0000u: // kbj -> Latn
+ case 0xA82A0000u: // kbk -> Latn
+ case 0xAC2A0000u: // kbl -> Latn
+ case 0xB02A0000u: // kbm -> Latn
+ case 0xB42A0000u: // kbn -> Latn
+ case 0xB82A0000u: // kbo -> Latn
+ case 0xBC2A0000u: // kbp -> Latn
+ case 0xC02A0000u: // kbq -> Latn
+ case 0xC42A0000u: // kbr -> Latn
+ case 0xC82A0000u: // kbs -> Latn
+ case 0xCC2A0000u: // kbt -> Latn
+ case 0xD42A0000u: // kbv -> Latn
+ case 0xD82A0000u: // kbw -> Latn
+ case 0xDC2A0000u: // kbx -> Latn
+ case 0xE42A0000u: // kbz -> Latn
+ case 0x844A0000u: // kcb -> Latn
+ case 0x884A0000u: // kcc -> Latn
+ case 0x8C4A0000u: // kcd -> Latn
+ case 0x904A0000u: // kce -> Latn
+ case 0x944A0000u: // kcf -> Latn
+ case 0x984A0000u: // kcg -> Latn
+ case 0x9C4A0000u: // kch -> Latn
+ case 0xA04A0000u: // kci -> Latn
+ case 0xA44A0000u: // kcj -> Latn
+ case 0xA84A0000u: // kck -> Latn
+ case 0xAC4A0000u: // kcl -> Latn
+ case 0xB04A0000u: // kcm -> Latn
+ case 0xB44A0000u: // kcn -> Latn
+ case 0xB84A0000u: // kco -> Latn
+ case 0xBC4A0000u: // kcp -> Latn
+ case 0xC04A0000u: // kcq -> Latn
+ case 0xC84A0000u: // kcs -> Latn
+ case 0xCC4A0000u: // kct -> Latn
+ case 0xD04A0000u: // kcu -> Latn
+ case 0xD44A0000u: // kcv -> Latn
+ case 0xD84A0000u: // kcw -> Latn
+ case 0xE44A0000u: // kcz -> Latn
+ case 0x806A0000u: // kda -> Latn
+ case 0x886A0000u: // kdc -> Latn
+ case 0x8C6A0000u: // kdd -> Latn
+ case 0x906A0000u: // kde -> Latn
+ case 0x946A0000u: // kdf -> Latn
+ case 0x986A0000u: // kdg -> Latn
+ case 0x9C6A0000u: // kdh -> Latn
+ case 0xA06A0000u: // kdi -> Latn
+ case 0xA46A0000u: // kdj -> Latn
+ case 0xA86A0000u: // kdk -> Latn
+ case 0xAC6A0000u: // kdl -> Latn
+ case 0xB06A0000u: // kdm -> Latn
+ case 0xB46A0000u: // kdn -> Latn
+ case 0xBC6A0000u: // kdp -> Latn
+ case 0xC46A0000u: // kdr -> Latn
+ case 0xD86A0000u: // kdw -> Latn
+ case 0xDC6A0000u: // kdx -> Latn
+ case 0xE06A0000u: // kdy -> Latn
+ case 0xE46A0000u: // kdz -> Latn
+ case 0x808A0000u: // kea -> Latn
+ case 0x848A0000u: // keb -> Latn
+ case 0x888A0000u: // kec -> Latn
+ case 0x8C8A0000u: // ked -> Latn
+ case 0x908A0000u: // kee -> Latn
+ case 0x948A0000u: // kef -> Latn
+ case 0x988A0000u: // keg -> Latn
+ case 0x9C8A0000u: // keh -> Latn
+ case 0xA08A0000u: // kei -> Latn
+ case 0xA88A0000u: // kek -> Latn
+ case 0xAC8A0000u: // kel -> Latn
+ case 0xB08A0000u: // kem -> Latn
+ case 0xB48A0000u: // ken -> Latn
+ case 0xB88A0000u: // keo -> Latn
+ case 0xC48A0000u: // ker -> Latn
+ case 0xC88A0000u: // kes -> Latn
+ case 0xD08A0000u: // keu -> Latn
+ case 0xD88A0000u: // kew -> Latn
+ case 0xE48A0000u: // kez -> Latn
+ case 0x94AA0000u: // kff -> Latn
+ case 0xACAA0000u: // kfl -> Latn
+ case 0xB4AA0000u: // kfn -> Latn
+ case 0xB8AA0000u: // kfo -> Latn
+ case 0xD4AA0000u: // kfv -> Latn
+ case 0xD8AA0000u: // kfw -> Latn
+ case 0xE4AA0000u: // kfz -> Latn
+ case 0x6B670000u: // kg -> Latn
+ case 0x80CA0000u: // kga -> Latn
+ case 0x84CA0000u: // kgb -> Latn
+ case 0x90CA0000u: // kge -> Latn
+ case 0x94CA0000u: // kgf -> Latn
+ case 0xA8CA0000u: // kgk -> Latn
+ case 0xACCA0000u: // kgl -> Latn
+ case 0xB8CA0000u: // kgo -> Latn
+ case 0xBCCA0000u: // kgp -> Latn
+ case 0xC0CA0000u: // kgq -> Latn
+ case 0xC4CA0000u: // kgr -> Latn
+ case 0xC8CA0000u: // kgs -> Latn
+ case 0xCCCA0000u: // kgt -> Latn
+ case 0xD0CA0000u: // kgu -> Latn
+ case 0xD4CA0000u: // kgv -> Latn
+ case 0xD8CA0000u: // kgw -> Latn
+ case 0xDCCA0000u: // kgx -> Latn
+ case 0x80EA0000u: // kha -> Latn
+ case 0x88EA0000u: // khc -> Latn
+ case 0x8CEA0000u: // khd -> Latn
+ case 0x90EA0000u: // khe -> Latn
+ case 0x9CEA0000u: // khh -> Latn
+ case 0xA4EA0000u: // khj -> Latn
+ case 0xACEA0000u: // khl -> Latn
+ case 0xBCEA0000u: // khp -> Latn
+ case 0xC0EA0000u: // khq -> Latn
+ case 0xC4EA0000u: // khr -> Latn
+ case 0xC8EA0000u: // khs -> Latn
+ case 0xD0EA0000u: // khu -> Latn
+ case 0xDCEA0000u: // khx -> Latn
+ case 0xE0EA0000u: // khy -> Latn
+ case 0xE4EA0000u: // khz -> Latn
+ case 0x6B690000u: // ki -> Latn
+ case 0x810A0000u: // kia -> Latn
+ case 0x850A0000u: // kib -> Latn
+ case 0x890A0000u: // kic -> Latn
+ case 0x8D0A0000u: // kid -> Latn
+ case 0x910A0000u: // kie -> Latn
+ case 0x990A0000u: // kig -> Latn
+ case 0x9D0A0000u: // kih -> Latn
+ case 0xA50A0000u: // kij -> Latn
+ case 0xAD0A0000u: // kil -> Latn
+ case 0xB90A0000u: // kio -> Latn
+ case 0xC10A0000u: // kiq -> Latn
+ case 0xC90A0000u: // kis -> Latn
+ case 0xCD0A0000u: // kit -> Latn
+ case 0xD10A0000u: // kiu -> Latn
+ case 0xD50A0000u: // kiv -> Latn
+ case 0xD90A0000u: // kiw -> Latn
+ case 0xDD0A0000u: // kix -> Latn
+ case 0xE10A0000u: // kiy -> Latn
+ case 0xE50A0000u: // kiz -> Latn
+ case 0x6B6A0000u: // kj -> Latn
+ case 0x812A0000u: // kja -> Latn
+ case 0x852A0000u: // kjb -> Latn
+ case 0x892A0000u: // kjc -> Latn
+ case 0x8D2A0000u: // kjd -> Latn
+ case 0x912A0000u: // kje -> Latn
+ case 0xA12A0000u: // kji -> Latn
+ case 0xA52A0000u: // kjj -> Latn
+ case 0xA92A0000u: // kjk -> Latn
+ case 0xB12A0000u: // kjm -> Latn
+ case 0xB52A0000u: // kjn -> Latn
+ case 0xC12A0000u: // kjq -> Latn
+ case 0xC52A0000u: // kjr -> Latn
+ case 0xC92A0000u: // kjs -> Latn
+ case 0xD12A0000u: // kju -> Latn
+ case 0xDD2A0000u: // kjx -> Latn
+ case 0xE12A0000u: // kjy -> Latn
+ case 0x814A0000u: // kka -> Latn
+ case 0x854A0000u: // kkb -> Latn
+ case 0x894A0000u: // kkc -> Latn
+ case 0x8D4A0000u: // kkd -> Latn
+ case 0x914A0000u: // kke -> Latn
+ case 0x994A0000u: // kkg -> Latn
+ case 0xA14A0000u: // kki -> Latn
+ case 0xA54A0000u: // kkj -> Latn
+ case 0xA94A0000u: // kkk -> Latn
+ case 0xAD4A0000u: // kkl -> Latn
+ case 0xB14A0000u: // kkm -> Latn
+ case 0xB94A0000u: // kko -> Latn
+ case 0xBD4A0000u: // kkp -> Latn
+ case 0xC14A0000u: // kkq -> Latn
+ case 0xC54A0000u: // kkr -> Latn
+ case 0xC94A0000u: // kks -> Latn
+ case 0xD14A0000u: // kku -> Latn
+ case 0xD54A0000u: // kkv -> Latn
+ case 0xD94A0000u: // kkw -> Latn
+ case 0xDD4A0000u: // kkx -> Latn
+ case 0xE14A0000u: // kky -> Latn
+ case 0xE54A0000u: // kkz -> Latn
+ case 0x6B6C0000u: // kl -> Latn
+ case 0x816A0000u: // kla -> Latn
+ case 0x856A0000u: // klb -> Latn
+ case 0x896A0000u: // klc -> Latn
+ case 0x8D6A0000u: // kld -> Latn
+ case 0x956A0000u: // klf -> Latn
+ case 0x996A0000u: // klg -> Latn
+ case 0x9D6A0000u: // klh -> Latn
+ case 0xA16A0000u: // kli -> Latn
+ case 0xA96A0000u: // klk -> Latn
+ case 0xAD6A0000u: // kll -> Latn
+ case 0xB16A0000u: // klm -> Latn
+ case 0xB56A0000u: // kln -> Latn
+ case 0xB96A0000u: // klo -> Latn
+ case 0xBD6A0000u: // klp -> Latn
+ case 0xC16A0000u: // klq -> Latn
+ case 0xC96A0000u: // kls -> Latn
+ case 0xCD6A0000u: // klt -> Latn
+ case 0xD16A0000u: // klu -> Latn
+ case 0xD56A0000u: // klv -> Latn
+ case 0xD96A0000u: // klw -> Latn
+ case 0xDD6A0000u: // klx -> Latn
+ case 0xE16A0000u: // kly -> Latn
+ case 0xE56A0000u: // klz -> Latn
+ case 0x818A0000u: // kma -> Latn
+ case 0x858A0000u: // kmb -> Latn
+ case 0x898A0000u: // kmc -> Latn
+ case 0x8D8A0000u: // kmd -> Latn
+ case 0x918A0000u: // kme -> Latn
+ case 0x958A0000u: // kmf -> Latn
+ case 0x998A0000u: // kmg -> Latn
+ case 0x9D8A0000u: // kmh -> Latn
+ case 0xA18A0000u: // kmi -> Latn
+ case 0xA98A0000u: // kmk -> Latn
+ case 0xAD8A0000u: // kml -> Latn
+ case 0xB18A0000u: // kmm -> Latn
+ case 0xB58A0000u: // kmn -> Latn
+ case 0xB98A0000u: // kmo -> Latn
+ case 0xBD8A0000u: // kmp -> Latn
+ case 0xC18A0000u: // kmq -> Latn
+ case 0xC98A0000u: // kms -> Latn
+ case 0xCD8A0000u: // kmt -> Latn
+ case 0xD18A0000u: // kmu -> Latn
+ case 0xD58A0000u: // kmv -> Latn
+ case 0xD98A0000u: // kmw -> Latn
+ case 0xDD8A0000u: // kmx -> Latn
+ case 0xE18A0000u: // kmy -> Latn
+ case 0x81AA0000u: // kna -> Latn
+ case 0x85AA0000u: // knb -> Latn
+ case 0x8DAA0000u: // knd -> Latn
+ case 0x91AA0000u: // kne -> Latn
+ case 0x95AA0000u: // knf -> Latn
+ case 0xA1AA0000u: // kni -> Latn
+ case 0xA5AA0000u: // knj -> Latn
+ case 0xA9AA0000u: // knk -> Latn
+ case 0xADAA0000u: // knl -> Latn
+ case 0xB1AA0000u: // knm -> Latn
+ case 0xB9AA0000u: // kno -> Latn
+ case 0xBDAA0000u: // knp -> Latn
+ case 0xC1AA0000u: // knq -> Latn
+ case 0xC5AA0000u: // knr -> Latn
+ case 0xC9AA0000u: // kns -> Latn
+ case 0xCDAA0000u: // knt -> Latn
+ case 0xD1AA0000u: // knu -> Latn
+ case 0xD5AA0000u: // knv -> Latn
+ case 0xD9AA0000u: // knw -> Latn
+ case 0xDDAA0000u: // knx -> Latn
+ case 0xE1AA0000u: // kny -> Latn
+ case 0xE5AA0000u: // knz -> Latn
+ case 0x81CA0000u: // koa -> Latn
+ case 0x89CA0000u: // koc -> Latn
+ case 0x8DCA0000u: // kod -> Latn
+ case 0x91CA0000u: // koe -> Latn
+ case 0x95CA0000u: // kof -> Latn
+ case 0x99CA0000u: // kog -> Latn
+ case 0x9DCA0000u: // koh -> Latn
+ case 0xADCA0000u: // kol -> Latn
+ case 0xB9CA0000u: // koo -> Latn
+ case 0xBDCA0000u: // kop -> Latn
+ case 0xC1CA0000u: // koq -> Latn
+ case 0xC9CA0000u: // kos -> Latn
+ case 0xCDCA0000u: // kot -> Latn
+ case 0xD1CA0000u: // kou -> Latn
+ case 0xD5CA0000u: // kov -> Latn
+ case 0xD9CA0000u: // kow -> Latn
+ case 0xE1CA0000u: // koy -> Latn
+ case 0xE5CA0000u: // koz -> Latn
+ case 0x81EA0000u: // kpa -> Latn
+ case 0x89EA0000u: // kpc -> Latn
+ case 0x8DEA0000u: // kpd -> Latn
+ case 0x91EA0000u: // kpe -> Latn
+ case 0x95EA0000u: // kpf -> Latn
+ case 0x99EA0000u: // kpg -> Latn
+ case 0x9DEA0000u: // kph -> Latn
+ case 0xA1EA0000u: // kpi -> Latn
+ case 0xA5EA0000u: // kpj -> Latn
+ case 0xA9EA0000u: // kpk -> Latn
+ case 0xADEA0000u: // kpl -> Latn
+ case 0xB1EA0000u: // kpm -> Latn
+ case 0xB5EA0000u: // kpn -> Latn
+ case 0xB9EA0000u: // kpo -> Latn
+ case 0xC1EA0000u: // kpq -> Latn
+ case 0xC5EA0000u: // kpr -> Latn
+ case 0xC9EA0000u: // kps -> Latn
+ case 0xD1EA0000u: // kpu -> Latn
+ case 0xD9EA0000u: // kpw -> Latn
+ case 0xDDEA0000u: // kpx -> Latn
+ case 0xE5EA0000u: // kpz -> Latn
+ case 0x820A0000u: // kqa -> Latn
+ case 0x860A0000u: // kqb -> Latn
+ case 0x8A0A0000u: // kqc -> Latn
+ case 0x920A0000u: // kqe -> Latn
+ case 0x960A0000u: // kqf -> Latn
+ case 0x9A0A0000u: // kqg -> Latn
+ case 0x9E0A0000u: // kqh -> Latn
+ case 0xA20A0000u: // kqi -> Latn
+ case 0xA60A0000u: // kqj -> Latn
+ case 0xAA0A0000u: // kqk -> Latn
+ case 0xAE0A0000u: // kql -> Latn
+ case 0xB20A0000u: // kqm -> Latn
+ case 0xB60A0000u: // kqn -> Latn
+ case 0xBA0A0000u: // kqo -> Latn
+ case 0xBE0A0000u: // kqp -> Latn
+ case 0xC20A0000u: // kqq -> Latn
+ case 0xC60A0000u: // kqr -> Latn
+ case 0xCA0A0000u: // kqs -> Latn
+ case 0xCE0A0000u: // kqt -> Latn
+ case 0xD20A0000u: // kqu -> Latn
+ case 0xD60A0000u: // kqv -> Latn
+ case 0xDA0A0000u: // kqw -> Latn
+ case 0xDE0A0000u: // kqx -> Latn
+ case 0xE60A0000u: // kqz -> Latn
+ case 0x6B720000u: // kr -> Latn
+ case 0x862A0000u: // krb -> Latn
+ case 0x8E2A0000u: // krd -> Latn
+ case 0x922A0000u: // kre -> Latn
+ case 0x962A0000u: // krf -> Latn
+ case 0x9E2A0000u: // krh -> Latn
+ case 0xA22A0000u: // kri -> Latn
+ case 0xA62A0000u: // krj -> Latn
+ case 0xAE2A0000u: // krl -> Latn
+ case 0xB62A0000u: // krn -> Latn
+ case 0xBE2A0000u: // krp -> Latn
+ case 0xCA2A0000u: // krs -> Latn
+ case 0xCE2A0000u: // krt -> Latn
+ case 0xDA2A0000u: // krw -> Latn
+ case 0xDE2A0000u: // krx -> Latn
+ case 0xE22A0000u: // kry -> Latn
+ case 0xE62A0000u: // krz -> Latn
+ case 0x864A0000u: // ksb -> Latn
+ case 0x8A4A0000u: // ksc -> Latn
+ case 0x8E4A0000u: // ksd -> Latn
+ case 0x924A0000u: // kse -> Latn
+ case 0x964A0000u: // ksf -> Latn
+ case 0x9A4A0000u: // ksg -> Latn
+ case 0x9E4A0000u: // ksh -> Latn
+ case 0xA24A0000u: // ksi -> Latn
+ case 0xA64A0000u: // ksj -> Latn
+ case 0xAA4A0000u: // ksk -> Latn
+ case 0xAE4A0000u: // ksl -> Latn
+ case 0xB24A0000u: // ksm -> Latn
+ case 0xB64A0000u: // ksn -> Latn
+ case 0xBA4A0000u: // kso -> Latn
+ case 0xBE4A0000u: // ksp -> Latn
+ case 0xC24A0000u: // ksq -> Latn
+ case 0xC64A0000u: // ksr -> Latn
+ case 0xCA4A0000u: // kss -> Latn
+ case 0xCE4A0000u: // kst -> Latn
+ case 0xD64A0000u: // ksv -> Latn
+ case 0xDE4A0000u: // ksx -> Latn
+ case 0x826A0000u: // kta -> Latn
+ case 0x8A6A0000u: // ktc -> Latn
+ case 0x8E6A0000u: // ktd -> Latn
+ case 0x966A0000u: // ktf -> Latn
+ case 0x9A6A0000u: // ktg -> Latn
+ case 0x9E6A0000u: // kth -> Latn
+ case 0xA26A0000u: // kti -> Latn
+ case 0xA66A0000u: // ktj -> Latn
+ case 0xAA6A0000u: // ktk -> Latn
+ case 0xB26A0000u: // ktm -> Latn
+ case 0xB66A0000u: // ktn -> Latn
+ case 0xBA6A0000u: // kto -> Latn
+ case 0xC26A0000u: // ktq -> Latn
+ case 0xCA6A0000u: // kts -> Latn
+ case 0xCE6A0000u: // ktt -> Latn
+ case 0xD26A0000u: // ktu -> Latn
+ case 0xD66A0000u: // ktv -> Latn
+ case 0xDA6A0000u: // ktw -> Latn
+ case 0xDE6A0000u: // ktx -> Latn
+ case 0xE26A0000u: // kty -> Latn
+ case 0xE66A0000u: // ktz -> Latn
+ case 0x6B750000u: // ku -> Latn
+ case 0x868A0000u: // kub -> Latn
+ case 0x8A8A0000u: // kuc -> Latn
+ case 0x8E8A0000u: // kud -> Latn
+ case 0x928A0000u: // kue -> Latn
+ case 0x9A8A0000u: // kug -> Latn
+ case 0x9E8A0000u: // kuh -> Latn
+ case 0xA28A0000u: // kui -> Latn
+ case 0xA68A0000u: // kuj -> Latn
+ case 0xAA8A0000u: // kuk -> Latn
+ case 0xAE8A0000u: // kul -> Latn
+ case 0xB68A0000u: // kun -> Latn
+ case 0xBA8A0000u: // kuo -> Latn
+ case 0xBE8A0000u: // kup -> Latn
+ case 0xC28A0000u: // kuq -> Latn
+ case 0xCA8A0000u: // kus -> Latn
+ case 0xCE8A0000u: // kut -> Latn
+ case 0xD28A0000u: // kuu -> Latn
+ case 0xD68A0000u: // kuv -> Latn
+ case 0xDA8A0000u: // kuw -> Latn
+ case 0xDE8A0000u: // kux -> Latn
+ case 0xE28A0000u: // kuy -> Latn
+ case 0xE68A0000u: // kuz -> Latn
+ case 0x86AA0000u: // kvb -> Latn
+ case 0x8AAA0000u: // kvc -> Latn
+ case 0x8EAA0000u: // kvd -> Latn
+ case 0x92AA0000u: // kve -> Latn
+ case 0x96AA0000u: // kvf -> Latn
+ case 0x9AAA0000u: // kvg -> Latn
+ case 0x9EAA0000u: // kvh -> Latn
+ case 0xA2AA0000u: // kvi -> Latn
+ case 0xA6AA0000u: // kvj -> Latn
+ case 0xAEAA0000u: // kvl -> Latn
+ case 0xB2AA0000u: // kvm -> Latn
+ case 0xB6AA0000u: // kvn -> Latn
+ case 0xBAAA0000u: // kvo -> Latn
+ case 0xBEAA0000u: // kvp -> Latn
+ case 0xC6AA0000u: // kvr -> Latn
+ case 0xD6AA0000u: // kvv -> Latn
+ case 0xDAAA0000u: // kvw -> Latn
+ case 0xE6AA0000u: // kvz -> Latn
+ case 0x6B770000u: // kw -> Latn
+ case 0x82CA0000u: // kwa -> Latn
+ case 0x86CA0000u: // kwb -> Latn
+ case 0x8ACA0000u: // kwc -> Latn
+ case 0x8ECA0000u: // kwd -> Latn
+ case 0x92CA0000u: // kwe -> Latn
+ case 0x96CA0000u: // kwf -> Latn
+ case 0x9ACA0000u: // kwg -> Latn
+ case 0x9ECA0000u: // kwh -> Latn
+ case 0xA2CA0000u: // kwi -> Latn
+ case 0xA6CA0000u: // kwj -> Latn
+ case 0xAACA0000u: // kwk -> Latn
+ case 0xAECA0000u: // kwl -> Latn
+ case 0xB2CA0000u: // kwm -> Latn
+ case 0xB6CA0000u: // kwn -> Latn
+ case 0xBACA0000u: // kwo -> Latn
+ case 0xBECA0000u: // kwp -> Latn
+ case 0xC6CA0000u: // kwr -> Latn
+ case 0xCACA0000u: // kws -> Latn
+ case 0xCECA0000u: // kwt -> Latn
+ case 0xD2CA0000u: // kwu -> Latn
+ case 0xD6CA0000u: // kwv -> Latn
+ case 0xDACA0000u: // kww -> Latn
+ case 0xE2CA0000u: // kwy -> Latn
+ case 0xE6CA0000u: // kwz -> Latn
+ case 0x82EA0000u: // kxa -> Latn
+ case 0x86EA0000u: // kxb -> Latn
+ case 0x8AEA0000u: // kxc -> Latn
+ case 0x8EEA0000u: // kxd -> Latn
+ case 0xA2EA0000u: // kxi -> Latn
+ case 0xA6EA0000u: // kxj -> Latn
+ case 0xB6EA0000u: // kxn -> Latn
+ case 0xBAEA0000u: // kxo -> Latn
+ case 0xC2EA0000u: // kxq -> Latn
+ case 0xC6EA0000u: // kxr -> Latn
+ case 0xCEEA0000u: // kxt -> Latn
+ case 0xD6EA0000u: // kxv -> Latn
+ case 0xDAEA0000u: // kxw -> Latn
+ case 0xDEEA0000u: // kxx -> Latn
+ case 0xE2EA0000u: // kxy -> Latn
+ case 0xE6EA0000u: // kxz -> Latn
+ case 0x6B795452u: // ky-TR -> Latn
+ case 0x830A0000u: // kya -> Latn
+ case 0x870A0000u: // kyb -> Latn
+ case 0x8B0A0000u: // kyc -> Latn
+ case 0x8F0A0000u: // kyd -> Latn
+ case 0x930A0000u: // kye -> Latn
+ case 0x970A0000u: // kyf -> Latn
+ case 0x9B0A0000u: // kyg -> Latn
+ case 0x9F0A0000u: // kyh -> Latn
+ case 0xA30A0000u: // kyi -> Latn
+ case 0xA70A0000u: // kyj -> Latn
+ case 0xAB0A0000u: // kyk -> Latn
+ case 0xAF0A0000u: // kyl -> Latn
+ case 0xB30A0000u: // kym -> Latn
+ case 0xB70A0000u: // kyn -> Latn
+ case 0xBB0A0000u: // kyo -> Latn
+ case 0xC30A0000u: // kyq -> Latn
+ case 0xC70A0000u: // kyr -> Latn
+ case 0xCB0A0000u: // kys -> Latn
+ case 0xCF0A0000u: // kyt -> Latn
+ case 0xDF0A0000u: // kyx -> Latn
+ case 0xE30A0000u: // kyy -> Latn
+ case 0xE70A0000u: // kyz -> Latn
+ case 0x832A0000u: // kza -> Latn
+ case 0x872A0000u: // kzb -> Latn
+ case 0x8B2A0000u: // kzc -> Latn
+ case 0x8F2A0000u: // kzd -> Latn
+ case 0x932A0000u: // kze -> Latn
+ case 0x972A0000u: // kzf -> Latn
+ case 0xA32A0000u: // kzi -> Latn
+ case 0xAB2A0000u: // kzk -> Latn
+ case 0xAF2A0000u: // kzl -> Latn
+ case 0xB32A0000u: // kzm -> Latn
+ case 0xB72A0000u: // kzn -> Latn
+ case 0xBB2A0000u: // kzo -> Latn
+ case 0xBF2A0000u: // kzp -> Latn
+ case 0xC72A0000u: // kzr -> Latn
+ case 0xCB2A0000u: // kzs -> Latn
+ case 0xD32A0000u: // kzu -> Latn
+ case 0xD72A0000u: // kzv -> Latn
+ case 0xDB2A0000u: // kzw -> Latn
+ case 0xDF2A0000u: // kzx -> Latn
+ case 0xE32A0000u: // kzy -> Latn
+ case 0xE72A0000u: // kzz -> Latn
+ case 0x6C610000u: // la -> Latn
+ case 0x800B0000u: // laa -> Latn
+ case 0x880B0000u: // lac -> Latn
+ case 0x980B0000u: // lag -> Latn
+ case 0xA00B0000u: // lai -> Latn
+ case 0xA40B0000u: // laj -> Latn
+ case 0xAC0B0000u: // lal -> Latn
+ case 0xB00B0000u: // lam -> Latn
+ case 0xB40B0000u: // lan -> Latn
+ case 0xBC0B0000u: // lap -> Latn
+ case 0xC00B0000u: // laq -> Latn
+ case 0xC40B0000u: // lar -> Latn
+ case 0xC80B0000u: // las -> Latn
+ case 0xD00B0000u: // lau -> Latn
+ case 0xD80B0000u: // law -> Latn
+ case 0xDC0B0000u: // lax -> Latn
+ case 0xE40B0000u: // laz -> Latn
+ case 0x6C620000u: // lb -> Latn
+ case 0x842B0000u: // lbb -> Latn
+ case 0xA02B0000u: // lbi -> Latn
+ case 0xAC2B0000u: // lbl -> Latn
+ case 0xB42B0000u: // lbn -> Latn
+ case 0xC02B0000u: // lbq -> Latn
+ case 0xCC2B0000u: // lbt -> Latn
+ case 0xD02B0000u: // lbu -> Latn
+ case 0xD42B0000u: // lbv -> Latn
+ case 0xD82B0000u: // lbw -> Latn
+ case 0xDC2B0000u: // lbx -> Latn
+ case 0xE02B0000u: // lby -> Latn
+ case 0xE42B0000u: // lbz -> Latn
+ case 0x884B0000u: // lcc -> Latn
+ case 0x8C4B0000u: // lcd -> Latn
+ case 0x904B0000u: // lce -> Latn
+ case 0x944B0000u: // lcf -> Latn
+ case 0x9C4B0000u: // lch -> Latn
+ case 0xAC4B0000u: // lcl -> Latn
+ case 0xB04B0000u: // lcm -> Latn
+ case 0xC04B0000u: // lcq -> Latn
+ case 0xC84B0000u: // lcs -> Latn
+ case 0x806B0000u: // lda -> Latn
+ case 0x846B0000u: // ldb -> Latn
+ case 0x8C6B0000u: // ldd -> Latn
+ case 0x986B0000u: // ldg -> Latn
+ case 0x9C6B0000u: // ldh -> Latn
+ case 0xA06B0000u: // ldi -> Latn
+ case 0xA46B0000u: // ldj -> Latn
+ case 0xA86B0000u: // ldk -> Latn
+ case 0xAC6B0000u: // ldl -> Latn
+ case 0xB06B0000u: // ldm -> Latn
+ case 0xB46B0000u: // ldn -> Latn
+ case 0xB86B0000u: // ldo -> Latn
+ case 0xBC6B0000u: // ldp -> Latn
+ case 0xC06B0000u: // ldq -> Latn
+ case 0x808B0000u: // lea -> Latn
+ case 0x848B0000u: // leb -> Latn
+ case 0x888B0000u: // lec -> Latn
+ case 0x8C8B0000u: // led -> Latn
+ case 0x908B0000u: // lee -> Latn
+ case 0x948B0000u: // lef -> Latn
+ case 0x9C8B0000u: // leh -> Latn
+ case 0xA08B0000u: // lei -> Latn
+ case 0xA48B0000u: // lej -> Latn
+ case 0xA88B0000u: // lek -> Latn
+ case 0xAC8B0000u: // lel -> Latn
+ case 0xB08B0000u: // lem -> Latn
+ case 0xB48B0000u: // len -> Latn
+ case 0xB88B0000u: // leo -> Latn
+ case 0xC08B0000u: // leq -> Latn
+ case 0xC48B0000u: // ler -> Latn
+ case 0xC88B0000u: // les -> Latn
+ case 0xCC8B0000u: // let -> Latn
+ case 0xD08B0000u: // leu -> Latn
+ case 0xD48B0000u: // lev -> Latn
+ case 0xD88B0000u: // lew -> Latn
+ case 0xDC8B0000u: // lex -> Latn
+ case 0xE08B0000u: // ley -> Latn
+ case 0x80AB0000u: // lfa -> Latn
+ case 0xB4AB0000u: // lfn -> Latn
+ case 0x6C670000u: // lg -> Latn
+ case 0x80CB0000u: // lga -> Latn
+ case 0x84CB0000u: // lgb -> Latn
+ case 0x98CB0000u: // lgg -> Latn
+ case 0x9CCB0000u: // lgh -> Latn
+ case 0xA0CB0000u: // lgi -> Latn
+ case 0xA8CB0000u: // lgk -> Latn
+ case 0xACCB0000u: // lgl -> Latn
+ case 0xB0CB0000u: // lgm -> Latn
+ case 0xB4CB0000u: // lgn -> Latn
+ case 0xB8CB0000u: // lgo -> Latn
+ case 0xC0CB0000u: // lgq -> Latn
+ case 0xC4CB0000u: // lgr -> Latn
+ case 0xCCCB0000u: // lgt -> Latn
+ case 0xD0CB0000u: // lgu -> Latn
+ case 0xE4CB0000u: // lgz -> Latn
+ case 0x80EB0000u: // lha -> Latn
+ case 0x9CEB0000u: // lhh -> Latn
+ case 0xA0EB0000u: // lhi -> Latn
+ case 0xB4EB0000u: // lhn -> Latn
+ case 0xCCEB0000u: // lht -> Latn
+ case 0xD0EB0000u: // lhu -> Latn
+ case 0x6C690000u: // li -> Latn
+ case 0x810B0000u: // lia -> Latn
+ case 0x850B0000u: // lib -> Latn
+ case 0x890B0000u: // lic -> Latn
+ case 0x8D0B0000u: // lid -> Latn
+ case 0x910B0000u: // lie -> Latn
+ case 0x990B0000u: // lig -> Latn
+ case 0x9D0B0000u: // lih -> Latn
+ case 0xA50B0000u: // lij -> Latn
+ case 0xA90B0000u: // lik -> Latn
+ case 0xAD0B0000u: // lil -> Latn
+ case 0xB90B0000u: // lio -> Latn
+ case 0xBD0B0000u: // lip -> Latn
+ case 0xC10B0000u: // liq -> Latn
+ case 0xC50B0000u: // lir -> Latn
+ case 0xD10B0000u: // liu -> Latn
+ case 0xD50B0000u: // liv -> Latn
+ case 0xD90B0000u: // liw -> Latn
+ case 0xDD0B0000u: // lix -> Latn
+ case 0xE10B0000u: // liy -> Latn
+ case 0xE50B0000u: // liz -> Latn
+ case 0x812B0000u: // lja -> Latn
+ case 0x912B0000u: // lje -> Latn
+ case 0xA12B0000u: // lji -> Latn
+ case 0xAD2B0000u: // ljl -> Latn
+ case 0xBD2B0000u: // ljp -> Latn
+ case 0xD92B0000u: // ljw -> Latn
+ case 0xDD2B0000u: // ljx -> Latn
+ case 0x814B0000u: // lka -> Latn
+ case 0x854B0000u: // lkb -> Latn
+ case 0x894B0000u: // lkc -> Latn
+ case 0x8D4B0000u: // lkd -> Latn
+ case 0x914B0000u: // lke -> Latn
+ case 0xA54B0000u: // lkj -> Latn
+ case 0xAD4B0000u: // lkl -> Latn
+ case 0xB14B0000u: // lkm -> Latn
+ case 0xB54B0000u: // lkn -> Latn
+ case 0xB94B0000u: // lko -> Latn
+ case 0xC54B0000u: // lkr -> Latn
+ case 0xC94B0000u: // lks -> Latn
+ case 0xCD4B0000u: // lkt -> Latn
+ case 0xD14B0000u: // lku -> Latn
+ case 0xE14B0000u: // lky -> Latn
+ case 0x816B0000u: // lla -> Latn
+ case 0x856B0000u: // llb -> Latn
+ case 0x896B0000u: // llc -> Latn
+ case 0x8D6B0000u: // lld -> Latn
+ case 0x916B0000u: // lle -> Latn
+ case 0x956B0000u: // llf -> Latn
+ case 0x996B0000u: // llg -> Latn
+ case 0xA16B0000u: // lli -> Latn
+ case 0xA56B0000u: // llj -> Latn
+ case 0xA96B0000u: // llk -> Latn
+ case 0xAD6B0000u: // lll -> Latn
+ case 0xB16B0000u: // llm -> Latn
+ case 0xB56B0000u: // lln -> Latn
+ case 0xBD6B0000u: // llp -> Latn
+ case 0xC16B0000u: // llq -> Latn
+ case 0xD16B0000u: // llu -> Latn
+ case 0xDD6B0000u: // llx -> Latn
+ case 0x818B0000u: // lma -> Latn
+ case 0x858B0000u: // lmb -> Latn
+ case 0x898B0000u: // lmc -> Latn
+ case 0x8D8B0000u: // lmd -> Latn
+ case 0x918B0000u: // lme -> Latn
+ case 0x958B0000u: // lmf -> Latn
+ case 0x998B0000u: // lmg -> Latn
+ case 0xA18B0000u: // lmi -> Latn
+ case 0xA58B0000u: // lmj -> Latn
+ case 0xA98B0000u: // lmk -> Latn
+ case 0xAD8B0000u: // lml -> Latn
+ case 0xB98B0000u: // lmo -> Latn
+ case 0xBD8B0000u: // lmp -> Latn
+ case 0xC18B0000u: // lmq -> Latn
+ case 0xC58B0000u: // lmr -> Latn
+ case 0xD18B0000u: // lmu -> Latn
+ case 0xD58B0000u: // lmv -> Latn
+ case 0xD98B0000u: // lmw -> Latn
+ case 0xDD8B0000u: // lmx -> Latn
+ case 0xE18B0000u: // lmy -> Latn
+ case 0x6C6E0000u: // ln -> Latn
+ case 0x81AB0000u: // lna -> Latn
+ case 0x85AB0000u: // lnb -> Latn
+ case 0x8DAB0000u: // lnd -> Latn
+ case 0x99AB0000u: // lng -> Latn
+ case 0x9DAB0000u: // lnh -> Latn
+ case 0xA1AB0000u: // lni -> Latn
+ case 0xA5AB0000u: // lnj -> Latn
+ case 0xADAB0000u: // lnl -> Latn
+ case 0xB1AB0000u: // lnm -> Latn
+ case 0xB5AB0000u: // lnn -> Latn
+ case 0xC9AB0000u: // lns -> Latn
+ case 0xD1AB0000u: // lnu -> Latn
+ case 0xD9AB0000u: // lnw -> Latn
+ case 0xE5AB0000u: // lnz -> Latn
+ case 0x81CB0000u: // loa -> Latn
+ case 0x85CB0000u: // lob -> Latn
+ case 0x89CB0000u: // loc -> Latn
+ case 0x91CB0000u: // loe -> Latn
+ case 0x99CB0000u: // log -> Latn
+ case 0x9DCB0000u: // loh -> Latn
+ case 0xA1CB0000u: // loi -> Latn
+ case 0xA5CB0000u: // loj -> Latn
+ case 0xA9CB0000u: // lok -> Latn
+ case 0xADCB0000u: // lol -> Latn
+ case 0xB1CB0000u: // lom -> Latn
+ case 0xB5CB0000u: // lon -> Latn
+ case 0xB9CB0000u: // loo -> Latn
+ case 0xBDCB0000u: // lop -> Latn
+ case 0xC1CB0000u: // loq -> Latn
+ case 0xC5CB0000u: // lor -> Latn
+ case 0xC9CB0000u: // los -> Latn
+ case 0xCDCB0000u: // lot -> Latn
+ case 0xD1CB0000u: // lou -> Latn
+ case 0xD9CB0000u: // low -> Latn
+ case 0xDDCB0000u: // lox -> Latn
+ case 0xE5CB0000u: // loz -> Latn
+ case 0x81EB0000u: // lpa -> Latn
+ case 0x91EB0000u: // lpe -> Latn
+ case 0xB5EB0000u: // lpn -> Latn
+ case 0xDDEB0000u: // lpx -> Latn
+ case 0xC60B0000u: // lqr -> Latn
+ case 0x822B0000u: // lra -> Latn
+ case 0x9A2B0000u: // lrg -> Latn
+ case 0xA22B0000u: // lri -> Latn
+ case 0xB22B0000u: // lrm -> Latn
+ case 0xB62B0000u: // lrn -> Latn
+ case 0xBA2B0000u: // lro -> Latn
+ case 0xCE2B0000u: // lrt -> Latn
+ case 0xD62B0000u: // lrv -> Latn
+ case 0xE62B0000u: // lrz -> Latn
+ case 0x924B0000u: // lse -> Latn
+ case 0xA24B0000u: // lsi -> Latn
+ case 0xB24B0000u: // lsm -> Latn
+ case 0xC64B0000u: // lsr -> Latn
+ case 0x6C740000u: // lt -> Latn
+ case 0x9A6B0000u: // ltg -> Latn
+ case 0x9E6B0000u: // lth -> Latn
+ case 0xA26B0000u: // lti -> Latn
+ case 0xB66B0000u: // ltn -> Latn
+ case 0xBA6B0000u: // lto -> Latn
+ case 0xCA6B0000u: // lts -> Latn
+ case 0xD26B0000u: // ltu -> Latn
+ case 0x6C750000u: // lu -> Latn
+ case 0x828B0000u: // lua -> Latn
+ case 0x8A8B0000u: // luc -> Latn
+ case 0x8E8B0000u: // lud -> Latn
+ case 0x928B0000u: // lue -> Latn
+ case 0x968B0000u: // luf -> Latn
+ case 0xA28B0000u: // lui -> Latn
+ case 0xA68B0000u: // luj -> Latn
+ case 0xAE8B0000u: // lul -> Latn
+ case 0xB28B0000u: // lum -> Latn
+ case 0xB68B0000u: // lun -> Latn
+ case 0xBA8B0000u: // luo -> Latn
+ case 0xBE8B0000u: // lup -> Latn
+ case 0xC28B0000u: // luq -> Latn
+ case 0xC68B0000u: // lur -> Latn
+ case 0xCA8B0000u: // lus -> Latn
+ case 0xCE8B0000u: // lut -> Latn
+ case 0xDA8B0000u: // luw -> Latn
+ case 0xE28B0000u: // luy -> Latn
+ case 0x6C760000u: // lv -> Latn
+ case 0x82AB0000u: // lva -> Latn
+ case 0xA2AB0000u: // lvi -> Latn
+ case 0xAAAB0000u: // lvk -> Latn
+ case 0xAEAB0000u: // lvl -> Latn
+ case 0xD2AB0000u: // lvu -> Latn
+ case 0x82CB0000u: // lwa -> Latn
+ case 0x92CB0000u: // lwe -> Latn
+ case 0x9ACB0000u: // lwg -> Latn
+ case 0x9ECB0000u: // lwh -> Latn
+ case 0xBACB0000u: // lwo -> Latn
+ case 0xCECB0000u: // lwt -> Latn
+ case 0xDACB0000u: // lww -> Latn
+ case 0xB2EB0000u: // lxm -> Latn
+ case 0xB70B0000u: // lyn -> Latn
+ case 0xAF2B0000u: // lzl -> Latn
+ case 0xB72B0000u: // lzn -> Latn
+ case 0xE72B0000u: // lzz -> Latn
+ case 0x800C0000u: // maa -> Latn
+ case 0x840C0000u: // mab -> Latn
+ case 0x8C0C0000u: // mad -> Latn
+ case 0x900C0000u: // mae -> Latn
+ case 0x940C0000u: // maf -> Latn
+ case 0xA40C0000u: // maj -> Latn
+ case 0xA80C0000u: // mak -> Latn
+ case 0xB00C0000u: // mam -> Latn
+ case 0xB40C0000u: // man -> Latn
+ case 0xC00C0000u: // maq -> Latn
+ case 0xC80C0000u: // mas -> Latn
+ case 0xCC0C0000u: // mat -> Latn
+ case 0xD00C0000u: // mau -> Latn
+ case 0xD40C0000u: // mav -> Latn
+ case 0xD80C0000u: // maw -> Latn
+ case 0xDC0C0000u: // max -> Latn
+ case 0xE40C0000u: // maz -> Latn
+ case 0x802C0000u: // mba -> Latn
+ case 0x842C0000u: // mbb -> Latn
+ case 0x882C0000u: // mbc -> Latn
+ case 0x8C2C0000u: // mbd -> Latn
+ case 0x942C0000u: // mbf -> Latn
+ case 0x9C2C0000u: // mbh -> Latn
+ case 0xA02C0000u: // mbi -> Latn
+ case 0xA42C0000u: // mbj -> Latn
+ case 0xA82C0000u: // mbk -> Latn
+ case 0xAC2C0000u: // mbl -> Latn
+ case 0xB02C0000u: // mbm -> Latn
+ case 0xB42C0000u: // mbn -> Latn
+ case 0xB82C0000u: // mbo -> Latn
+ case 0xBC2C0000u: // mbp -> Latn
+ case 0xC02C0000u: // mbq -> Latn
+ case 0xC42C0000u: // mbr -> Latn
+ case 0xC82C0000u: // mbs -> Latn
+ case 0xCC2C0000u: // mbt -> Latn
+ case 0xD02C0000u: // mbu -> Latn
+ case 0xD42C0000u: // mbv -> Latn
+ case 0xD82C0000u: // mbw -> Latn
+ case 0xDC2C0000u: // mbx -> Latn
+ case 0xE42C0000u: // mbz -> Latn
+ case 0x804C0000u: // mca -> Latn
+ case 0x844C0000u: // mcb -> Latn
+ case 0x884C0000u: // mcc -> Latn
+ case 0x8C4C0000u: // mcd -> Latn
+ case 0x904C0000u: // mce -> Latn
+ case 0x944C0000u: // mcf -> Latn
+ case 0x984C0000u: // mcg -> Latn
+ case 0x9C4C0000u: // mch -> Latn
+ case 0xA04C0000u: // mci -> Latn
+ case 0xA44C0000u: // mcj -> Latn
+ case 0xA84C0000u: // mck -> Latn
+ case 0xAC4C0000u: // mcl -> Latn
+ case 0xB04C0000u: // mcm -> Latn
+ case 0xB44C0000u: // mcn -> Latn
+ case 0xB84C0000u: // mco -> Latn
+ case 0xBC4C0000u: // mcp -> Latn
+ case 0xC04C0000u: // mcq -> Latn
+ case 0xC44C0000u: // mcr -> Latn
+ case 0xC84C0000u: // mcs -> Latn
+ case 0xCC4C0000u: // mct -> Latn
+ case 0xD04C0000u: // mcu -> Latn
+ case 0xD44C0000u: // mcv -> Latn
+ case 0xD84C0000u: // mcw -> Latn
+ case 0xDC4C0000u: // mcx -> Latn
+ case 0xE04C0000u: // mcy -> Latn
+ case 0xE44C0000u: // mcz -> Latn
+ case 0x806C0000u: // mda -> Latn
+ case 0x846C0000u: // mdb -> Latn
+ case 0x886C0000u: // mdc -> Latn
+ case 0x8C6C0000u: // mdd -> Latn
+ case 0x986C0000u: // mdg -> Latn
+ case 0x9C6C0000u: // mdh -> Latn
+ case 0xA06C0000u: // mdi -> Latn
+ case 0xA46C0000u: // mdj -> Latn
+ case 0xA86C0000u: // mdk -> Latn
+ case 0xB06C0000u: // mdm -> Latn
+ case 0xB46C0000u: // mdn -> Latn
+ case 0xBC6C0000u: // mdp -> Latn
+ case 0xC06C0000u: // mdq -> Latn
+ case 0xC46C0000u: // mdr -> Latn
+ case 0xC86C0000u: // mds -> Latn
+ case 0xCC6C0000u: // mdt -> Latn
+ case 0xD06C0000u: // mdu -> Latn
+ case 0xD46C0000u: // mdv -> Latn
+ case 0xD86C0000u: // mdw -> Latn
+ case 0xE46C0000u: // mdz -> Latn
+ case 0x808C0000u: // mea -> Latn
+ case 0x848C0000u: // meb -> Latn
+ case 0x888C0000u: // mec -> Latn
+ case 0x8C8C0000u: // med -> Latn
+ case 0x908C0000u: // mee -> Latn
+ case 0x9C8C0000u: // meh -> Latn
+ case 0xA48C0000u: // mej -> Latn
+ case 0xA88C0000u: // mek -> Latn
+ case 0xAC8C0000u: // mel -> Latn
+ case 0xB08C0000u: // mem -> Latn
+ case 0xB48C0000u: // men -> Latn
+ case 0xB88C0000u: // meo -> Latn
+ case 0xBC8C0000u: // mep -> Latn
+ case 0xC08C0000u: // meq -> Latn
+ case 0xC48C0000u: // mer -> Latn
+ case 0xC88C0000u: // mes -> Latn
+ case 0xCC8C0000u: // met -> Latn
+ case 0xD08C0000u: // meu -> Latn
+ case 0xD48C0000u: // mev -> Latn
+ case 0xD88C0000u: // mew -> Latn
+ case 0xE08C0000u: // mey -> Latn
+ case 0xE48C0000u: // mez -> Latn
+ case 0x84AC0000u: // mfb -> Latn
+ case 0x88AC0000u: // mfc -> Latn
+ case 0x8CAC0000u: // mfd -> Latn
+ case 0x90AC0000u: // mfe -> Latn
+ case 0x94AC0000u: // mff -> Latn
+ case 0x98AC0000u: // mfg -> Latn
+ case 0x9CAC0000u: // mfh -> Latn
+ case 0xA4AC0000u: // mfj -> Latn
+ case 0xA8AC0000u: // mfk -> Latn
+ case 0xACAC0000u: // mfl -> Latn
+ case 0xB0AC0000u: // mfm -> Latn
+ case 0xB4AC0000u: // mfn -> Latn
+ case 0xB8AC0000u: // mfo -> Latn
+ case 0xBCAC0000u: // mfp -> Latn
+ case 0xC0AC0000u: // mfq -> Latn
+ case 0xC4AC0000u: // mfr -> Latn
+ case 0xCCAC0000u: // mft -> Latn
+ case 0xD0AC0000u: // mfu -> Latn
+ case 0xD4AC0000u: // mfv -> Latn
+ case 0xD8AC0000u: // mfw -> Latn
+ case 0xDCAC0000u: // mfx -> Latn
+ case 0xE0AC0000u: // mfy -> Latn
+ case 0xE4AC0000u: // mfz -> Latn
+ case 0x6D670000u: // mg -> Latn
+ case 0x84CC0000u: // mgb -> Latn
+ case 0x88CC0000u: // mgc -> Latn
+ case 0x8CCC0000u: // mgd -> Latn
+ case 0x90CC0000u: // mge -> Latn
+ case 0x94CC0000u: // mgf -> Latn
+ case 0x98CC0000u: // mgg -> Latn
+ case 0x9CCC0000u: // mgh -> Latn
+ case 0xA0CC0000u: // mgi -> Latn
+ case 0xA4CC0000u: // mgj -> Latn
+ case 0xA8CC0000u: // mgk -> Latn
+ case 0xACCC0000u: // mgl -> Latn
+ case 0xB0CC0000u: // mgm -> Latn
+ case 0xB4CC0000u: // mgn -> Latn
+ case 0xB8CC0000u: // mgo -> Latn
+ case 0xC0CC0000u: // mgq -> Latn
+ case 0xC4CC0000u: // mgr -> Latn
+ case 0xC8CC0000u: // mgs -> Latn
+ case 0xCCCC0000u: // mgt -> Latn
+ case 0xD0CC0000u: // mgu -> Latn
+ case 0xD4CC0000u: // mgv -> Latn
+ case 0xD8CC0000u: // mgw -> Latn
+ case 0xE0CC0000u: // mgy -> Latn
+ case 0xE4CC0000u: // mgz -> Latn
+ case 0x6D680000u: // mh -> Latn
+ case 0x84EC0000u: // mhb -> Latn
+ case 0x88EC0000u: // mhc -> Latn
+ case 0x8CEC0000u: // mhd -> Latn
+ case 0x90EC0000u: // mhe -> Latn
+ case 0x94EC0000u: // mhf -> Latn
+ case 0x98EC0000u: // mhg -> Latn
+ case 0xA0EC0000u: // mhi -> Latn
+ case 0xA8EC0000u: // mhk -> Latn
+ case 0xACEC0000u: // mhl -> Latn
+ case 0xB0EC0000u: // mhm -> Latn
+ case 0xB4EC0000u: // mhn -> Latn
+ case 0xB8EC0000u: // mho -> Latn
+ case 0xBCEC0000u: // mhp -> Latn
+ case 0xC0EC0000u: // mhq -> Latn
+ case 0xC8EC0000u: // mhs -> Latn
+ case 0xCCEC0000u: // mht -> Latn
+ case 0xD0EC0000u: // mhu -> Latn
+ case 0xD8EC0000u: // mhw -> Latn
+ case 0xDCEC0000u: // mhx -> Latn
+ case 0xE0EC0000u: // mhy -> Latn
+ case 0xE4EC0000u: // mhz -> Latn
+ case 0x6D690000u: // mi -> Latn
+ case 0x810C0000u: // mia -> Latn
+ case 0x850C0000u: // mib -> Latn
+ case 0x890C0000u: // mic -> Latn
+ case 0x910C0000u: // mie -> Latn
+ case 0x950C0000u: // mif -> Latn
+ case 0x990C0000u: // mig -> Latn
+ case 0x9D0C0000u: // mih -> Latn
+ case 0xA10C0000u: // mii -> Latn
+ case 0xA50C0000u: // mij -> Latn
+ case 0xA90C0000u: // mik -> Latn
+ case 0xAD0C0000u: // mil -> Latn
+ case 0xB10C0000u: // mim -> Latn
+ case 0xB50C0000u: // min -> Latn
+ case 0xB90C0000u: // mio -> Latn
+ case 0xBD0C0000u: // mip -> Latn
+ case 0xC10C0000u: // miq -> Latn
+ case 0xC50C0000u: // mir -> Latn
+ case 0xCD0C0000u: // mit -> Latn
+ case 0xD10C0000u: // miu -> Latn
+ case 0xD90C0000u: // miw -> Latn
+ case 0xDD0C0000u: // mix -> Latn
+ case 0xE10C0000u: // miy -> Latn
+ case 0xE50C0000u: // miz -> Latn
+ case 0x852C0000u: // mjb -> Latn
+ case 0x892C0000u: // mjc -> Latn
+ case 0x8D2C0000u: // mjd -> Latn
+ case 0x912C0000u: // mje -> Latn
+ case 0x992C0000u: // mjg -> Latn
+ case 0x9D2C0000u: // mjh -> Latn
+ case 0xA12C0000u: // mji -> Latn
+ case 0xA52C0000u: // mjj -> Latn
+ case 0xA92C0000u: // mjk -> Latn
+ case 0xB12C0000u: // mjm -> Latn
+ case 0xB52C0000u: // mjn -> Latn
+ case 0xC92C0000u: // mjs -> Latn
+ case 0xD92C0000u: // mjw -> Latn
+ case 0xDD2C0000u: // mjx -> Latn
+ case 0xE12C0000u: // mjy -> Latn
+ case 0x814C0000u: // mka -> Latn
+ case 0x894C0000u: // mkc -> Latn
+ case 0x954C0000u: // mkf -> Latn
+ case 0xA54C0000u: // mkj -> Latn
+ case 0xA94C0000u: // mkk -> Latn
+ case 0xAD4C0000u: // mkl -> Latn
+ case 0xB54C0000u: // mkn -> Latn
+ case 0xB94C0000u: // mko -> Latn
+ case 0xBD4C0000u: // mkp -> Latn
+ case 0xC54C0000u: // mkr -> Latn
+ case 0xC94C0000u: // mks -> Latn
+ case 0xCD4C0000u: // mkt -> Latn
+ case 0xD14C0000u: // mku -> Latn
+ case 0xD54C0000u: // mkv -> Latn
+ case 0xD94C0000u: // mkw -> Latn
+ case 0xDD4C0000u: // mkx -> Latn
+ case 0xE14C0000u: // mky -> Latn
+ case 0xE54C0000u: // mkz -> Latn
+ case 0x816C0000u: // mla -> Latn
+ case 0x856C0000u: // mlb -> Latn
+ case 0x896C0000u: // mlc -> Latn
+ case 0x916C0000u: // mle -> Latn
+ case 0x9D6C0000u: // mlh -> Latn
+ case 0xA16C0000u: // mli -> Latn
+ case 0xA56C0000u: // mlj -> Latn
+ case 0xA96C0000u: // mlk -> Latn
+ case 0xAD6C0000u: // mll -> Latn
+ case 0xB56C0000u: // mln -> Latn
+ case 0xB96C0000u: // mlo -> Latn
+ case 0xBD6C0000u: // mlp -> Latn
+ case 0xC16C0000u: // mlq -> Latn
+ case 0xC56C0000u: // mlr -> Latn
+ case 0xC96C0000u: // mls -> Latn
+ case 0xD16C0000u: // mlu -> Latn
+ case 0xD56C0000u: // mlv -> Latn
+ case 0xD96C0000u: // mlw -> Latn
+ case 0xDD6C0000u: // mlx -> Latn
+ case 0xE56C0000u: // mlz -> Latn
+ case 0x818C0000u: // mma -> Latn
+ case 0x858C0000u: // mmb -> Latn
+ case 0x898C0000u: // mmc -> Latn
+ case 0x8D8C0000u: // mmd -> Latn
+ case 0x918C0000u: // mme -> Latn
+ case 0x958C0000u: // mmf -> Latn
+ case 0x998C0000u: // mmg -> Latn
+ case 0x9D8C0000u: // mmh -> Latn
+ case 0xA18C0000u: // mmi -> Latn
+ case 0xB18C0000u: // mmm -> Latn
+ case 0xB58C0000u: // mmn -> Latn
+ case 0xB98C0000u: // mmo -> Latn
+ case 0xBD8C0000u: // mmp -> Latn
+ case 0xC18C0000u: // mmq -> Latn
+ case 0xC58C0000u: // mmr -> Latn
+ case 0xCD8C0000u: // mmt -> Latn
+ case 0xD18C0000u: // mmu -> Latn
+ case 0xD58C0000u: // mmv -> Latn
+ case 0xD98C0000u: // mmw -> Latn
+ case 0xDD8C0000u: // mmx -> Latn
+ case 0xE18C0000u: // mmy -> Latn
+ case 0xE58C0000u: // mmz -> Latn
+ case 0x81AC0000u: // mna -> Latn
+ case 0x85AC0000u: // mnb -> Latn
+ case 0x8DAC0000u: // mnd -> Latn
+ case 0x91AC0000u: // mne -> Latn
+ case 0x95AC0000u: // mnf -> Latn
+ case 0x99AC0000u: // mng -> Latn
+ case 0x9DAC0000u: // mnh -> Latn
+ case 0xADAC0000u: // mnl -> Latn
+ case 0xB1AC0000u: // mnm -> Latn
+ case 0xB5AC0000u: // mnn -> Latn
+ case 0xBDAC0000u: // mnp -> Latn
+ case 0xC1AC0000u: // mnq -> Latn
+ case 0xC5AC0000u: // mnr -> Latn
+ case 0xD1AC0000u: // mnu -> Latn
+ case 0xD5AC0000u: // mnv -> Latn
+ case 0xDDAC0000u: // mnx -> Latn
+ case 0xE1AC0000u: // mny -> Latn
+ case 0xE5AC0000u: // mnz -> Latn
+ case 0x6D6F0000u: // mo -> Latn
+ case 0x81CC0000u: // moa -> Latn
+ case 0x89CC0000u: // moc -> Latn
+ case 0x8DCC0000u: // mod -> Latn
+ case 0x91CC0000u: // moe -> Latn
+ case 0x99CC0000u: // mog -> Latn
+ case 0x9DCC0000u: // moh -> Latn
+ case 0xA1CC0000u: // moi -> Latn
+ case 0xA5CC0000u: // moj -> Latn
+ case 0xA9CC0000u: // mok -> Latn
+ case 0xB1CC0000u: // mom -> Latn
+ case 0xB9CC0000u: // moo -> Latn
+ case 0xBDCC0000u: // mop -> Latn
+ case 0xC1CC0000u: // moq -> Latn
+ case 0xC5CC0000u: // mor -> Latn
+ case 0xC9CC0000u: // mos -> Latn
+ case 0xCDCC0000u: // mot -> Latn
+ case 0xD1CC0000u: // mou -> Latn
+ case 0xD5CC0000u: // mov -> Latn
+ case 0xD9CC0000u: // mow -> Latn
+ case 0xDDCC0000u: // mox -> Latn
+ case 0xE1CC0000u: // moy -> Latn
+ case 0xE5CC0000u: // moz -> Latn
+ case 0x81EC0000u: // mpa -> Latn
+ case 0x85EC0000u: // mpb -> Latn
+ case 0x89EC0000u: // mpc -> Latn
+ case 0x8DEC0000u: // mpd -> Latn
+ case 0x91EC0000u: // mpe -> Latn
+ case 0x99EC0000u: // mpg -> Latn
+ case 0x9DEC0000u: // mph -> Latn
+ case 0xA1EC0000u: // mpi -> Latn
+ case 0xA5EC0000u: // mpj -> Latn
+ case 0xA9EC0000u: // mpk -> Latn
+ case 0xADEC0000u: // mpl -> Latn
+ case 0xB1EC0000u: // mpm -> Latn
+ case 0xB5EC0000u: // mpn -> Latn
+ case 0xB9EC0000u: // mpo -> Latn
+ case 0xBDEC0000u: // mpp -> Latn
+ case 0xC1EC0000u: // mpq -> Latn
+ case 0xC5EC0000u: // mpr -> Latn
+ case 0xC9EC0000u: // mps -> Latn
+ case 0xCDEC0000u: // mpt -> Latn
+ case 0xD1EC0000u: // mpu -> Latn
+ case 0xD5EC0000u: // mpv -> Latn
+ case 0xD9EC0000u: // mpw -> Latn
+ case 0xDDEC0000u: // mpx -> Latn
+ case 0xE1EC0000u: // mpy -> Latn
+ case 0x820C0000u: // mqa -> Latn
+ case 0x860C0000u: // mqb -> Latn
+ case 0x8A0C0000u: // mqc -> Latn
+ case 0x920C0000u: // mqe -> Latn
+ case 0x960C0000u: // mqf -> Latn
+ case 0x9A0C0000u: // mqg -> Latn
+ case 0x9E0C0000u: // mqh -> Latn
+ case 0xA20C0000u: // mqi -> Latn
+ case 0xA60C0000u: // mqj -> Latn
+ case 0xAA0C0000u: // mqk -> Latn
+ case 0xAE0C0000u: // mql -> Latn
+ case 0xB20C0000u: // mqm -> Latn
+ case 0xB60C0000u: // mqn -> Latn
+ case 0xBA0C0000u: // mqo -> Latn
+ case 0xBE0C0000u: // mqp -> Latn
+ case 0xC20C0000u: // mqq -> Latn
+ case 0xC60C0000u: // mqr -> Latn
+ case 0xCA0C0000u: // mqs -> Latn
+ case 0xD20C0000u: // mqu -> Latn
+ case 0xD60C0000u: // mqv -> Latn
+ case 0xDA0C0000u: // mqw -> Latn
+ case 0xDE0C0000u: // mqx -> Latn
+ case 0xE20C0000u: // mqy -> Latn
+ case 0xE60C0000u: // mqz -> Latn
+ case 0x862C0000u: // mrb -> Latn
+ case 0x8A2C0000u: // mrc -> Latn
+ case 0x962C0000u: // mrf -> Latn
+ case 0x9A2C0000u: // mrg -> Latn
+ case 0x9E2C0000u: // mrh -> Latn
+ case 0xAA2C0000u: // mrk -> Latn
+ case 0xAE2C0000u: // mrl -> Latn
+ case 0xB22C0000u: // mrm -> Latn
+ case 0xB62C0000u: // mrn -> Latn
+ case 0xBE2C0000u: // mrp -> Latn
+ case 0xC22C0000u: // mrq -> Latn
+ case 0xCA2C0000u: // mrs -> Latn
+ case 0xCE2C0000u: // mrt -> Latn
+ case 0xD22C0000u: // mru -> Latn
+ case 0xD62C0000u: // mrv -> Latn
+ case 0xDA2C0000u: // mrw -> Latn
+ case 0xDE2C0000u: // mrx -> Latn
+ case 0xE22C0000u: // mry -> Latn
+ case 0xE62C0000u: // mrz -> Latn
+ case 0x6D730000u: // ms -> Latn
+ case 0x864C0000u: // msb -> Latn
+ case 0x8A4C0000u: // msc -> Latn
+ case 0x924C0000u: // mse -> Latn
+ case 0x964C0000u: // msf -> Latn
+ case 0x9A4C0000u: // msg -> Latn
+ case 0x9E4C0000u: // msh -> Latn
+ case 0xA24C0000u: // msi -> Latn
+ case 0xA64C0000u: // msj -> Latn
+ case 0xAA4C0000u: // msk -> Latn
+ case 0xAE4C0000u: // msl -> Latn
+ case 0xB24C0000u: // msm -> Latn
+ case 0xB64C0000u: // msn -> Latn
+ case 0xBA4C0000u: // mso -> Latn
+ case 0xBE4C0000u: // msp -> Latn
+ case 0xC24C0000u: // msq -> Latn
+ case 0xCA4C0000u: // mss -> Latn
+ case 0xD24C0000u: // msu -> Latn
+ case 0xD64C0000u: // msv -> Latn
+ case 0xDA4C0000u: // msw -> Latn
+ case 0xDE4C0000u: // msx -> Latn
+ case 0xE24C0000u: // msy -> Latn
+ case 0xE64C0000u: // msz -> Latn
+ case 0x6D740000u: // mt -> Latn
+ case 0x826C0000u: // mta -> Latn
+ case 0x866C0000u: // mtb -> Latn
+ case 0x8A6C0000u: // mtc -> Latn
+ case 0x8E6C0000u: // mtd -> Latn
+ case 0x926C0000u: // mte -> Latn
+ case 0x966C0000u: // mtf -> Latn
+ case 0x9A6C0000u: // mtg -> Latn
+ case 0x9E6C0000u: // mth -> Latn
+ case 0xA26C0000u: // mti -> Latn
+ case 0xA66C0000u: // mtj -> Latn
+ case 0xAA6C0000u: // mtk -> Latn
+ case 0xAE6C0000u: // mtl -> Latn
+ case 0xB66C0000u: // mtn -> Latn
+ case 0xBA6C0000u: // mto -> Latn
+ case 0xBE6C0000u: // mtp -> Latn
+ case 0xC26C0000u: // mtq -> Latn
+ case 0xCA6C0000u: // mts -> Latn
+ case 0xCE6C0000u: // mtt -> Latn
+ case 0xD26C0000u: // mtu -> Latn
+ case 0xD66C0000u: // mtv -> Latn
+ case 0xDA6C0000u: // mtw -> Latn
+ case 0xDE6C0000u: // mtx -> Latn
+ case 0xE26C0000u: // mty -> Latn
+ case 0x828C0000u: // mua -> Latn
+ case 0x868C0000u: // mub -> Latn
+ case 0x8A8C0000u: // muc -> Latn
+ case 0x928C0000u: // mue -> Latn
+ case 0x9A8C0000u: // mug -> Latn
+ case 0x9E8C0000u: // muh -> Latn
+ case 0xA28C0000u: // mui -> Latn
+ case 0xA68C0000u: // muj -> Latn
+ case 0xB28C0000u: // mum -> Latn
+ case 0xBA8C0000u: // muo -> Latn
+ case 0xC28C0000u: // muq -> Latn
+ case 0xC68C0000u: // mur -> Latn
+ case 0xCA8C0000u: // mus -> Latn
+ case 0xD28C0000u: // muu -> Latn
+ case 0xDE8C0000u: // mux -> Latn
+ case 0xE28C0000u: // muy -> Latn
+ case 0x82AC0000u: // mva -> Latn
+ case 0x8EAC0000u: // mvd -> Latn
+ case 0x9AAC0000u: // mvg -> Latn
+ case 0x9EAC0000u: // mvh -> Latn
+ case 0xAAAC0000u: // mvk -> Latn
+ case 0xAEAC0000u: // mvl -> Latn
+ case 0xB6AC0000u: // mvn -> Latn
+ case 0xBAAC0000u: // mvo -> Latn
+ case 0xBEAC0000u: // mvp -> Latn
+ case 0xC2AC0000u: // mvq -> Latn
+ case 0xC6AC0000u: // mvr -> Latn
+ case 0xCAAC0000u: // mvs -> Latn
+ case 0xCEAC0000u: // mvt -> Latn
+ case 0xD2AC0000u: // mvu -> Latn
+ case 0xD6AC0000u: // mvv -> Latn
+ case 0xDAAC0000u: // mvw -> Latn
+ case 0xDEAC0000u: // mvx -> Latn
+ case 0x82CC0000u: // mwa -> Latn
+ case 0x86CC0000u: // mwb -> Latn
+ case 0x8ACC0000u: // mwc -> Latn
+ case 0x92CC0000u: // mwe -> Latn
+ case 0x96CC0000u: // mwf -> Latn
+ case 0x9ACC0000u: // mwg -> Latn
+ case 0x9ECC0000u: // mwh -> Latn
+ case 0xA2CC0000u: // mwi -> Latn
+ case 0xAACC0000u: // mwk -> Latn
+ case 0xAECC0000u: // mwl -> Latn
+ case 0xB2CC0000u: // mwm -> Latn
+ case 0xB6CC0000u: // mwn -> Latn
+ case 0xBACC0000u: // mwo -> Latn
+ case 0xBECC0000u: // mwp -> Latn
+ case 0xC2CC0000u: // mwq -> Latn
+ case 0xCACC0000u: // mws -> Latn
+ case 0xD2CC0000u: // mwu -> Latn
+ case 0xD6CC0000u: // mwv -> Latn
+ case 0xE6CC0000u: // mwz -> Latn
+ case 0x82EC0000u: // mxa -> Latn
+ case 0x86EC0000u: // mxb -> Latn
+ case 0x8AEC0000u: // mxc -> Latn
+ case 0x8EEC0000u: // mxd -> Latn
+ case 0x92EC0000u: // mxe -> Latn
+ case 0x96EC0000u: // mxf -> Latn
+ case 0x9AEC0000u: // mxg -> Latn
+ case 0x9EEC0000u: // mxh -> Latn
+ case 0xA2EC0000u: // mxi -> Latn
+ case 0xA6EC0000u: // mxj -> Latn
+ case 0xAAEC0000u: // mxk -> Latn
+ case 0xAEEC0000u: // mxl -> Latn
+ case 0xB2EC0000u: // mxm -> Latn
+ case 0xB6EC0000u: // mxn -> Latn
+ case 0xBAEC0000u: // mxo -> Latn
+ case 0xBEEC0000u: // mxp -> Latn
+ case 0xC2EC0000u: // mxq -> Latn
+ case 0xC6EC0000u: // mxr -> Latn
+ case 0xCAEC0000u: // mxs -> Latn
+ case 0xCEEC0000u: // mxt -> Latn
+ case 0xD2EC0000u: // mxu -> Latn
+ case 0xD6EC0000u: // mxv -> Latn
+ case 0xDAEC0000u: // mxw -> Latn
+ case 0xDEEC0000u: // mxx -> Latn
+ case 0xE2EC0000u: // mxy -> Latn
+ case 0xE6EC0000u: // mxz -> Latn
+ case 0x870C0000u: // myb -> Latn
+ case 0x8B0C0000u: // myc -> Latn
+ case 0x930C0000u: // mye -> Latn
+ case 0x970C0000u: // myf -> Latn
+ case 0x9B0C0000u: // myg -> Latn
+ case 0x9F0C0000u: // myh -> Latn
+ case 0xA70C0000u: // myj -> Latn
+ case 0xAB0C0000u: // myk -> Latn
+ case 0xAF0C0000u: // myl -> Latn
+ case 0xBF0C0000u: // myp -> Latn
+ case 0xC70C0000u: // myr -> Latn
+ case 0xD30C0000u: // myu -> Latn
+ case 0xDB0C0000u: // myw -> Latn
+ case 0xDF0C0000u: // myx -> Latn
+ case 0xE30C0000u: // myy -> Latn
+ case 0x832C0000u: // mza -> Latn
+ case 0x8F2C0000u: // mzd -> Latn
+ case 0x932C0000u: // mze -> Latn
+ case 0x9F2C0000u: // mzh -> Latn
+ case 0xA32C0000u: // mzi -> Latn
+ case 0xA72C0000u: // mzj -> Latn
+ case 0xAB2C0000u: // mzk -> Latn
+ case 0xAF2C0000u: // mzl -> Latn
+ case 0xB32C0000u: // mzm -> Latn
+ case 0xBB2C0000u: // mzo -> Latn
+ case 0xBF2C0000u: // mzp -> Latn
+ case 0xC32C0000u: // mzq -> Latn
+ case 0xC72C0000u: // mzr -> Latn
+ case 0xCF2C0000u: // mzt -> Latn
+ case 0xD32C0000u: // mzu -> Latn
+ case 0xD72C0000u: // mzv -> Latn
+ case 0xDB2C0000u: // mzw -> Latn
+ case 0xDF2C0000u: // mzx -> Latn
+ case 0xE72C0000u: // mzz -> Latn
+ case 0x6E610000u: // na -> Latn
+ case 0x800D0000u: // naa -> Latn
+ case 0x840D0000u: // nab -> Latn
+ case 0x880D0000u: // nac -> Latn
+ case 0x900D0000u: // nae -> Latn
+ case 0x940D0000u: // naf -> Latn
+ case 0x980D0000u: // nag -> Latn
+ case 0xA40D0000u: // naj -> Latn
+ case 0xA80D0000u: // nak -> Latn
+ case 0xAC0D0000u: // nal -> Latn
+ case 0xB00D0000u: // nam -> Latn
+ case 0xBC0D0000u: // nap -> Latn
+ case 0xC00D0000u: // naq -> Latn
+ case 0xC40D0000u: // nar -> Latn
+ case 0xC80D0000u: // nas -> Latn
+ case 0xCC0D0000u: // nat -> Latn
+ case 0xD80D0000u: // naw -> Latn
+ case 0xDC0D0000u: // nax -> Latn
+ case 0xE00D0000u: // nay -> Latn
+ case 0xE40D0000u: // naz -> Latn
+ case 0x6E620000u: // nb -> Latn
+ case 0x802D0000u: // nba -> Latn
+ case 0x842D0000u: // nbb -> Latn
+ case 0x882D0000u: // nbc -> Latn
+ case 0x8C2D0000u: // nbd -> Latn
+ case 0x902D0000u: // nbe -> Latn
+ case 0x9C2D0000u: // nbh -> Latn
+ case 0xA02D0000u: // nbi -> Latn
+ case 0xA42D0000u: // nbj -> Latn
+ case 0xA82D0000u: // nbk -> Latn
+ case 0xB02D0000u: // nbm -> Latn
+ case 0xB42D0000u: // nbn -> Latn
+ case 0xB82D0000u: // nbo -> Latn
+ case 0xBC2D0000u: // nbp -> Latn
+ case 0xC02D0000u: // nbq -> Latn
+ case 0xC42D0000u: // nbr -> Latn
+ case 0xCC2D0000u: // nbt -> Latn
+ case 0xD02D0000u: // nbu -> Latn
+ case 0xD42D0000u: // nbv -> Latn
+ case 0xD82D0000u: // nbw -> Latn
+ case 0xE02D0000u: // nby -> Latn
+ case 0x804D0000u: // nca -> Latn
+ case 0x844D0000u: // ncb -> Latn
+ case 0x884D0000u: // ncc -> Latn
+ case 0x904D0000u: // nce -> Latn
+ case 0x944D0000u: // ncf -> Latn
+ case 0x984D0000u: // ncg -> Latn
+ case 0x9C4D0000u: // nch -> Latn
+ case 0xA04D0000u: // nci -> Latn
+ case 0xA44D0000u: // ncj -> Latn
+ case 0xA84D0000u: // nck -> Latn
+ case 0xAC4D0000u: // ncl -> Latn
+ case 0xB04D0000u: // ncm -> Latn
+ case 0xB44D0000u: // ncn -> Latn
+ case 0xB84D0000u: // nco -> Latn
+ case 0xC44D0000u: // ncr -> Latn
+ case 0xCC4D0000u: // nct -> Latn
+ case 0xD04D0000u: // ncu -> Latn
+ case 0xDC4D0000u: // ncx -> Latn
+ case 0xE44D0000u: // ncz -> Latn
+ case 0x6E640000u: // nd -> Latn
+ case 0x806D0000u: // nda -> Latn
+ case 0x846D0000u: // ndb -> Latn
+ case 0x886D0000u: // ndc -> Latn
+ case 0x8C6D0000u: // ndd -> Latn
+ case 0x986D0000u: // ndg -> Latn
+ case 0x9C6D0000u: // ndh -> Latn
+ case 0xA06D0000u: // ndi -> Latn
+ case 0xA46D0000u: // ndj -> Latn
+ case 0xA86D0000u: // ndk -> Latn
+ case 0xAC6D0000u: // ndl -> Latn
+ case 0xB06D0000u: // ndm -> Latn
+ case 0xB46D0000u: // ndn -> Latn
+ case 0xBC6D0000u: // ndp -> Latn
+ case 0xC06D0000u: // ndq -> Latn
+ case 0xC46D0000u: // ndr -> Latn
+ case 0xC86D0000u: // nds -> Latn
+ case 0xCC6D0000u: // ndt -> Latn
+ case 0xD06D0000u: // ndu -> Latn
+ case 0xD46D0000u: // ndv -> Latn
+ case 0xD86D0000u: // ndw -> Latn
+ case 0xDC6D0000u: // ndx -> Latn
+ case 0xE06D0000u: // ndy -> Latn
+ case 0xE46D0000u: // ndz -> Latn
+ case 0x808D0000u: // nea -> Latn
+ case 0x848D0000u: // neb -> Latn
+ case 0x888D0000u: // nec -> Latn
+ case 0x8C8D0000u: // ned -> Latn
+ case 0x908D0000u: // nee -> Latn
+ case 0xA48D0000u: // nej -> Latn
+ case 0xA88D0000u: // nek -> Latn
+ case 0xB08D0000u: // nem -> Latn
+ case 0xB48D0000u: // nen -> Latn
+ case 0xB88D0000u: // neo -> Latn
+ case 0xC08D0000u: // neq -> Latn
+ case 0xC48D0000u: // ner -> Latn
+ case 0xCC8D0000u: // net -> Latn
+ case 0xD08D0000u: // neu -> Latn
+ case 0xDC8D0000u: // nex -> Latn
+ case 0xE08D0000u: // ney -> Latn
+ case 0xE48D0000u: // nez -> Latn
+ case 0x80AD0000u: // nfa -> Latn
+ case 0x8CAD0000u: // nfd -> Latn
+ case 0xACAD0000u: // nfl -> Latn
+ case 0xC4AD0000u: // nfr -> Latn
+ case 0xD0AD0000u: // nfu -> Latn
+ case 0x6E670000u: // ng -> Latn
+ case 0x80CD0000u: // nga -> Latn
+ case 0x84CD0000u: // ngb -> Latn
+ case 0x88CD0000u: // ngc -> Latn
+ case 0x8CCD0000u: // ngd -> Latn
+ case 0x90CD0000u: // nge -> Latn
+ case 0x98CD0000u: // ngg -> Latn
+ case 0x9CCD0000u: // ngh -> Latn
+ case 0xA0CD0000u: // ngi -> Latn
+ case 0xA4CD0000u: // ngj -> Latn
+ case 0xA8CD0000u: // ngk -> Latn
+ case 0xACCD0000u: // ngl -> Latn
+ case 0xB0CD0000u: // ngm -> Latn
+ case 0xB4CD0000u: // ngn -> Latn
+ case 0xBCCD0000u: // ngp -> Latn
+ case 0xC0CD0000u: // ngq -> Latn
+ case 0xC4CD0000u: // ngr -> Latn
+ case 0xC8CD0000u: // ngs -> Latn
+ case 0xD0CD0000u: // ngu -> Latn
+ case 0xD4CD0000u: // ngv -> Latn
+ case 0xD8CD0000u: // ngw -> Latn
+ case 0xDCCD0000u: // ngx -> Latn
+ case 0xE0CD0000u: // ngy -> Latn
+ case 0xE4CD0000u: // ngz -> Latn
+ case 0x80ED0000u: // nha -> Latn
+ case 0x84ED0000u: // nhb -> Latn
+ case 0x88ED0000u: // nhc -> Latn
+ case 0x8CED0000u: // nhd -> Latn
+ case 0x90ED0000u: // nhe -> Latn
+ case 0x94ED0000u: // nhf -> Latn
+ case 0x98ED0000u: // nhg -> Latn
+ case 0xA0ED0000u: // nhi -> Latn
+ case 0xA8ED0000u: // nhk -> Latn
+ case 0xB0ED0000u: // nhm -> Latn
+ case 0xB4ED0000u: // nhn -> Latn
+ case 0xB8ED0000u: // nho -> Latn
+ case 0xBCED0000u: // nhp -> Latn
+ case 0xC0ED0000u: // nhq -> Latn
+ case 0xC4ED0000u: // nhr -> Latn
+ case 0xCCED0000u: // nht -> Latn
+ case 0xD0ED0000u: // nhu -> Latn
+ case 0xD4ED0000u: // nhv -> Latn
+ case 0xD8ED0000u: // nhw -> Latn
+ case 0xDCED0000u: // nhx -> Latn
+ case 0xE0ED0000u: // nhy -> Latn
+ case 0xE4ED0000u: // nhz -> Latn
+ case 0x810D0000u: // nia -> Latn
+ case 0x850D0000u: // nib -> Latn
+ case 0x8D0D0000u: // nid -> Latn
+ case 0x910D0000u: // nie -> Latn
+ case 0x950D0000u: // nif -> Latn
+ case 0x990D0000u: // nig -> Latn
+ case 0x9D0D0000u: // nih -> Latn
+ case 0xA10D0000u: // nii -> Latn
+ case 0xA50D0000u: // nij -> Latn
+ case 0xAD0D0000u: // nil -> Latn
+ case 0xB10D0000u: // nim -> Latn
+ case 0xB50D0000u: // nin -> Latn
+ case 0xC10D0000u: // niq -> Latn
+ case 0xC50D0000u: // nir -> Latn
+ case 0xC90D0000u: // nis -> Latn
+ case 0xD10D0000u: // niu -> Latn
+ case 0xD90D0000u: // niw -> Latn
+ case 0xDD0D0000u: // nix -> Latn
+ case 0xE10D0000u: // niy -> Latn
+ case 0xE50D0000u: // niz -> Latn
+ case 0x812D0000u: // nja -> Latn
+ case 0x852D0000u: // njb -> Latn
+ case 0x8D2D0000u: // njd -> Latn
+ case 0x9D2D0000u: // njh -> Latn
+ case 0xA12D0000u: // nji -> Latn
+ case 0xA52D0000u: // njj -> Latn
+ case 0xAD2D0000u: // njl -> Latn
+ case 0xB12D0000u: // njm -> Latn
+ case 0xB52D0000u: // njn -> Latn
+ case 0xB92D0000u: // njo -> Latn
+ case 0xC52D0000u: // njr -> Latn
+ case 0xC92D0000u: // njs -> Latn
+ case 0xCD2D0000u: // njt -> Latn
+ case 0xD12D0000u: // nju -> Latn
+ case 0xDD2D0000u: // njx -> Latn
+ case 0xE12D0000u: // njy -> Latn
+ case 0xE52D0000u: // njz -> Latn
+ case 0x814D0000u: // nka -> Latn
+ case 0x854D0000u: // nkb -> Latn
+ case 0x894D0000u: // nkc -> Latn
+ case 0x8D4D0000u: // nkd -> Latn
+ case 0x914D0000u: // nke -> Latn
+ case 0x954D0000u: // nkf -> Latn
+ case 0x994D0000u: // nkg -> Latn
+ case 0x9D4D0000u: // nkh -> Latn
+ case 0xA14D0000u: // nki -> Latn
+ case 0xA54D0000u: // nkj -> Latn
+ case 0xA94D0000u: // nkk -> Latn
+ case 0xB14D0000u: // nkm -> Latn
+ case 0xB54D0000u: // nkn -> Latn
+ case 0xB94D0000u: // nko -> Latn
+ case 0xC14D0000u: // nkq -> Latn
+ case 0xC54D0000u: // nkr -> Latn
+ case 0xC94D0000u: // nks -> Latn
+ case 0xCD4D0000u: // nkt -> Latn
+ case 0xD14D0000u: // nku -> Latn
+ case 0xD54D0000u: // nkv -> Latn
+ case 0xD94D0000u: // nkw -> Latn
+ case 0xDD4D0000u: // nkx -> Latn
+ case 0xE54D0000u: // nkz -> Latn
+ case 0x6E6C0000u: // nl -> Latn
+ case 0x816D0000u: // nla -> Latn
+ case 0x896D0000u: // nlc -> Latn
+ case 0x916D0000u: // nle -> Latn
+ case 0x996D0000u: // nlg -> Latn
+ case 0xA56D0000u: // nlj -> Latn
+ case 0xA96D0000u: // nlk -> Latn
+ case 0xB96D0000u: // nlo -> Latn
+ case 0xC16D0000u: // nlq -> Latn
+ case 0xD16D0000u: // nlu -> Latn
+ case 0xD56D0000u: // nlv -> Latn
+ case 0xD96D0000u: // nlw -> Latn
+ case 0xE16D0000u: // nly -> Latn
+ case 0xE56D0000u: // nlz -> Latn
+ case 0x818D0000u: // nma -> Latn
+ case 0x858D0000u: // nmb -> Latn
+ case 0x898D0000u: // nmc -> Latn
+ case 0x8D8D0000u: // nmd -> Latn
+ case 0x918D0000u: // nme -> Latn
+ case 0x958D0000u: // nmf -> Latn
+ case 0x998D0000u: // nmg -> Latn
+ case 0x9D8D0000u: // nmh -> Latn
+ case 0xA18D0000u: // nmi -> Latn
+ case 0xA58D0000u: // nmj -> Latn
+ case 0xA98D0000u: // nmk -> Latn
+ case 0xAD8D0000u: // nml -> Latn
+ case 0xB58D0000u: // nmn -> Latn
+ case 0xB98D0000u: // nmo -> Latn
+ case 0xBD8D0000u: // nmp -> Latn
+ case 0xC18D0000u: // nmq -> Latn
+ case 0xC58D0000u: // nmr -> Latn
+ case 0xC98D0000u: // nms -> Latn
+ case 0xCD8D0000u: // nmt -> Latn
+ case 0xD18D0000u: // nmu -> Latn
+ case 0xD58D0000u: // nmv -> Latn
+ case 0xD98D0000u: // nmw -> Latn
+ case 0xDD8D0000u: // nmx -> Latn
+ case 0xE58D0000u: // nmz -> Latn
+ case 0x6E6E0000u: // nn -> Latn
+ case 0x81AD0000u: // nna -> Latn
+ case 0x85AD0000u: // nnb -> Latn
+ case 0x89AD0000u: // nnc -> Latn
+ case 0x8DAD0000u: // nnd -> Latn
+ case 0x91AD0000u: // nne -> Latn
+ case 0x95AD0000u: // nnf -> Latn
+ case 0x99AD0000u: // nng -> Latn
+ case 0x9DAD0000u: // nnh -> Latn
+ case 0xA1AD0000u: // nni -> Latn
+ case 0xA5AD0000u: // nnj -> Latn
+ case 0xA9AD0000u: // nnk -> Latn
+ case 0xADAD0000u: // nnl -> Latn
+ case 0xB1AD0000u: // nnm -> Latn
+ case 0xB5AD0000u: // nnn -> Latn
+ case 0xC1AD0000u: // nnq -> Latn
+ case 0xC5AD0000u: // nnr -> Latn
+ case 0xCDAD0000u: // nnt -> Latn
+ case 0xD1AD0000u: // nnu -> Latn
+ case 0xD5AD0000u: // nnv -> Latn
+ case 0xD9AD0000u: // nnw -> Latn
+ case 0xE1AD0000u: // nny -> Latn
+ case 0xE5AD0000u: // nnz -> Latn
+ case 0x6E6F0000u: // no -> Latn
+ case 0x81CD0000u: // noa -> Latn
+ case 0x89CD0000u: // noc -> Latn
+ case 0x95CD0000u: // nof -> Latn
+ case 0x9DCD0000u: // noh -> Latn
+ case 0xA5CD0000u: // noj -> Latn
+ case 0xA9CD0000u: // nok -> Latn
+ case 0xBDCD0000u: // nop -> Latn
+ case 0xC1CD0000u: // noq -> Latn
+ case 0xCDCD0000u: // not -> Latn
+ case 0xD1CD0000u: // nou -> Latn
+ case 0xD5CD0000u: // nov -> Latn
+ case 0xD9CD0000u: // now -> Latn
+ case 0xE1CD0000u: // noy -> Latn
+ case 0x99ED0000u: // npg -> Latn
+ case 0x9DED0000u: // nph -> Latn
+ case 0xADED0000u: // npl -> Latn
+ case 0xB5ED0000u: // npn -> Latn
+ case 0xB9ED0000u: // npo -> Latn
+ case 0xC9ED0000u: // nps -> Latn
+ case 0xD1ED0000u: // npu -> Latn
+ case 0xDDED0000u: // npx -> Latn
+ case 0xE1ED0000u: // npy -> Latn
+ case 0x9A0D0000u: // nqg -> Latn
+ case 0xAA0D0000u: // nqk -> Latn
+ case 0xAE0D0000u: // nql -> Latn
+ case 0xB20D0000u: // nqm -> Latn
+ case 0xB60D0000u: // nqn -> Latn
+ case 0xC20D0000u: // nqq -> Latn
+ case 0xCE0D0000u: // nqt -> Latn
+ case 0xE20D0000u: // nqy -> Latn
+ case 0x6E720000u: // nr -> Latn
+ case 0x822D0000u: // nra -> Latn
+ case 0x862D0000u: // nrb -> Latn
+ case 0x922D0000u: // nre -> Latn
+ case 0x962D0000u: // nrf -> Latn
+ case 0x9A2D0000u: // nrg -> Latn
+ case 0xA22D0000u: // nri -> Latn
+ case 0xAA2D0000u: // nrk -> Latn
+ case 0xAE2D0000u: // nrl -> Latn
+ case 0xB22D0000u: // nrm -> Latn
+ case 0xBE2D0000u: // nrp -> Latn
+ case 0xD22D0000u: // nru -> Latn
+ case 0xDE2D0000u: // nrx -> Latn
+ case 0xE62D0000u: // nrz -> Latn
+ case 0x824D0000u: // nsa -> Latn
+ case 0x864D0000u: // nsb -> Latn
+ case 0x8A4D0000u: // nsc -> Latn
+ case 0x924D0000u: // nse -> Latn
+ case 0x9A4D0000u: // nsg -> Latn
+ case 0x9E4D0000u: // nsh -> Latn
+ case 0xB24D0000u: // nsm -> Latn
+ case 0xB64D0000u: // nsn -> Latn
+ case 0xBA4D0000u: // nso -> Latn
+ case 0xC24D0000u: // nsq -> Latn
+ case 0xCA4D0000u: // nss -> Latn
+ case 0xD24D0000u: // nsu -> Latn
+ case 0xDA4D0000u: // nsw -> Latn
+ case 0xDE4D0000u: // nsx -> Latn
+ case 0xE24D0000u: // nsy -> Latn
+ case 0xE64D0000u: // nsz -> Latn
+ case 0x8E6D0000u: // ntd -> Latn
+ case 0x926D0000u: // nte -> Latn
+ case 0x9A6D0000u: // ntg -> Latn
+ case 0xA26D0000u: // nti -> Latn
+ case 0xA66D0000u: // ntj -> Latn
+ case 0xAA6D0000u: // ntk -> Latn
+ case 0xB26D0000u: // ntm -> Latn
+ case 0xBA6D0000u: // nto -> Latn
+ case 0xBE6D0000u: // ntp -> Latn
+ case 0xC66D0000u: // ntr -> Latn
+ case 0xD26D0000u: // ntu -> Latn
+ case 0xDE6D0000u: // ntx -> Latn
+ case 0x828D0000u: // nua -> Latn
+ case 0x8A8D0000u: // nuc -> Latn
+ case 0x8E8D0000u: // nud -> Latn
+ case 0x928D0000u: // nue -> Latn
+ case 0x968D0000u: // nuf -> Latn
+ case 0x9A8D0000u: // nug -> Latn
+ case 0x9E8D0000u: // nuh -> Latn
+ case 0xA28D0000u: // nui -> Latn
+ case 0xA68D0000u: // nuj -> Latn
+ case 0xAA8D0000u: // nuk -> Latn
+ case 0xB28D0000u: // num -> Latn
+ case 0xB68D0000u: // nun -> Latn
+ case 0xBA8D0000u: // nuo -> Latn
+ case 0xBE8D0000u: // nup -> Latn
+ case 0xC28D0000u: // nuq -> Latn
+ case 0xC68D0000u: // nur -> Latn
+ case 0xCA8D0000u: // nus -> Latn
+ case 0xCE8D0000u: // nut -> Latn
+ case 0xD28D0000u: // nuu -> Latn
+ case 0xD68D0000u: // nuv -> Latn
+ case 0xDA8D0000u: // nuw -> Latn
+ case 0xDE8D0000u: // nux -> Latn
+ case 0xE28D0000u: // nuy -> Latn
+ case 0xE68D0000u: // nuz -> Latn
+ case 0x6E760000u: // nv -> Latn
+ case 0x9EAD0000u: // nvh -> Latn
+ case 0xB2AD0000u: // nvm -> Latn
+ case 0xBAAD0000u: // nvo -> Latn
+ case 0x86CD0000u: // nwb -> Latn
+ case 0x92CD0000u: // nwe -> Latn
+ case 0x9ACD0000u: // nwg -> Latn
+ case 0xA2CD0000u: // nwi -> Latn
+ case 0xB2CD0000u: // nwm -> Latn
+ case 0xBACD0000u: // nwo -> Latn
+ case 0xC6CD0000u: // nwr -> Latn
+ case 0xDACD0000u: // nww -> Latn
+ case 0x82ED0000u: // nxa -> Latn
+ case 0x8EED0000u: // nxd -> Latn
+ case 0x92ED0000u: // nxe -> Latn
+ case 0x9AED0000u: // nxg -> Latn
+ case 0xA2ED0000u: // nxi -> Latn
+ case 0xAEED0000u: // nxl -> Latn
+ case 0xB6ED0000u: // nxn -> Latn
+ case 0xBAED0000u: // nxo -> Latn
+ case 0xC2ED0000u: // nxq -> Latn
+ case 0xC6ED0000u: // nxr -> Latn
+ case 0xDEED0000u: // nxx -> Latn
+ case 0x6E790000u: // ny -> Latn
+ case 0x870D0000u: // nyb -> Latn
+ case 0x8B0D0000u: // nyc -> Latn
+ case 0x8F0D0000u: // nyd -> Latn
+ case 0x930D0000u: // nye -> Latn
+ case 0x970D0000u: // nyf -> Latn
+ case 0x9B0D0000u: // nyg -> Latn
+ case 0x9F0D0000u: // nyh -> Latn
+ case 0xA30D0000u: // nyi -> Latn
+ case 0xA70D0000u: // nyj -> Latn
+ case 0xAB0D0000u: // nyk -> Latn
+ case 0xB30D0000u: // nym -> Latn
+ case 0xB70D0000u: // nyn -> Latn
+ case 0xBB0D0000u: // nyo -> Latn
+ case 0xBF0D0000u: // nyp -> Latn
+ case 0xC70D0000u: // nyr -> Latn
+ case 0xCB0D0000u: // nys -> Latn
+ case 0xCF0D0000u: // nyt -> Latn
+ case 0xD30D0000u: // nyu -> Latn
+ case 0xD70D0000u: // nyv -> Latn
+ case 0xDF0D0000u: // nyx -> Latn
+ case 0xE30D0000u: // nyy -> Latn
+ case 0x832D0000u: // nza -> Latn
+ case 0x872D0000u: // nzb -> Latn
+ case 0x8F2D0000u: // nzd -> Latn
+ case 0xA32D0000u: // nzi -> Latn
+ case 0xAB2D0000u: // nzk -> Latn
+ case 0xB32D0000u: // nzm -> Latn
+ case 0xC72D0000u: // nzr -> Latn
+ case 0xD32D0000u: // nzu -> Latn
+ case 0xE32D0000u: // nzy -> Latn
+ case 0xE72D0000u: // nzz -> Latn
+ case 0xA02E0000u: // obi -> Latn
+ case 0xA82E0000u: // obk -> Latn
+ case 0xAC2E0000u: // obl -> Latn
+ case 0xB82E0000u: // obo -> Latn
+ case 0xCC2E0000u: // obt -> Latn
+ case 0xD02E0000u: // obu -> Latn
+ case 0x6F630000u: // oc -> Latn
+ case 0x804E0000u: // oca -> Latn
+ case 0xB84E0000u: // oco -> Latn
+ case 0xD04E0000u: // ocu -> Latn
+ case 0x806E0000u: // oda -> Latn
+ case 0xCC6E0000u: // odt -> Latn
+ case 0xD06E0000u: // odu -> Latn
+ case 0xC8AE0000u: // ofs -> Latn
+ case 0xD0AE0000u: // ofu -> Latn
+ case 0x84CE0000u: // ogb -> Latn
+ case 0x88CE0000u: // ogc -> Latn
+ case 0x98CE0000u: // ogg -> Latn
+ case 0xB8CE0000u: // ogo -> Latn
+ case 0xD0CE0000u: // ogu -> Latn
+ case 0xD0EE0000u: // ohu -> Latn
+ case 0x810E0000u: // oia -> Latn
+ case 0x910E0000u: // oie -> Latn
+ case 0xB50E0000u: // oin -> Latn
+ case 0x852E0000u: // ojb -> Latn
+ case 0x892E0000u: // ojc -> Latn
+ case 0xD52E0000u: // ojv -> Latn
+ case 0xD92E0000u: // ojw -> Latn
+ case 0x814E0000u: // oka -> Latn
+ case 0x854E0000u: // okb -> Latn
+ case 0x894E0000u: // okc -> Latn
+ case 0x8D4E0000u: // okd -> Latn
+ case 0x914E0000u: // oke -> Latn
+ case 0x994E0000u: // okg -> Latn
+ case 0xA14E0000u: // oki -> Latn
+ case 0xA94E0000u: // okk -> Latn
+ case 0xC54E0000u: // okr -> Latn
+ case 0xC94E0000u: // oks -> Latn
+ case 0xD14E0000u: // oku -> Latn
+ case 0xD54E0000u: // okv -> Latn
+ case 0xDD4E0000u: // okx -> Latn
+ case 0x8D6E0000u: // old -> Latn
+ case 0xA96E0000u: // olk -> Latn
+ case 0xB16E0000u: // olm -> Latn
+ case 0xB96E0000u: // olo -> Latn
+ case 0xC56E0000u: // olr -> Latn
+ case 0xCD6E0000u: // olt -> Latn
+ case 0xD16E0000u: // olu -> Latn
+ case 0x6F6D0000u: // om -> Latn
+ case 0x818E0000u: // oma -> Latn
+ case 0x858E0000u: // omb -> Latn
+ case 0x898E0000u: // omc -> Latn
+ case 0x998E0000u: // omg -> Latn
+ case 0xA18E0000u: // omi -> Latn
+ case 0xAD8E0000u: // oml -> Latn
+ case 0xB98E0000u: // omo -> Latn
+ case 0xCD8E0000u: // omt -> Latn
+ case 0xD18E0000u: // omu -> Latn
+ case 0xD98E0000u: // omw -> Latn
+ case 0x81AE0000u: // ona -> Latn
+ case 0x91AE0000u: // one -> Latn
+ case 0x99AE0000u: // ong -> Latn
+ case 0xA1AE0000u: // oni -> Latn
+ case 0xA5AE0000u: // onj -> Latn
+ case 0xA9AE0000u: // onk -> Latn
+ case 0xB5AE0000u: // onn -> Latn
+ case 0xB9AE0000u: // ono -> Latn
+ case 0xBDAE0000u: // onp -> Latn
+ case 0xC5AE0000u: // onr -> Latn
+ case 0xC9AE0000u: // ons -> Latn
+ case 0xCDAE0000u: // ont -> Latn
+ case 0xD1AE0000u: // onu -> Latn
+ case 0xDDAE0000u: // onx -> Latn
+ case 0x8DCE0000u: // ood -> Latn
+ case 0xC5CE0000u: // oor -> Latn
+ case 0x81EE0000u: // opa -> Latn
+ case 0xA9EE0000u: // opk -> Latn
+ case 0xB1EE0000u: // opm -> Latn
+ case 0xB9EE0000u: // opo -> Latn
+ case 0xCDEE0000u: // opt -> Latn
+ case 0xE1EE0000u: // opy -> Latn
+ case 0x822E0000u: // ora -> Latn
+ case 0x8A2E0000u: // orc -> Latn
+ case 0x922E0000u: // ore -> Latn
+ case 0x9A2E0000u: // org -> Latn
+ case 0xB62E0000u: // orn -> Latn
+ case 0xBA2E0000u: // oro -> Latn
+ case 0xC62E0000u: // orr -> Latn
+ case 0xCA2E0000u: // ors -> Latn
+ case 0xDA2E0000u: // orw -> Latn
+ case 0xDE2E0000u: // orx -> Latn
+ case 0xE62E0000u: // orz -> Latn
+ case 0xBA4E0000u: // oso -> Latn
+ case 0xBE4E0000u: // osp -> Latn
+ case 0xCE4E0000u: // ost -> Latn
+ case 0xD24E0000u: // osu -> Latn
+ case 0xDE4E0000u: // osx -> Latn
+ case 0x8E6E0000u: // otd -> Latn
+ case 0x926E0000u: // ote -> Latn
+ case 0xA26E0000u: // oti -> Latn
+ case 0xAE6E0000u: // otl -> Latn
+ case 0xB26E0000u: // otm -> Latn
+ case 0xB66E0000u: // otn -> Latn
+ case 0xC26E0000u: // otq -> Latn
+ case 0xC66E0000u: // otr -> Latn
+ case 0xCA6E0000u: // ots -> Latn
+ case 0xCE6E0000u: // ott -> Latn
+ case 0xD26E0000u: // otu -> Latn
+ case 0xDA6E0000u: // otw -> Latn
+ case 0xDE6E0000u: // otx -> Latn
+ case 0xE66E0000u: // otz -> Latn
+ case 0x868E0000u: // oub -> Latn
+ case 0x928E0000u: // oue -> Latn
+ case 0xB28E0000u: // oum -> Latn
+ case 0x8EAE0000u: // ovd -> Latn
+ case 0xA2CE0000u: // owi -> Latn
+ case 0xAECE0000u: // owl -> Latn
+ case 0x8F0E0000u: // oyd -> Latn
+ case 0xB30E0000u: // oym -> Latn
+ case 0xE30E0000u: // oyy -> Latn
+ case 0xB32E0000u: // ozm -> Latn
+ case 0x840F0000u: // pab -> Latn
+ case 0x880F0000u: // pac -> Latn
+ case 0x8C0F0000u: // pad -> Latn
+ case 0x900F0000u: // pae -> Latn
+ case 0x940F0000u: // paf -> Latn
+ case 0x980F0000u: // pag -> Latn
+ case 0x9C0F0000u: // pah -> Latn
+ case 0xA00F0000u: // pai -> Latn
+ case 0xA80F0000u: // pak -> Latn
+ case 0xB00F0000u: // pam -> Latn
+ case 0xB80F0000u: // pao -> Latn
+ case 0xBC0F0000u: // pap -> Latn
+ case 0xC40F0000u: // par -> Latn
+ case 0xC80F0000u: // pas -> Latn
+ case 0xD00F0000u: // pau -> Latn
+ case 0xD40F0000u: // pav -> Latn
+ case 0xD80F0000u: // paw -> Latn
+ case 0xDC0F0000u: // pax -> Latn
+ case 0xE00F0000u: // pay -> Latn
+ case 0xE40F0000u: // paz -> Latn
+ case 0x842F0000u: // pbb -> Latn
+ case 0x882F0000u: // pbc -> Latn
+ case 0x902F0000u: // pbe -> Latn
+ case 0x942F0000u: // pbf -> Latn
+ case 0x982F0000u: // pbg -> Latn
+ case 0x9C2F0000u: // pbh -> Latn
+ case 0xA02F0000u: // pbi -> Latn
+ case 0xAC2F0000u: // pbl -> Latn
+ case 0xB02F0000u: // pbm -> Latn
+ case 0xB42F0000u: // pbn -> Latn
+ case 0xB82F0000u: // pbo -> Latn
+ case 0xBC2F0000u: // pbp -> Latn
+ case 0xC42F0000u: // pbr -> Latn
+ case 0xC82F0000u: // pbs -> Latn
+ case 0xD42F0000u: // pbv -> Latn
+ case 0xE02F0000u: // pby -> Latn
+ case 0x804F0000u: // pca -> Latn
+ case 0x884F0000u: // pcc -> Latn
+ case 0x8C4F0000u: // pcd -> Latn
+ case 0xA84F0000u: // pck -> Latn
+ case 0xB04F0000u: // pcm -> Latn
+ case 0xB44F0000u: // pcn -> Latn
+ case 0xBC4F0000u: // pcp -> Latn
+ case 0xD84F0000u: // pcw -> Latn
+ case 0x806F0000u: // pda -> Latn
+ case 0x886F0000u: // pdc -> Latn
+ case 0xB46F0000u: // pdn -> Latn
+ case 0xB86F0000u: // pdo -> Latn
+ case 0xCC6F0000u: // pdt -> Latn
+ case 0xD06F0000u: // pdu -> Latn
+ case 0x808F0000u: // pea -> Latn
+ case 0x848F0000u: // peb -> Latn
+ case 0x8C8F0000u: // ped -> Latn
+ case 0x908F0000u: // pee -> Latn
+ case 0xA08F0000u: // pei -> Latn
+ case 0xA88F0000u: // pek -> Latn
+ case 0xAC8F0000u: // pel -> Latn
+ case 0xB08F0000u: // pem -> Latn
+ case 0xBC8F0000u: // pep -> Latn
+ case 0xC08F0000u: // peq -> Latn
+ case 0xD48F0000u: // pev -> Latn
+ case 0xDC8F0000u: // pex -> Latn
+ case 0xE08F0000u: // pey -> Latn
+ case 0xE48F0000u: // pez -> Latn
+ case 0x80AF0000u: // pfa -> Latn
+ case 0x90AF0000u: // pfe -> Latn
+ case 0xACAF0000u: // pfl -> Latn
+ case 0x80CF0000u: // pga -> Latn
+ case 0xA0CF0000u: // pgi -> Latn
+ case 0xA8CF0000u: // pgk -> Latn
+ case 0xC8CF0000u: // pgs -> Latn
+ case 0xD0CF0000u: // pgu -> Latn
+ case 0x98EF0000u: // phg -> Latn
+ case 0x9CEF0000u: // phh -> Latn
+ case 0xB0EF0000u: // phm -> Latn
+ case 0x810F0000u: // pia -> Latn
+ case 0x850F0000u: // pib -> Latn
+ case 0x890F0000u: // pic -> Latn
+ case 0x8D0F0000u: // pid -> Latn
+ case 0x950F0000u: // pif -> Latn
+ case 0x990F0000u: // pig -> Latn
+ case 0x9D0F0000u: // pih -> Latn
+ case 0xA50F0000u: // pij -> Latn
+ case 0xAD0F0000u: // pil -> Latn
+ case 0xB10F0000u: // pim -> Latn
+ case 0xB50F0000u: // pin -> Latn
+ case 0xB90F0000u: // pio -> Latn
+ case 0xBD0F0000u: // pip -> Latn
+ case 0xC50F0000u: // pir -> Latn
+ case 0xC90F0000u: // pis -> Latn
+ case 0xCD0F0000u: // pit -> Latn
+ case 0xD10F0000u: // piu -> Latn
+ case 0xD50F0000u: // piv -> Latn
+ case 0xD90F0000u: // piw -> Latn
+ case 0xDD0F0000u: // pix -> Latn
+ case 0xE10F0000u: // piy -> Latn
+ case 0xE50F0000u: // piz -> Latn
+ case 0xCD2F0000u: // pjt -> Latn
+ case 0x854F0000u: // pkb -> Latn
+ case 0x994F0000u: // pkg -> Latn
+ case 0x9D4F0000u: // pkh -> Latn
+ case 0xB54F0000u: // pkn -> Latn
+ case 0xB94F0000u: // pko -> Latn
+ case 0xBD4F0000u: // pkp -> Latn
+ case 0xD14F0000u: // pku -> Latn
+ case 0x706C0000u: // pl -> Latn
+ case 0x816F0000u: // pla -> Latn
+ case 0x856F0000u: // plb -> Latn
+ case 0x896F0000u: // plc -> Latn
+ case 0x8D6F0000u: // pld -> Latn
+ case 0x916F0000u: // ple -> Latn
+ case 0x996F0000u: // plg -> Latn
+ case 0x9D6F0000u: // plh -> Latn
+ case 0xB56F0000u: // pln -> Latn
+ case 0xB96F0000u: // plo -> Latn
+ case 0xC56F0000u: // plr -> Latn
+ case 0xC96F0000u: // pls -> Latn
+ case 0xD16F0000u: // plu -> Latn
+ case 0xD56F0000u: // plv -> Latn
+ case 0xD96F0000u: // plw -> Latn
+ case 0xE56F0000u: // plz -> Latn
+ case 0x818F0000u: // pma -> Latn
+ case 0x858F0000u: // pmb -> Latn
+ case 0x8D8F0000u: // pmd -> Latn
+ case 0x918F0000u: // pme -> Latn
+ case 0x958F0000u: // pmf -> Latn
+ case 0xA18F0000u: // pmi -> Latn
+ case 0xA58F0000u: // pmj -> Latn
+ case 0xAD8F0000u: // pml -> Latn
+ case 0xB18F0000u: // pmm -> Latn
+ case 0xB58F0000u: // pmn -> Latn
+ case 0xB98F0000u: // pmo -> Latn
+ case 0xC18F0000u: // pmq -> Latn
+ case 0xC58F0000u: // pmr -> Latn
+ case 0xC98F0000u: // pms -> Latn
+ case 0xCD8F0000u: // pmt -> Latn
+ case 0xD98F0000u: // pmw -> Latn
+ case 0xDD8F0000u: // pmx -> Latn
+ case 0xE18F0000u: // pmy -> Latn
+ case 0xE58F0000u: // pmz -> Latn
+ case 0x81AF0000u: // pna -> Latn
+ case 0x89AF0000u: // pnc -> Latn
+ case 0x8DAF0000u: // pnd -> Latn
+ case 0x91AF0000u: // pne -> Latn
+ case 0x99AF0000u: // png -> Latn
+ case 0x9DAF0000u: // pnh -> Latn
+ case 0xA1AF0000u: // pni -> Latn
+ case 0xA5AF0000u: // pnj -> Latn
+ case 0xA9AF0000u: // pnk -> Latn
+ case 0xADAF0000u: // pnl -> Latn
+ case 0xB1AF0000u: // pnm -> Latn
+ case 0xB5AF0000u: // pnn -> Latn
+ case 0xB9AF0000u: // pno -> Latn
+ case 0xBDAF0000u: // pnp -> Latn
+ case 0xC1AF0000u: // pnq -> Latn
+ case 0xC5AF0000u: // pnr -> Latn
+ case 0xC9AF0000u: // pns -> Latn
+ case 0xD5AF0000u: // pnv -> Latn
+ case 0xD9AF0000u: // pnw -> Latn
+ case 0xE1AF0000u: // pny -> Latn
+ case 0xE5AF0000u: // pnz -> Latn
+ case 0x89CF0000u: // poc -> Latn
+ case 0x91CF0000u: // poe -> Latn
+ case 0x95CF0000u: // pof -> Latn
+ case 0x99CF0000u: // pog -> Latn
+ case 0x9DCF0000u: // poh -> Latn
+ case 0xA1CF0000u: // poi -> Latn
+ case 0xA9CF0000u: // pok -> Latn
+ case 0xB1CF0000u: // pom -> Latn
+ case 0xB5CF0000u: // pon -> Latn
+ case 0xB9CF0000u: // poo -> Latn
+ case 0xBDCF0000u: // pop -> Latn
+ case 0xC1CF0000u: // poq -> Latn
+ case 0xC9CF0000u: // pos -> Latn
+ case 0xCDCF0000u: // pot -> Latn
+ case 0xD5CF0000u: // pov -> Latn
+ case 0xD9CF0000u: // pow -> Latn
+ case 0xE1CF0000u: // poy -> Latn
+ case 0x91EF0000u: // ppe -> Latn
+ case 0xA1EF0000u: // ppi -> Latn
+ case 0xA9EF0000u: // ppk -> Latn
+ case 0xADEF0000u: // ppl -> Latn
+ case 0xB1EF0000u: // ppm -> Latn
+ case 0xB5EF0000u: // ppn -> Latn
+ case 0xB9EF0000u: // ppo -> Latn
+ case 0xBDEF0000u: // ppp -> Latn
+ case 0xC1EF0000u: // ppq -> Latn
+ case 0xC9EF0000u: // pps -> Latn
+ case 0xCDEF0000u: // ppt -> Latn
+ case 0x820F0000u: // pqa -> Latn
+ case 0xB20F0000u: // pqm -> Latn
+ case 0x922F0000u: // pre -> Latn
+ case 0x962F0000u: // prf -> Latn
+ case 0x9A2F0000u: // prg -> Latn
+ case 0x9E2F0000u: // prh -> Latn
+ case 0xA22F0000u: // pri -> Latn
+ case 0xAA2F0000u: // prk -> Latn
+ case 0xB22F0000u: // prm -> Latn
+ case 0xBA2F0000u: // pro -> Latn
+ case 0xC22F0000u: // prq -> Latn
+ case 0xC62F0000u: // prr -> Latn
+ case 0xD22F0000u: // pru -> Latn
+ case 0xDA2F0000u: // prw -> Latn
+ case 0x824F0000u: // psa -> Latn
+ case 0x924F0000u: // pse -> Latn
+ case 0xB24F0000u: // psm -> Latn
+ case 0xB64F0000u: // psn -> Latn
+ case 0xC24F0000u: // psq -> Latn
+ case 0xCA4F0000u: // pss -> Latn
+ case 0xDA4F0000u: // psw -> Latn
+ case 0x70740000u: // pt -> Latn
+ case 0x826F0000u: // pta -> Latn
+ case 0x9E6F0000u: // pth -> Latn
+ case 0xA26F0000u: // pti -> Latn
+ case 0xB66F0000u: // ptn -> Latn
+ case 0xBA6F0000u: // pto -> Latn
+ case 0xBE6F0000u: // ptp -> Latn
+ case 0xC66F0000u: // ptr -> Latn
+ case 0xCE6F0000u: // ptt -> Latn
+ case 0xD26F0000u: // ptu -> Latn
+ case 0xD66F0000u: // ptv -> Latn
+ case 0x828F0000u: // pua -> Latn
+ case 0x868F0000u: // pub -> Latn
+ case 0x8A8F0000u: // puc -> Latn
+ case 0x8E8F0000u: // pud -> Latn
+ case 0x928F0000u: // pue -> Latn
+ case 0x968F0000u: // puf -> Latn
+ case 0x9A8F0000u: // pug -> Latn
+ case 0xA28F0000u: // pui -> Latn
+ case 0xA68F0000u: // puj -> Latn
+ case 0xBA8F0000u: // puo -> Latn
+ case 0xBE8F0000u: // pup -> Latn
+ case 0xC28F0000u: // puq -> Latn
+ case 0xC68F0000u: // pur -> Latn
+ case 0xCE8F0000u: // put -> Latn
+ case 0xD28F0000u: // puu -> Latn
+ case 0xDA8F0000u: // puw -> Latn
+ case 0xDE8F0000u: // pux -> Latn
+ case 0xE28F0000u: // puy -> Latn
+ case 0x82CF0000u: // pwa -> Latn
+ case 0x86CF0000u: // pwb -> Latn
+ case 0x9ACF0000u: // pwg -> Latn
+ case 0xB2CF0000u: // pwm -> Latn
+ case 0xB6CF0000u: // pwn -> Latn
+ case 0xB2EF0000u: // pxm -> Latn
+ case 0x930F0000u: // pye -> Latn
+ case 0xB30F0000u: // pym -> Latn
+ case 0xB70F0000u: // pyn -> Latn
+ case 0xD30F0000u: // pyu -> Latn
+ case 0xE30F0000u: // pyy -> Latn
+ case 0x932F0000u: // pze -> Latn
+ case 0x9F2F0000u: // pzh -> Latn
+ case 0xB72F0000u: // pzn -> Latn
+ case 0x71750000u: // qu -> Latn
+ case 0x82900000u: // qua -> Latn
+ case 0x86900000u: // qub -> Latn
+ case 0x8A900000u: // quc -> Latn
+ case 0x8E900000u: // qud -> Latn
+ case 0x96900000u: // quf -> Latn
+ case 0x9A900000u: // qug -> Latn
+ case 0xA2900000u: // qui -> Latn
+ case 0xAA900000u: // quk -> Latn
+ case 0xAE900000u: // qul -> Latn
+ case 0xB2900000u: // qum -> Latn
+ case 0xB6900000u: // qun -> Latn
+ case 0xBE900000u: // qup -> Latn
+ case 0xC2900000u: // quq -> Latn
+ case 0xC6900000u: // qur -> Latn
+ case 0xCA900000u: // qus -> Latn
+ case 0xD6900000u: // quv -> Latn
+ case 0xDA900000u: // quw -> Latn
+ case 0xDE900000u: // qux -> Latn
+ case 0xE2900000u: // quy -> Latn
+ case 0x82B00000u: // qva -> Latn
+ case 0x8AB00000u: // qvc -> Latn
+ case 0x92B00000u: // qve -> Latn
+ case 0x9EB00000u: // qvh -> Latn
+ case 0xA2B00000u: // qvi -> Latn
+ case 0xA6B00000u: // qvj -> Latn
+ case 0xAEB00000u: // qvl -> Latn
+ case 0xB2B00000u: // qvm -> Latn
+ case 0xB6B00000u: // qvn -> Latn
+ case 0xBAB00000u: // qvo -> Latn
+ case 0xBEB00000u: // qvp -> Latn
+ case 0xCAB00000u: // qvs -> Latn
+ case 0xDAB00000u: // qvw -> Latn
+ case 0xE6B00000u: // qvz -> Latn
+ case 0x82D00000u: // qwa -> Latn
+ case 0x8AD00000u: // qwc -> Latn
+ case 0x9ED00000u: // qwh -> Latn
+ case 0xB2D00000u: // qwm -> Latn
+ case 0xCAD00000u: // qws -> Latn
+ case 0xCED00000u: // qwt -> Latn
+ case 0x82F00000u: // qxa -> Latn
+ case 0x8AF00000u: // qxc -> Latn
+ case 0x9EF00000u: // qxh -> Latn
+ case 0xAEF00000u: // qxl -> Latn
+ case 0xB6F00000u: // qxn -> Latn
+ case 0xBAF00000u: // qxo -> Latn
+ case 0xBEF00000u: // qxp -> Latn
+ case 0xC6F00000u: // qxr -> Latn
+ case 0xCEF00000u: // qxt -> Latn
+ case 0xD2F00000u: // qxu -> Latn
+ case 0xDAF00000u: // qxw -> Latn
+ case 0x83100000u: // qya -> Latn
+ case 0xBF100000u: // qyp -> Latn
+ case 0x88110000u: // rac -> Latn
+ case 0x8C110000u: // rad -> Latn
+ case 0x98110000u: // rag -> Latn
+ case 0xA0110000u: // rai -> Latn
+ case 0xA8110000u: // rak -> Latn
+ case 0xB0110000u: // ram -> Latn
+ case 0xB4110000u: // ran -> Latn
+ case 0xB8110000u: // rao -> Latn
+ case 0xBC110000u: // rap -> Latn
+ case 0xC4110000u: // rar -> Latn
+ case 0xD8110000u: // raw -> Latn
+ case 0xDC110000u: // rax -> Latn
+ case 0xE0110000u: // ray -> Latn
+ case 0xE4110000u: // raz -> Latn
+ case 0xA8310000u: // rbk -> Latn
+ case 0xAC310000u: // rbl -> Latn
+ case 0xBC310000u: // rbp -> Latn
+ case 0x94510000u: // rcf -> Latn
+ case 0x80910000u: // rea -> Latn
+ case 0x84910000u: // reb -> Latn
+ case 0x90910000u: // ree -> Latn
+ case 0x98910000u: // reg -> Latn
+ case 0xA4910000u: // rej -> Latn
+ case 0xAC910000u: // rel -> Latn
+ case 0xB0910000u: // rem -> Latn
+ case 0xB4910000u: // ren -> Latn
+ case 0xC8910000u: // res -> Latn
+ case 0xCC910000u: // ret -> Latn
+ case 0xE0910000u: // rey -> Latn
+ case 0x80D10000u: // rga -> Latn
+ case 0xB4D10000u: // rgn -> Latn
+ case 0xC4D10000u: // rgr -> Latn
+ case 0xC8D10000u: // rgs -> Latn
+ case 0xD0D10000u: // rgu -> Latn
+ case 0xBCF10000u: // rhp -> Latn
+ case 0x81110000u: // ria -> Latn
+ case 0x95110000u: // rif -> Latn
+ case 0xAD110000u: // ril -> Latn
+ case 0xB1110000u: // rim -> Latn
+ case 0xB5110000u: // rin -> Latn
+ case 0xC5110000u: // rir -> Latn
+ case 0xCD110000u: // rit -> Latn
+ case 0xD1110000u: // riu -> Latn
+ case 0x99310000u: // rjg -> Latn
+ case 0x85510000u: // rkb -> Latn
+ case 0x9D510000u: // rkh -> Latn
+ case 0xB1510000u: // rkm -> Latn
+ case 0xD9510000u: // rkw -> Latn
+ case 0x726D0000u: // rm -> Latn
+ case 0x81910000u: // rma -> Latn
+ case 0x85910000u: // rmb -> Latn
+ case 0x89910000u: // rmc -> Latn
+ case 0x8D910000u: // rmd -> Latn
+ case 0x91910000u: // rme -> Latn
+ case 0x95910000u: // rmf -> Latn
+ case 0x99910000u: // rmg -> Latn
+ case 0x9D910000u: // rmh -> Latn
+ case 0xA9910000u: // rmk -> Latn
+ case 0xAD910000u: // rml -> Latn
+ case 0xB1910000u: // rmm -> Latn
+ case 0xB5910000u: // rmn -> Latn
+ case 0xB9910000u: // rmo -> Latn
+ case 0xBD910000u: // rmp -> Latn
+ case 0xC1910000u: // rmq -> Latn
+ case 0xD1910000u: // rmu -> Latn
+ case 0xD9910000u: // rmw -> Latn
+ case 0xDD910000u: // rmx -> Latn
+ case 0x726E0000u: // rn -> Latn
+ case 0x8DB10000u: // rnd -> Latn
+ case 0x99B10000u: // rng -> Latn
+ case 0xADB10000u: // rnl -> Latn
+ case 0xB5B10000u: // rnn -> Latn
+ case 0xC5B10000u: // rnr -> Latn
+ case 0xD9B10000u: // rnw -> Latn
+ case 0x726F0000u: // ro -> Latn
+ case 0x85D10000u: // rob -> Latn
+ case 0x89D10000u: // roc -> Latn
+ case 0x8DD10000u: // rod -> Latn
+ case 0x91D10000u: // roe -> Latn
+ case 0x95D10000u: // rof -> Latn
+ case 0x99D10000u: // rog -> Latn
+ case 0xADD10000u: // rol -> Latn
+ case 0xB1D10000u: // rom -> Latn
+ case 0xB9D10000u: // roo -> Latn
+ case 0xBDD10000u: // rop -> Latn
+ case 0xC5D10000u: // ror -> Latn
+ case 0xD1D10000u: // rou -> Latn
+ case 0xD9D10000u: // row -> Latn
+ case 0xB5F10000u: // rpn -> Latn
+ case 0xCDF10000u: // rpt -> Latn
+ case 0xA2310000u: // rri -> Latn
+ case 0xB2310000u: // rrm -> Latn
+ case 0xBA310000u: // rro -> Latn
+ case 0xCE310000u: // rrt -> Latn
+ case 0xDA510000u: // rsw -> Latn
+ case 0x8A710000u: // rtc -> Latn
+ case 0x9E710000u: // rth -> Latn
+ case 0xB2710000u: // rtm -> Latn
+ case 0x86910000u: // rub -> Latn
+ case 0x8A910000u: // ruc -> Latn
+ case 0x96910000u: // ruf -> Latn
+ case 0x9A910000u: // rug -> Latn
+ case 0xA2910000u: // rui -> Latn
+ case 0xAA910000u: // ruk -> Latn
+ case 0xBA910000u: // ruo -> Latn
+ case 0xBE910000u: // rup -> Latn
+ case 0xC2910000u: // ruq -> Latn
+ case 0xD2910000u: // ruu -> Latn
+ case 0xE2910000u: // ruy -> Latn
+ case 0xE6910000u: // ruz -> Latn
+ case 0x72770000u: // rw -> Latn
+ case 0x82D10000u: // rwa -> Latn
+ case 0xAAD10000u: // rwk -> Latn
+ case 0xAED10000u: // rwl -> Latn
+ case 0xB2D10000u: // rwm -> Latn
+ case 0xBAD10000u: // rwo -> Latn
+ case 0x8EF10000u: // rxd -> Latn
+ case 0xDAF10000u: // rxw -> Latn
+ case 0x80120000u: // saa -> Latn
+ case 0x84120000u: // sab -> Latn
+ case 0x88120000u: // sac -> Latn
+ case 0x8C120000u: // sad -> Latn
+ case 0x90120000u: // sae -> Latn
+ case 0x94120000u: // saf -> Latn
+ case 0xA4120000u: // saj -> Latn
+ case 0xA8120000u: // sak -> Latn
+ case 0xB8120000u: // sao -> Latn
+ case 0xC0120000u: // saq -> Latn
+ case 0xC4120000u: // sar -> Latn
+ case 0xC8120000u: // sas -> Latn
+ case 0xD0120000u: // sau -> Latn
+ case 0xD4120000u: // sav -> Latn
+ case 0xD8120000u: // saw -> Latn
+ case 0xDC120000u: // sax -> Latn
+ case 0xE0120000u: // say -> Latn
+ case 0x80320000u: // sba -> Latn
+ case 0x84320000u: // sbb -> Latn
+ case 0x88320000u: // sbc -> Latn
+ case 0x8C320000u: // sbd -> Latn
+ case 0x90320000u: // sbe -> Latn
+ case 0x98320000u: // sbg -> Latn
+ case 0x9C320000u: // sbh -> Latn
+ case 0xA0320000u: // sbi -> Latn
+ case 0xA4320000u: // sbj -> Latn
+ case 0xA8320000u: // sbk -> Latn
+ case 0xAC320000u: // sbl -> Latn
+ case 0xB0320000u: // sbm -> Latn
+ case 0xB8320000u: // sbo -> Latn
+ case 0xBC320000u: // sbp -> Latn
+ case 0xC0320000u: // sbq -> Latn
+ case 0xC4320000u: // sbr -> Latn
+ case 0xC8320000u: // sbs -> Latn
+ case 0xCC320000u: // sbt -> Latn
+ case 0xD4320000u: // sbv -> Latn
+ case 0xD8320000u: // sbw -> Latn
+ case 0xDC320000u: // sbx -> Latn
+ case 0xE0320000u: // sby -> Latn
+ case 0xE4320000u: // sbz -> Latn
+ case 0x73630000u: // sc -> Latn
+ case 0x84520000u: // scb -> Latn
+ case 0x90520000u: // sce -> Latn
+ case 0x94520000u: // scf -> Latn
+ case 0x98520000u: // scg -> Latn
+ case 0x9C520000u: // sch -> Latn
+ case 0xA0520000u: // sci -> Latn
+ case 0xB4520000u: // scn -> Latn
+ case 0xB8520000u: // sco -> Latn
+ case 0xC8520000u: // scs -> Latn
+ case 0xD4520000u: // scv -> Latn
+ case 0xD8520000u: // scw -> Latn
+ case 0x80720000u: // sda -> Latn
+ case 0x88720000u: // sdc -> Latn
+ case 0x90720000u: // sde -> Latn
+ case 0xA4720000u: // sdj -> Latn
+ case 0xA8720000u: // sdk -> Latn
+ case 0xB4720000u: // sdn -> Latn
+ case 0xB8720000u: // sdo -> Latn
+ case 0xC0720000u: // sdq -> Latn
+ case 0xD0720000u: // sdu -> Latn
+ case 0xDC720000u: // sdx -> Latn
+ case 0x73650000u: // se -> Latn
+ case 0x80920000u: // sea -> Latn
+ case 0x84920000u: // seb -> Latn
+ case 0x88920000u: // sec -> Latn
+ case 0x8C920000u: // sed -> Latn
+ case 0x90920000u: // see -> Latn
+ case 0x94920000u: // sef -> Latn
+ case 0x98920000u: // seg -> Latn
+ case 0x9C920000u: // seh -> Latn
+ case 0xA0920000u: // sei -> Latn
+ case 0xA4920000u: // sej -> Latn
+ case 0xA8920000u: // sek -> Latn
+ case 0xB4920000u: // sen -> Latn
+ case 0xB8920000u: // seo -> Latn
+ case 0xBC920000u: // sep -> Latn
+ case 0xC0920000u: // seq -> Latn
+ case 0xC4920000u: // ser -> Latn
+ case 0xC8920000u: // ses -> Latn
+ case 0xCC920000u: // set -> Latn
+ case 0xD0920000u: // seu -> Latn
+ case 0xD4920000u: // sev -> Latn
+ case 0xD8920000u: // sew -> Latn
+ case 0xE0920000u: // sey -> Latn
+ case 0xE4920000u: // sez -> Latn
+ case 0x90B20000u: // sfe -> Latn
+ case 0xD8B20000u: // sfw -> Latn
+ case 0x73670000u: // sg -> Latn
+ case 0x84D20000u: // sgb -> Latn
+ case 0x88D20000u: // sgc -> Latn
+ case 0x8CD20000u: // sgd -> Latn
+ case 0x90D20000u: // sge -> Latn
+ case 0xA0D20000u: // sgi -> Latn
+ case 0xB0D20000u: // sgm -> Latn
+ case 0xBCD20000u: // sgp -> Latn
+ case 0xC8D20000u: // sgs -> Latn
+ case 0xD0D20000u: // sgu -> Latn
+ case 0xE4D20000u: // sgz -> Latn
+ case 0x80F20000u: // sha -> Latn
+ case 0x84F20000u: // shb -> Latn
+ case 0x88F20000u: // shc -> Latn
+ case 0x90F20000u: // she -> Latn
+ case 0x98F20000u: // shg -> Latn
+ case 0x9CF20000u: // shh -> Latn
+ case 0xA4F20000u: // shj -> Latn
+ case 0xA8F20000u: // shk -> Latn
+ case 0xB8F20000u: // sho -> Latn
+ case 0xBCF20000u: // shp -> Latn
+ case 0xC0F20000u: // shq -> Latn
+ case 0xC4F20000u: // shr -> Latn
+ case 0xC8F20000u: // shs -> Latn
+ case 0xCCF20000u: // sht -> Latn
+ case 0xD8F20000u: // shw -> Latn
+ case 0xE0F20000u: // shy -> Latn
+ case 0xE4F20000u: // shz -> Latn
+ case 0x85120000u: // sib -> Latn
+ case 0x8D120000u: // sid -> Latn
+ case 0x91120000u: // sie -> Latn
+ case 0x95120000u: // sif -> Latn
+ case 0x99120000u: // sig -> Latn
+ case 0x9D120000u: // sih -> Latn
+ case 0xA1120000u: // sii -> Latn
+ case 0xA5120000u: // sij -> Latn
+ case 0xA9120000u: // sik -> Latn
+ case 0xAD120000u: // sil -> Latn
+ case 0xB1120000u: // sim -> Latn
+ case 0xC1120000u: // siq -> Latn
+ case 0xC5120000u: // sir -> Latn
+ case 0xC9120000u: // sis -> Latn
+ case 0xD1120000u: // siu -> Latn
+ case 0xD5120000u: // siv -> Latn
+ case 0xD9120000u: // siw -> Latn
+ case 0xDD120000u: // six -> Latn
+ case 0x81320000u: // sja -> Latn
+ case 0x85320000u: // sjb -> Latn
+ case 0x91320000u: // sje -> Latn
+ case 0x99320000u: // sjg -> Latn
+ case 0xAD320000u: // sjl -> Latn
+ case 0xB1320000u: // sjm -> Latn
+ case 0xC5320000u: // sjr -> Latn
+ case 0xD1320000u: // sju -> Latn
+ case 0xD9320000u: // sjw -> Latn
+ case 0x736B0000u: // sk -> Latn
+ case 0x81520000u: // ska -> Latn
+ case 0x89520000u: // skc -> Latn
+ case 0x8D520000u: // skd -> Latn
+ case 0x91520000u: // ske -> Latn
+ case 0x95520000u: // skf -> Latn
+ case 0x99520000u: // skg -> Latn
+ case 0x9D520000u: // skh -> Latn
+ case 0xA1520000u: // ski -> Latn
+ case 0xB1520000u: // skm -> Latn
+ case 0xB5520000u: // skn -> Latn
+ case 0xB9520000u: // sko -> Latn
+ case 0xBD520000u: // skp -> Latn
+ case 0xC1520000u: // skq -> Latn
+ case 0xC9520000u: // sks -> Latn
+ case 0xCD520000u: // skt -> Latn
+ case 0xD1520000u: // sku -> Latn
+ case 0xD5520000u: // skv -> Latn
+ case 0xD9520000u: // skw -> Latn
+ case 0xDD520000u: // skx -> Latn
+ case 0xE1520000u: // sky -> Latn
+ case 0xE5520000u: // skz -> Latn
+ case 0x736C0000u: // sl -> Latn
+ case 0x89720000u: // slc -> Latn
+ case 0x8D720000u: // sld -> Latn
+ case 0x99720000u: // slg -> Latn
+ case 0x9D720000u: // slh -> Latn
+ case 0xA1720000u: // sli -> Latn
+ case 0xA5720000u: // slj -> Latn
+ case 0xAD720000u: // sll -> Latn
+ case 0xB1720000u: // slm -> Latn
+ case 0xB5720000u: // sln -> Latn
+ case 0xBD720000u: // slp -> Latn
+ case 0xC5720000u: // slr -> Latn
+ case 0xD1720000u: // slu -> Latn
+ case 0xD9720000u: // slw -> Latn
+ case 0xDD720000u: // slx -> Latn
+ case 0xE1720000u: // sly -> Latn
+ case 0xE5720000u: // slz -> Latn
+ case 0x736D0000u: // sm -> Latn
+ case 0x81920000u: // sma -> Latn
+ case 0x85920000u: // smb -> Latn
+ case 0x89920000u: // smc -> Latn
+ case 0x95920000u: // smf -> Latn
+ case 0x99920000u: // smg -> Latn
+ case 0xA5920000u: // smj -> Latn
+ case 0xA9920000u: // smk -> Latn
+ case 0xAD920000u: // sml -> Latn
+ case 0xB5920000u: // smn -> Latn
+ case 0xC1920000u: // smq -> Latn
+ case 0xC5920000u: // smr -> Latn
+ case 0xC9920000u: // sms -> Latn
+ case 0xCD920000u: // smt -> Latn
+ case 0xD9920000u: // smw -> Latn
+ case 0xDD920000u: // smx -> Latn
+ case 0xE5920000u: // smz -> Latn
+ case 0x736E0000u: // sn -> Latn
+ case 0x89B20000u: // snc -> Latn
+ case 0x91B20000u: // sne -> Latn
+ case 0x95B20000u: // snf -> Latn
+ case 0x99B20000u: // sng -> Latn
+ case 0xA1B20000u: // sni -> Latn
+ case 0xA5B20000u: // snj -> Latn
+ case 0xA9B20000u: // snk -> Latn
+ case 0xADB20000u: // snl -> Latn
+ case 0xB1B20000u: // snm -> Latn
+ case 0xB5B20000u: // snn -> Latn
+ case 0xB9B20000u: // sno -> Latn
+ case 0xBDB20000u: // snp -> Latn
+ case 0xC1B20000u: // snq -> Latn
+ case 0xC5B20000u: // snr -> Latn
+ case 0xC9B20000u: // sns -> Latn
+ case 0xD1B20000u: // snu -> Latn
+ case 0xD5B20000u: // snv -> Latn
+ case 0xD9B20000u: // snw -> Latn
+ case 0xDDB20000u: // snx -> Latn
+ case 0xE1B20000u: // sny -> Latn
+ case 0xE5B20000u: // snz -> Latn
+ case 0x736F0000u: // so -> Latn
+ case 0x85D20000u: // sob -> Latn
+ case 0x89D20000u: // soc -> Latn
+ case 0x8DD20000u: // sod -> Latn
+ case 0x91D20000u: // soe -> Latn
+ case 0xA9D20000u: // sok -> Latn
+ case 0xADD20000u: // sol -> Latn
+ case 0xB9D20000u: // soo -> Latn
+ case 0xBDD20000u: // sop -> Latn
+ case 0xC1D20000u: // soq -> Latn
+ case 0xC5D20000u: // sor -> Latn
+ case 0xC9D20000u: // sos -> Latn
+ case 0xD5D20000u: // sov -> Latn
+ case 0xD9D20000u: // sow -> Latn
+ case 0xDDD20000u: // sox -> Latn
+ case 0xE1D20000u: // soy -> Latn
+ case 0xE5D20000u: // soz -> Latn
+ case 0x85F20000u: // spb -> Latn
+ case 0x89F20000u: // spc -> Latn
+ case 0x8DF20000u: // spd -> Latn
+ case 0x91F20000u: // spe -> Latn
+ case 0x99F20000u: // spg -> Latn
+ case 0xA1F20000u: // spi -> Latn
+ case 0xA9F20000u: // spk -> Latn
+ case 0xADF20000u: // spl -> Latn
+ case 0xB1F20000u: // spm -> Latn
+ case 0xB5F20000u: // spn -> Latn
+ case 0xB9F20000u: // spo -> Latn
+ case 0xBDF20000u: // spp -> Latn
+ case 0xC1F20000u: // spq -> Latn
+ case 0xC5F20000u: // spr -> Latn
+ case 0xC9F20000u: // sps -> Latn
+ case 0x73710000u: // sq -> Latn
+ case 0x82120000u: // sqa -> Latn
+ case 0x9E120000u: // sqh -> Latn
+ case 0xB2120000u: // sqm -> Latn
+ case 0xD2120000u: // squ -> Latn
+ case 0x73724D45u: // sr-ME -> Latn
+ case 0x7372524Fu: // sr-RO -> Latn
+ case 0x73725255u: // sr-RU -> Latn
+ case 0x73725452u: // sr-TR -> Latn
+ case 0x82320000u: // sra -> Latn
+ case 0x92320000u: // sre -> Latn
+ case 0x96320000u: // srf -> Latn
+ case 0x9A320000u: // srg -> Latn
+ case 0xA2320000u: // sri -> Latn
+ case 0xAA320000u: // srk -> Latn
+ case 0xAE320000u: // srl -> Latn
+ case 0xB2320000u: // srm -> Latn
+ case 0xB6320000u: // srn -> Latn
+ case 0xBA320000u: // sro -> Latn
+ case 0xC2320000u: // srq -> Latn
+ case 0xC6320000u: // srr -> Latn
+ case 0xCA320000u: // srs -> Latn
+ case 0xCE320000u: // srt -> Latn
+ case 0xD2320000u: // sru -> Latn
+ case 0xD6320000u: // srv -> Latn
+ case 0xDA320000u: // srw -> Latn
+ case 0xE2320000u: // sry -> Latn
+ case 0x73730000u: // ss -> Latn
+ case 0x86520000u: // ssb -> Latn
+ case 0x8A520000u: // ssc -> Latn
+ case 0x8E520000u: // ssd -> Latn
+ case 0x92520000u: // sse -> Latn
+ case 0x96520000u: // ssf -> Latn
+ case 0x9A520000u: // ssg -> Latn
+ case 0xA6520000u: // ssj -> Latn
+ case 0xAE520000u: // ssl -> Latn
+ case 0xB2520000u: // ssm -> Latn
+ case 0xB6520000u: // ssn -> Latn
+ case 0xBA520000u: // sso -> Latn
+ case 0xC2520000u: // ssq -> Latn
+ case 0xCE520000u: // sst -> Latn
+ case 0xD2520000u: // ssu -> Latn
+ case 0xD6520000u: // ssv -> Latn
+ case 0xDE520000u: // ssx -> Latn
+ case 0xE2520000u: // ssy -> Latn
+ case 0xE6520000u: // ssz -> Latn
+ case 0x73740000u: // st -> Latn
+ case 0x82720000u: // sta -> Latn
+ case 0x86720000u: // stb -> Latn
+ case 0x92720000u: // ste -> Latn
+ case 0x96720000u: // stf -> Latn
+ case 0x9A720000u: // stg -> Latn
+ case 0x9E720000u: // sth -> Latn
+ case 0xA2720000u: // sti -> Latn
+ case 0xA6720000u: // stj -> Latn
+ case 0xAA720000u: // stk -> Latn
+ case 0xAE720000u: // stl -> Latn
+ case 0xB2720000u: // stm -> Latn
+ case 0xB6720000u: // stn -> Latn
+ case 0xBA720000u: // sto -> Latn
+ case 0xBE720000u: // stp -> Latn
+ case 0xC2720000u: // stq -> Latn
+ case 0xC6720000u: // str -> Latn
+ case 0xCE720000u: // stt -> Latn
+ case 0xDA720000u: // stw -> Latn
+ case 0x73750000u: // su -> Latn
+ case 0x82920000u: // sua -> Latn
+ case 0x86920000u: // sub -> Latn
+ case 0x8A920000u: // suc -> Latn
+ case 0x92920000u: // sue -> Latn
+ case 0x9A920000u: // sug -> Latn
+ case 0xA2920000u: // sui -> Latn
+ case 0xA6920000u: // suj -> Latn
+ case 0xAA920000u: // suk -> Latn
+ case 0xBA920000u: // suo -> Latn
+ case 0xC2920000u: // suq -> Latn
+ case 0xC6920000u: // sur -> Latn
+ case 0xCA920000u: // sus -> Latn
+ case 0xCE920000u: // sut -> Latn
+ case 0xD6920000u: // suv -> Latn
+ case 0xDA920000u: // suw -> Latn
+ case 0xE2920000u: // suy -> Latn
+ case 0x73760000u: // sv -> Latn
+ case 0x86B20000u: // svb -> Latn
+ case 0x8AB20000u: // svc -> Latn
+ case 0x92B20000u: // sve -> Latn
+ case 0xB2B20000u: // svm -> Latn
+ case 0xCAB20000u: // svs -> Latn
+ case 0x73770000u: // sw -> Latn
+ case 0x96D20000u: // swf -> Latn
+ case 0x9AD20000u: // swg -> Latn
+ case 0xA6D20000u: // swj -> Latn
+ case 0xAAD20000u: // swk -> Latn
+ case 0xB2D20000u: // swm -> Latn
+ case 0xBAD20000u: // swo -> Latn
+ case 0xBED20000u: // swp -> Latn
+ case 0xC2D20000u: // swq -> Latn
+ case 0xC6D20000u: // swr -> Latn
+ case 0xCAD20000u: // sws -> Latn
+ case 0xCED20000u: // swt -> Latn
+ case 0xD2D20000u: // swu -> Latn
+ case 0xDAD20000u: // sww -> Latn
+ case 0xDED20000u: // swx -> Latn
+ case 0xE2D20000u: // swy -> Latn
+ case 0x86F20000u: // sxb -> Latn
+ case 0x92F20000u: // sxe -> Latn
+ case 0xB6F20000u: // sxn -> Latn
+ case 0xC6F20000u: // sxr -> Latn
+ case 0xCAF20000u: // sxs -> Latn
+ case 0xDAF20000u: // sxw -> Latn
+ case 0x83120000u: // sya -> Latn
+ case 0x87120000u: // syb -> Latn
+ case 0xA3120000u: // syi -> Latn
+ case 0xAB120000u: // syk -> Latn
+ case 0xB3120000u: // sym -> Latn
+ case 0xBB120000u: // syo -> Latn
+ case 0xCB120000u: // sys -> Latn
+ case 0xDF120000u: // syx -> Latn
+ case 0x83320000u: // sza -> Latn
+ case 0x87320000u: // szb -> Latn
+ case 0x8B320000u: // szc -> Latn
+ case 0x9B320000u: // szg -> Latn
+ case 0xAF320000u: // szl -> Latn
+ case 0xB7320000u: // szn -> Latn
+ case 0xBF320000u: // szp -> Latn
+ case 0xD7320000u: // szv -> Latn
+ case 0xDB320000u: // szw -> Latn
+ case 0xE3320000u: // szy -> Latn
+ case 0x80130000u: // taa -> Latn
+ case 0x88130000u: // tac -> Latn
+ case 0x8C130000u: // tad -> Latn
+ case 0x90130000u: // tae -> Latn
+ case 0x94130000u: // taf -> Latn
+ case 0x98130000u: // tag -> Latn
+ case 0xA8130000u: // tak -> Latn
+ case 0xAC130000u: // tal -> Latn
+ case 0xB4130000u: // tan -> Latn
+ case 0xB8130000u: // tao -> Latn
+ case 0xBC130000u: // tap -> Latn
+ case 0xC0130000u: // taq -> Latn
+ case 0xC4130000u: // tar -> Latn
+ case 0xC8130000u: // tas -> Latn
+ case 0xD0130000u: // tau -> Latn
+ case 0xD4130000u: // tav -> Latn
+ case 0xD8130000u: // taw -> Latn
+ case 0xDC130000u: // tax -> Latn
+ case 0xE0130000u: // tay -> Latn
+ case 0xE4130000u: // taz -> Latn
+ case 0x80330000u: // tba -> Latn
+ case 0x88330000u: // tbc -> Latn
+ case 0x8C330000u: // tbd -> Latn
+ case 0x90330000u: // tbe -> Latn
+ case 0x94330000u: // tbf -> Latn
+ case 0x98330000u: // tbg -> Latn
+ case 0x9C330000u: // tbh -> Latn
+ case 0xA0330000u: // tbi -> Latn
+ case 0xA4330000u: // tbj -> Latn
+ case 0xAC330000u: // tbl -> Latn
+ case 0xB0330000u: // tbm -> Latn
+ case 0xB4330000u: // tbn -> Latn
+ case 0xB8330000u: // tbo -> Latn
+ case 0xBC330000u: // tbp -> Latn
+ case 0xC8330000u: // tbs -> Latn
+ case 0xCC330000u: // tbt -> Latn
+ case 0xD0330000u: // tbu -> Latn
+ case 0xD4330000u: // tbv -> Latn
+ case 0xD8330000u: // tbw -> Latn
+ case 0xDC330000u: // tbx -> Latn
+ case 0xE0330000u: // tby -> Latn
+ case 0xE4330000u: // tbz -> Latn
+ case 0x80530000u: // tca -> Latn
+ case 0x84530000u: // tcb -> Latn
+ case 0x88530000u: // tcc -> Latn
+ case 0x8C530000u: // tcd -> Latn
+ case 0x90530000u: // tce -> Latn
+ case 0x94530000u: // tcf -> Latn
+ case 0x98530000u: // tcg -> Latn
+ case 0x9C530000u: // tch -> Latn
+ case 0xA0530000u: // tci -> Latn
+ case 0xA8530000u: // tck -> Latn
+ case 0xB0530000u: // tcm -> Latn
+ case 0xBC530000u: // tcp -> Latn
+ case 0xC0530000u: // tcq -> Latn
+ case 0xC8530000u: // tcs -> Latn
+ case 0xD0530000u: // tcu -> Latn
+ case 0xD8530000u: // tcw -> Latn
+ case 0xE4530000u: // tcz -> Latn
+ case 0x88730000u: // tdc -> Latn
+ case 0x90730000u: // tde -> Latn
+ case 0xA0730000u: // tdi -> Latn
+ case 0xA4730000u: // tdj -> Latn
+ case 0xA8730000u: // tdk -> Latn
+ case 0xAC730000u: // tdl -> Latn
+ case 0xB0730000u: // tdm -> Latn
+ case 0xB4730000u: // tdn -> Latn
+ case 0xB8730000u: // tdo -> Latn
+ case 0xC0730000u: // tdq -> Latn
+ case 0xC4730000u: // tdr -> Latn
+ case 0xC8730000u: // tds -> Latn
+ case 0xCC730000u: // tdt -> Latn
+ case 0xD4730000u: // tdv -> Latn
+ case 0xDC730000u: // tdx -> Latn
+ case 0xE0730000u: // tdy -> Latn
+ case 0x80930000u: // tea -> Latn
+ case 0x84930000u: // teb -> Latn
+ case 0x88930000u: // tec -> Latn
+ case 0x8C930000u: // ted -> Latn
+ case 0x90930000u: // tee -> Latn
+ case 0x98930000u: // teg -> Latn
+ case 0x9C930000u: // teh -> Latn
+ case 0xA0930000u: // tei -> Latn
+ case 0xA8930000u: // tek -> Latn
+ case 0xB0930000u: // tem -> Latn
+ case 0xB4930000u: // ten -> Latn
+ case 0xB8930000u: // teo -> Latn
+ case 0xBC930000u: // tep -> Latn
+ case 0xC0930000u: // teq -> Latn
+ case 0xC4930000u: // ter -> Latn
+ case 0xCC930000u: // tet -> Latn
+ case 0xD0930000u: // teu -> Latn
+ case 0xD4930000u: // tev -> Latn
+ case 0xD8930000u: // tew -> Latn
+ case 0xDC930000u: // tex -> Latn
+ case 0xE0930000u: // tey -> Latn
+ case 0xE4930000u: // tez -> Latn
+ case 0xA0B30000u: // tfi -> Latn
+ case 0xB4B30000u: // tfn -> Latn
+ case 0xB8B30000u: // tfo -> Latn
+ case 0xC4B30000u: // tfr -> Latn
+ case 0xCCB30000u: // tft -> Latn
+ case 0x80D30000u: // tga -> Latn
+ case 0x84D30000u: // tgb -> Latn
+ case 0x88D30000u: // tgc -> Latn
+ case 0x8CD30000u: // tgd -> Latn
+ case 0x9CD30000u: // tgh -> Latn
+ case 0xA0D30000u: // tgi -> Latn
+ case 0xA4D30000u: // tgj -> Latn
+ case 0xB4D30000u: // tgn -> Latn
+ case 0xB8D30000u: // tgo -> Latn
+ case 0xBCD30000u: // tgp -> Latn
+ case 0xC0D30000u: // tgq -> Latn
+ case 0xC8D30000u: // tgs -> Latn
+ case 0xCCD30000u: // tgt -> Latn
+ case 0xD0D30000u: // tgu -> Latn
+ case 0xD4D30000u: // tgv -> Latn
+ case 0xD8D30000u: // tgw -> Latn
+ case 0xDCD30000u: // tgx -> Latn
+ case 0xE0D30000u: // tgy -> Latn
+ case 0xE4D30000u: // tgz -> Latn
+ case 0x8CF30000u: // thd -> Latn
+ case 0x9CF30000u: // thh -> Latn
+ case 0xA8F30000u: // thk -> Latn
+ case 0xBCF30000u: // thp -> Latn
+ case 0xCCF30000u: // tht -> Latn
+ case 0xD0F30000u: // thu -> Latn
+ case 0xD4F30000u: // thv -> Latn
+ case 0xE0F30000u: // thy -> Latn
+ case 0xE4F30000u: // thz -> Latn
+ case 0x89130000u: // tic -> Latn
+ case 0x95130000u: // tif -> Latn
+ case 0x9D130000u: // tih -> Latn
+ case 0xA1130000u: // tii -> Latn
+ case 0xA9130000u: // tik -> Latn
+ case 0xAD130000u: // til -> Latn
+ case 0xB1130000u: // tim -> Latn
+ case 0xB9130000u: // tio -> Latn
+ case 0xBD130000u: // tip -> Latn
+ case 0xC1130000u: // tiq -> Latn
+ case 0xC9130000u: // tis -> Latn
+ case 0xCD130000u: // tit -> Latn
+ case 0xD1130000u: // tiu -> Latn
+ case 0xD5130000u: // tiv -> Latn
+ case 0xD9130000u: // tiw -> Latn
+ case 0xDD130000u: // tix -> Latn
+ case 0xE1130000u: // tiy -> Latn
+ case 0x81330000u: // tja -> Latn
+ case 0x99330000u: // tjg -> Latn
+ case 0xA1330000u: // tji -> Latn
+ case 0xA5330000u: // tjj -> Latn
+ case 0xB5330000u: // tjn -> Latn
+ case 0xBD330000u: // tjp -> Latn
+ case 0xC9330000u: // tjs -> Latn
+ case 0xD1330000u: // tju -> Latn
+ case 0xD9330000u: // tjw -> Latn
+ case 0x746B0000u: // tk -> Latn
+ case 0x81530000u: // tka -> Latn
+ case 0x8D530000u: // tkd -> Latn
+ case 0x91530000u: // tke -> Latn
+ case 0x95530000u: // tkf -> Latn
+ case 0x99530000u: // tkg -> Latn
+ case 0xAD530000u: // tkl -> Latn
+ case 0xBD530000u: // tkp -> Latn
+ case 0xC1530000u: // tkq -> Latn
+ case 0xC5530000u: // tkr -> Latn
+ case 0xD1530000u: // tku -> Latn
+ case 0xD5530000u: // tkv -> Latn
+ case 0xD9530000u: // tkw -> Latn
+ case 0xDD530000u: // tkx -> Latn
+ case 0xE5530000u: // tkz -> Latn
+ case 0x746C0000u: // tl -> Latn
+ case 0x81730000u: // tla -> Latn
+ case 0x85730000u: // tlb -> Latn
+ case 0x89730000u: // tlc -> Latn
+ case 0x8D730000u: // tld -> Latn
+ case 0x95730000u: // tlf -> Latn
+ case 0x99730000u: // tlg -> Latn
+ case 0xA1730000u: // tli -> Latn
+ case 0xA5730000u: // tlj -> Latn
+ case 0xA9730000u: // tlk -> Latn
+ case 0xAD730000u: // tll -> Latn
+ case 0xB1730000u: // tlm -> Latn
+ case 0xB5730000u: // tln -> Latn
+ case 0xBD730000u: // tlp -> Latn
+ case 0xC1730000u: // tlq -> Latn
+ case 0xC5730000u: // tlr -> Latn
+ case 0xC9730000u: // tls -> Latn
+ case 0xCD730000u: // tlt -> Latn
+ case 0xD1730000u: // tlu -> Latn
+ case 0xD5730000u: // tlv -> Latn
+ case 0xDD730000u: // tlx -> Latn
+ case 0xE1730000u: // tly -> Latn
+ case 0x81930000u: // tma -> Latn
+ case 0x85930000u: // tmb -> Latn
+ case 0x89930000u: // tmc -> Latn
+ case 0x8D930000u: // tmd -> Latn
+ case 0x91930000u: // tme -> Latn
+ case 0x95930000u: // tmf -> Latn
+ case 0x99930000u: // tmg -> Latn
+ case 0x9D930000u: // tmh -> Latn
+ case 0xA1930000u: // tmi -> Latn
+ case 0xA5930000u: // tmj -> Latn
+ case 0xAD930000u: // tml -> Latn
+ case 0xB1930000u: // tmm -> Latn
+ case 0xB5930000u: // tmn -> Latn
+ case 0xB9930000u: // tmo -> Latn
+ case 0xC1930000u: // tmq -> Latn
+ case 0xCD930000u: // tmt -> Latn
+ case 0xD1930000u: // tmu -> Latn
+ case 0xD5930000u: // tmv -> Latn
+ case 0xD9930000u: // tmw -> Latn
+ case 0xE1930000u: // tmy -> Latn
+ case 0xE5930000u: // tmz -> Latn
+ case 0x746E0000u: // tn -> Latn
+ case 0x81B30000u: // tna -> Latn
+ case 0x85B30000u: // tnb -> Latn
+ case 0x89B30000u: // tnc -> Latn
+ case 0x8DB30000u: // tnd -> Latn
+ case 0x99B30000u: // tng -> Latn
+ case 0x9DB30000u: // tnh -> Latn
+ case 0xA1B30000u: // tni -> Latn
+ case 0xA9B30000u: // tnk -> Latn
+ case 0xADB30000u: // tnl -> Latn
+ case 0xB1B30000u: // tnm -> Latn
+ case 0xB5B30000u: // tnn -> Latn
+ case 0xB9B30000u: // tno -> Latn
+ case 0xBDB30000u: // tnp -> Latn
+ case 0xC1B30000u: // tnq -> Latn
+ case 0xC5B30000u: // tnr -> Latn
+ case 0xC9B30000u: // tns -> Latn
+ case 0xCDB30000u: // tnt -> Latn
+ case 0xD9B30000u: // tnw -> Latn
+ case 0xDDB30000u: // tnx -> Latn
+ case 0xE1B30000u: // tny -> Latn
+ case 0x746F0000u: // to -> Latn
+ case 0x85D30000u: // tob -> Latn
+ case 0x89D30000u: // toc -> Latn
+ case 0x8DD30000u: // tod -> Latn
+ case 0x95D30000u: // tof -> Latn
+ case 0x99D30000u: // tog -> Latn
+ case 0x9DD30000u: // toh -> Latn
+ case 0xA1D30000u: // toi -> Latn
+ case 0xA5D30000u: // toj -> Latn
+ case 0xA9D30000u: // tok -> Latn
+ case 0xADD30000u: // tol -> Latn
+ case 0xB1D30000u: // tom -> Latn
+ case 0xB9D30000u: // too -> Latn
+ case 0xBDD30000u: // top -> Latn
+ case 0xC1D30000u: // toq -> Latn
+ case 0xC5D30000u: // tor -> Latn
+ case 0xC9D30000u: // tos -> Latn
+ case 0xD1D30000u: // tou -> Latn
+ case 0xD9D30000u: // tow -> Latn
+ case 0xDDD30000u: // tox -> Latn
+ case 0xE1D30000u: // toy -> Latn
+ case 0xE5D30000u: // toz -> Latn
+ case 0x81F30000u: // tpa -> Latn
+ case 0x89F30000u: // tpc -> Latn
+ case 0x91F30000u: // tpe -> Latn
+ case 0x95F30000u: // tpf -> Latn
+ case 0x99F30000u: // tpg -> Latn
+ case 0xA1F30000u: // tpi -> Latn
+ case 0xA5F30000u: // tpj -> Latn
+ case 0xA9F30000u: // tpk -> Latn
+ case 0xADF30000u: // tpl -> Latn
+ case 0xB1F30000u: // tpm -> Latn
+ case 0xB5F30000u: // tpn -> Latn
+ case 0xBDF30000u: // tpp -> Latn
+ case 0xC5F30000u: // tpr -> Latn
+ case 0xCDF30000u: // tpt -> Latn
+ case 0xD5F30000u: // tpv -> Latn
+ case 0xDDF30000u: // tpx -> Latn
+ case 0xE1F30000u: // tpy -> Latn
+ case 0xE5F30000u: // tpz -> Latn
+ case 0x86130000u: // tqb -> Latn
+ case 0xAE130000u: // tql -> Latn
+ case 0xB2130000u: // tqm -> Latn
+ case 0xB6130000u: // tqn -> Latn
+ case 0xBA130000u: // tqo -> Latn
+ case 0xBE130000u: // tqp -> Latn
+ case 0xCE130000u: // tqt -> Latn
+ case 0xD2130000u: // tqu -> Latn
+ case 0xDA130000u: // tqw -> Latn
+ case 0x74720000u: // tr -> Latn
+ case 0x86330000u: // trb -> Latn
+ case 0x8A330000u: // trc -> Latn
+ case 0x92330000u: // tre -> Latn
+ case 0x96330000u: // trf -> Latn
+ case 0x9E330000u: // trh -> Latn
+ case 0xA2330000u: // tri -> Latn
+ case 0xA6330000u: // trj -> Latn
+ case 0xAE330000u: // trl -> Latn
+ case 0xB6330000u: // trn -> Latn
+ case 0xBA330000u: // tro -> Latn
+ case 0xBE330000u: // trp -> Latn
+ case 0xC2330000u: // trq -> Latn
+ case 0xC6330000u: // trr -> Latn
+ case 0xCA330000u: // trs -> Latn
+ case 0xCE330000u: // trt -> Latn
+ case 0xD2330000u: // tru -> Latn
+ case 0xD6330000u: // trv -> Latn
+ case 0xDE330000u: // trx -> Latn
+ case 0xE2330000u: // try -> Latn
+ case 0xE6330000u: // trz -> Latn
+ case 0x74730000u: // ts -> Latn
+ case 0x82530000u: // tsa -> Latn
+ case 0x86530000u: // tsb -> Latn
+ case 0x8A530000u: // tsc -> Latn
+ case 0x9A530000u: // tsg -> Latn
+ case 0x9E530000u: // tsh -> Latn
+ case 0xA2530000u: // tsi -> Latn
+ case 0xAE530000u: // tsl -> Latn
+ case 0xBE530000u: // tsp -> Latn
+ case 0xC6530000u: // tsr -> Latn
+ case 0xCE530000u: // tst -> Latn
+ case 0xD2530000u: // tsu -> Latn
+ case 0xD6530000u: // tsv -> Latn
+ case 0xDA530000u: // tsw -> Latn
+ case 0xDE530000u: // tsx -> Latn
+ case 0xE6530000u: // tsz -> Latn
+ case 0x86730000u: // ttb -> Latn
+ case 0x8A730000u: // ttc -> Latn
+ case 0x8E730000u: // ttd -> Latn
+ case 0x92730000u: // tte -> Latn
+ case 0x96730000u: // ttf -> Latn
+ case 0xA2730000u: // tti -> Latn
+ case 0xA6730000u: // ttj -> Latn
+ case 0xAA730000u: // ttk -> Latn
+ case 0xAE730000u: // ttl -> Latn
+ case 0xB2730000u: // ttm -> Latn
+ case 0xB6730000u: // ttn -> Latn
+ case 0xBE730000u: // ttp -> Latn
+ case 0xC6730000u: // ttr -> Latn
+ case 0xCE730000u: // ttt -> Latn
+ case 0xD2730000u: // ttu -> Latn
+ case 0xD6730000u: // ttv -> Latn
+ case 0xDA730000u: // ttw -> Latn
+ case 0xE2730000u: // tty -> Latn
+ case 0x82930000u: // tua -> Latn
+ case 0x86930000u: // tub -> Latn
+ case 0x8A930000u: // tuc -> Latn
+ case 0x8E930000u: // tud -> Latn
+ case 0x92930000u: // tue -> Latn
+ case 0x96930000u: // tuf -> Latn
+ case 0x9A930000u: // tug -> Latn
+ case 0x9E930000u: // tuh -> Latn
+ case 0xA2930000u: // tui -> Latn
+ case 0xA6930000u: // tuj -> Latn
+ case 0xAE930000u: // tul -> Latn
+ case 0xB2930000u: // tum -> Latn
+ case 0xB6930000u: // tun -> Latn
+ case 0xBA930000u: // tuo -> Latn
+ case 0xC2930000u: // tuq -> Latn
+ case 0xCA930000u: // tus -> Latn
+ case 0xD2930000u: // tuu -> Latn
+ case 0xD6930000u: // tuv -> Latn
+ case 0xDE930000u: // tux -> Latn
+ case 0xE2930000u: // tuy -> Latn
+ case 0xE6930000u: // tuz -> Latn
+ case 0x82B30000u: // tva -> Latn
+ case 0x8EB30000u: // tvd -> Latn
+ case 0x92B30000u: // tve -> Latn
+ case 0xA2B30000u: // tvi -> Latn
+ case 0xAAB30000u: // tvk -> Latn
+ case 0xAEB30000u: // tvl -> Latn
+ case 0xB2B30000u: // tvm -> Latn
+ case 0xBAB30000u: // tvo -> Latn
+ case 0xCAB30000u: // tvs -> Latn
+ case 0xCEB30000u: // tvt -> Latn
+ case 0xD2B30000u: // tvu -> Latn
+ case 0xDAB30000u: // tvw -> Latn
+ case 0xDEB30000u: // tvx -> Latn
+ case 0x82D30000u: // twa -> Latn
+ case 0x86D30000u: // twb -> Latn
+ case 0x8ED30000u: // twd -> Latn
+ case 0x92D30000u: // twe -> Latn
+ case 0x96D30000u: // twf -> Latn
+ case 0x9AD30000u: // twg -> Latn
+ case 0x9ED30000u: // twh -> Latn
+ case 0xAED30000u: // twl -> Latn
+ case 0xB6D30000u: // twn -> Latn
+ case 0xBAD30000u: // two -> Latn
+ case 0xBED30000u: // twp -> Latn
+ case 0xC2D30000u: // twq -> Latn
+ case 0xC6D30000u: // twr -> Latn
+ case 0xCED30000u: // twt -> Latn
+ case 0xD2D30000u: // twu -> Latn
+ case 0xDAD30000u: // tww -> Latn
+ case 0xDED30000u: // twx -> Latn
+ case 0xE2D30000u: // twy -> Latn
+ case 0x82F30000u: // txa -> Latn
+ case 0x92F30000u: // txe -> Latn
+ case 0xA2F30000u: // txi -> Latn
+ case 0xA6F30000u: // txj -> Latn
+ case 0xB2F30000u: // txm -> Latn
+ case 0xB6F30000u: // txn -> Latn
+ case 0xC2F30000u: // txq -> Latn
+ case 0xCAF30000u: // txs -> Latn
+ case 0xCEF30000u: // txt -> Latn
+ case 0xD2F30000u: // txu -> Latn
+ case 0xDEF30000u: // txx -> Latn
+ case 0xE2F30000u: // txy -> Latn
+ case 0x74790000u: // ty -> Latn
+ case 0x83130000u: // tya -> Latn
+ case 0x93130000u: // tye -> Latn
+ case 0x9F130000u: // tyh -> Latn
+ case 0xA3130000u: // tyi -> Latn
+ case 0xA7130000u: // tyj -> Latn
+ case 0xAF130000u: // tyl -> Latn
+ case 0xB7130000u: // tyn -> Latn
+ case 0xBF130000u: // typ -> Latn
+ case 0xCB130000u: // tys -> Latn
+ case 0xCF130000u: // tyt -> Latn
+ case 0xD3130000u: // tyu -> Latn
+ case 0xDF130000u: // tyx -> Latn
+ case 0xE3130000u: // tyy -> Latn
+ case 0xE7130000u: // tyz -> Latn
+ case 0x9F330000u: // tzh -> Latn
+ case 0xA7330000u: // tzj -> Latn
+ case 0xAF330000u: // tzl -> Latn
+ case 0xB3330000u: // tzm -> Latn
+ case 0xB7330000u: // tzn -> Latn
+ case 0xBB330000u: // tzo -> Latn
+ case 0xDF330000u: // tzx -> Latn
+ case 0xB0140000u: // uam -> Latn
+ case 0xC4140000u: // uar -> Latn
+ case 0x80340000u: // uba -> Latn
+ case 0xA0340000u: // ubi -> Latn
+ case 0xAC340000u: // ubl -> Latn
+ case 0xC4340000u: // ubr -> Latn
+ case 0xD0340000u: // ubu -> Latn
+ case 0xE0340000u: // uby -> Latn
+ case 0x80740000u: // uda -> Latn
+ case 0xA4740000u: // udj -> Latn
+ case 0xAC740000u: // udl -> Latn
+ case 0xD0740000u: // udu -> Latn
+ case 0xC8940000u: // ues -> Latn
+ case 0xA0B40000u: // ufi -> Latn
+ case 0x84D40000u: // ugb -> Latn
+ case 0x90D40000u: // uge -> Latn
+ case 0x80F40000u: // uha -> Latn
+ case 0xB4F40000u: // uhn -> Latn
+ case 0xC9140000u: // uis -> Latn
+ case 0xD5140000u: // uiv -> Latn
+ case 0xA1340000u: // uji -> Latn
+ case 0x81540000u: // uka -> Latn
+ case 0x99540000u: // ukg -> Latn
+ case 0x9D540000u: // ukh -> Latn
+ case 0xA9540000u: // ukk -> Latn
+ case 0xBD540000u: // ukp -> Latn
+ case 0xC1540000u: // ukq -> Latn
+ case 0xD1540000u: // uku -> Latn
+ case 0xD5540000u: // ukv -> Latn
+ case 0xD9540000u: // ukw -> Latn
+ case 0xE1540000u: // uky -> Latn
+ case 0x81740000u: // ula -> Latn
+ case 0x85740000u: // ulb -> Latn
+ case 0x91740000u: // ule -> Latn
+ case 0x95740000u: // ulf -> Latn
+ case 0xA1740000u: // uli -> Latn
+ case 0xA9740000u: // ulk -> Latn
+ case 0xB1740000u: // ulm -> Latn
+ case 0xB5740000u: // uln -> Latn
+ case 0xD1740000u: // ulu -> Latn
+ case 0xD9740000u: // ulw -> Latn
+ case 0xE1740000u: // uly -> Latn
+ case 0x81940000u: // uma -> Latn
+ case 0x85940000u: // umb -> Latn
+ case 0x8D940000u: // umd -> Latn
+ case 0x99940000u: // umg -> Latn
+ case 0xA1940000u: // umi -> Latn
+ case 0xB1940000u: // umm -> Latn
+ case 0xB5940000u: // umn -> Latn
+ case 0xB9940000u: // umo -> Latn
+ case 0xBD940000u: // ump -> Latn
+ case 0xC5940000u: // umr -> Latn
+ case 0xC9940000u: // ums -> Latn
+ case 0x81B40000u: // una -> Latn
+ case 0x91B40000u: // une -> Latn
+ case 0x99B40000u: // ung -> Latn
+ case 0xA1B40000u: // uni -> Latn
+ case 0xA9B40000u: // unk -> Latn
+ case 0xB1B40000u: // unm -> Latn
+ case 0xB5B40000u: // unn -> Latn
+ case 0xD1B40000u: // unu -> Latn
+ case 0xE5B40000u: // unz -> Latn
+ case 0xB5D40000u: // uon -> Latn
+ case 0xA1F40000u: // upi -> Latn
+ case 0xD5F40000u: // upv -> Latn
+ case 0x82340000u: // ura -> Latn
+ case 0x86340000u: // urb -> Latn
+ case 0x8A340000u: // urc -> Latn
+ case 0x92340000u: // ure -> Latn
+ case 0x96340000u: // urf -> Latn
+ case 0x9A340000u: // urg -> Latn
+ case 0x9E340000u: // urh -> Latn
+ case 0xA2340000u: // uri -> Latn
+ case 0xB2340000u: // urm -> Latn
+ case 0xB6340000u: // urn -> Latn
+ case 0xBA340000u: // uro -> Latn
+ case 0xBE340000u: // urp -> Latn
+ case 0xC6340000u: // urr -> Latn
+ case 0xCE340000u: // urt -> Latn
+ case 0xD2340000u: // uru -> Latn
+ case 0xD6340000u: // urv -> Latn
+ case 0xDA340000u: // urw -> Latn
+ case 0xDE340000u: // urx -> Latn
+ case 0xE2340000u: // ury -> Latn
+ case 0xE6340000u: // urz -> Latn
+ case 0x82540000u: // usa -> Latn
+ case 0xA2540000u: // usi -> Latn
+ case 0xAA540000u: // usk -> Latn
+ case 0xBE540000u: // usp -> Latn
+ case 0xCA540000u: // uss -> Latn
+ case 0xD2540000u: // usu -> Latn
+ case 0x82740000u: // uta -> Latn
+ case 0x92740000u: // ute -> Latn
+ case 0x9E740000u: // uth -> Latn
+ case 0xBE740000u: // utp -> Latn
+ case 0xC6740000u: // utr -> Latn
+ case 0xD2740000u: // utu -> Latn
+ case 0xC6940000u: // uur -> Latn
+ case 0x92B40000u: // uve -> Latn
+ case 0x9EB40000u: // uvh -> Latn
+ case 0xAEB40000u: // uvl -> Latn
+ case 0x82D40000u: // uwa -> Latn
+ case 0x83140000u: // uya -> Latn
+ case 0x757A0000u: // uz -> Latn
+ case 0x90150000u: // vae -> Latn
+ case 0x98150000u: // vag -> Latn
+ case 0xA4150000u: // vaj -> Latn
+ case 0xAC150000u: // val -> Latn
+ case 0xB0150000u: // vam -> Latn
+ case 0xB4150000u: // van -> Latn
+ case 0xB8150000u: // vao -> Latn
+ case 0xBC150000u: // vap -> Latn
+ case 0xC4150000u: // var -> Latn
+ case 0xD0150000u: // vau -> Latn
+ case 0x84350000u: // vbb -> Latn
+ case 0xA8350000u: // vbk -> Latn
+ case 0x76650000u: // ve -> Latn
+ case 0x88950000u: // vec -> Latn
+ case 0xB0950000u: // vem -> Latn
+ case 0xB8950000u: // veo -> Latn
+ case 0xBC950000u: // vep -> Latn
+ case 0xC4950000u: // ver -> Latn
+ case 0x76690000u: // vi -> Latn
+ case 0x89150000u: // vic -> Latn
+ case 0x8D150000u: // vid -> Latn
+ case 0x95150000u: // vif -> Latn
+ case 0x99150000u: // vig -> Latn
+ case 0xAD150000u: // vil -> Latn
+ case 0xB5150000u: // vin -> Latn
+ case 0xCD150000u: // vit -> Latn
+ case 0xD5150000u: // viv -> Latn
+ case 0x81550000u: // vka -> Latn
+ case 0xA5550000u: // vkj -> Latn
+ case 0xA9550000u: // vkk -> Latn
+ case 0xAD550000u: // vkl -> Latn
+ case 0xB1550000u: // vkm -> Latn
+ case 0xB5550000u: // vkn -> Latn
+ case 0xB9550000u: // vko -> Latn
+ case 0xBD550000u: // vkp -> Latn
+ case 0xCD550000u: // vkt -> Latn
+ case 0xD1550000u: // vku -> Latn
+ case 0xE5550000u: // vkz -> Latn
+ case 0xBD750000u: // vlp -> Latn
+ case 0xC9750000u: // vls -> Latn
+ case 0x81950000u: // vma -> Latn
+ case 0x85950000u: // vmb -> Latn
+ case 0x89950000u: // vmc -> Latn
+ case 0x91950000u: // vme -> Latn
+ case 0x95950000u: // vmf -> Latn
+ case 0x99950000u: // vmg -> Latn
+ case 0xA1950000u: // vmi -> Latn
+ case 0xA5950000u: // vmj -> Latn
+ case 0xA9950000u: // vmk -> Latn
+ case 0xAD950000u: // vml -> Latn
+ case 0xB1950000u: // vmm -> Latn
+ case 0xBD950000u: // vmp -> Latn
+ case 0xC1950000u: // vmq -> Latn
+ case 0xC5950000u: // vmr -> Latn
+ case 0xC9950000u: // vms -> Latn
+ case 0xD1950000u: // vmu -> Latn
+ case 0xD9950000u: // vmw -> Latn
+ case 0xDD950000u: // vmx -> Latn
+ case 0xE1950000u: // vmy -> Latn
+ case 0xE5950000u: // vmz -> Latn
+ case 0xA9B50000u: // vnk -> Latn
+ case 0xB1B50000u: // vnm -> Latn
+ case 0xBDB50000u: // vnp -> Latn
+ case 0x766F0000u: // vo -> Latn
+ case 0xC5D50000u: // vor -> Latn
+ case 0xCDD50000u: // vot -> Latn
+ case 0x82350000u: // vra -> Latn
+ case 0xBA350000u: // vro -> Latn
+ case 0xCA350000u: // vrs -> Latn
+ case 0xCE350000u: // vrt -> Latn
+ case 0xBA750000u: // vto -> Latn
+ case 0xB2950000u: // vum -> Latn
+ case 0xB6950000u: // vun -> Latn
+ case 0xCE950000u: // vut -> Latn
+ case 0x82D50000u: // vwa -> Latn
+ case 0x77610000u: // wa -> Latn
+ case 0x80160000u: // waa -> Latn
+ case 0x84160000u: // wab -> Latn
+ case 0x88160000u: // wac -> Latn
+ case 0x8C160000u: // wad -> Latn
+ case 0x90160000u: // wae -> Latn
+ case 0x94160000u: // waf -> Latn
+ case 0x98160000u: // wag -> Latn
+ case 0x9C160000u: // wah -> Latn
+ case 0xA0160000u: // wai -> Latn
+ case 0xA4160000u: // waj -> Latn
+ case 0xB0160000u: // wam -> Latn
+ case 0xB4160000u: // wan -> Latn
+ case 0xBC160000u: // wap -> Latn
+ case 0xC0160000u: // waq -> Latn
+ case 0xC4160000u: // war -> Latn
+ case 0xC8160000u: // was -> Latn
+ case 0xCC160000u: // wat -> Latn
+ case 0xD0160000u: // wau -> Latn
+ case 0xD4160000u: // wav -> Latn
+ case 0xD8160000u: // waw -> Latn
+ case 0xDC160000u: // wax -> Latn
+ case 0xE0160000u: // way -> Latn
+ case 0xE4160000u: // waz -> Latn
+ case 0x80360000u: // wba -> Latn
+ case 0x84360000u: // wbb -> Latn
+ case 0x90360000u: // wbe -> Latn
+ case 0x94360000u: // wbf -> Latn
+ case 0x9C360000u: // wbh -> Latn
+ case 0xA0360000u: // wbi -> Latn
+ case 0xA4360000u: // wbj -> Latn
+ case 0xAC360000u: // wbl -> Latn
+ case 0xB0360000u: // wbm -> Latn
+ case 0xBC360000u: // wbp -> Latn
+ case 0xCC360000u: // wbt -> Latn
+ case 0xD4360000u: // wbv -> Latn
+ case 0xD8360000u: // wbw -> Latn
+ case 0x80560000u: // wca -> Latn
+ case 0xA0560000u: // wci -> Latn
+ case 0x8C760000u: // wdd -> Latn
+ case 0x98760000u: // wdg -> Latn
+ case 0xA4760000u: // wdj -> Latn
+ case 0xA8760000u: // wdk -> Latn
+ case 0xCC760000u: // wdt -> Latn
+ case 0xD0760000u: // wdu -> Latn
+ case 0xE0760000u: // wdy -> Latn
+ case 0x88960000u: // wec -> Latn
+ case 0x8C960000u: // wed -> Latn
+ case 0x98960000u: // weg -> Latn
+ case 0x9C960000u: // weh -> Latn
+ case 0xA0960000u: // wei -> Latn
+ case 0xB0960000u: // wem -> Latn
+ case 0xB8960000u: // weo -> Latn
+ case 0xBC960000u: // wep -> Latn
+ case 0xC4960000u: // wer -> Latn
+ case 0xC8960000u: // wes -> Latn
+ case 0xCC960000u: // wet -> Latn
+ case 0xD0960000u: // weu -> Latn
+ case 0xD8960000u: // wew -> Latn
+ case 0x98B60000u: // wfg -> Latn
+ case 0x80D60000u: // wga -> Latn
+ case 0x84D60000u: // wgb -> Latn
+ case 0x98D60000u: // wgg -> Latn
+ case 0xA0D60000u: // wgi -> Latn
+ case 0xB8D60000u: // wgo -> Latn
+ case 0xD0D60000u: // wgu -> Latn
+ case 0xE0D60000u: // wgy -> Latn
+ case 0x80F60000u: // wha -> Latn
+ case 0x98F60000u: // whg -> Latn
+ case 0xA8F60000u: // whk -> Latn
+ case 0xD0F60000u: // whu -> Latn
+ case 0x85160000u: // wib -> Latn
+ case 0x89160000u: // wic -> Latn
+ case 0x91160000u: // wie -> Latn
+ case 0x95160000u: // wif -> Latn
+ case 0x99160000u: // wig -> Latn
+ case 0x9D160000u: // wih -> Latn
+ case 0xA1160000u: // wii -> Latn
+ case 0xA5160000u: // wij -> Latn
+ case 0xA9160000u: // wik -> Latn
+ case 0xAD160000u: // wil -> Latn
+ case 0xB1160000u: // wim -> Latn
+ case 0xB5160000u: // win -> Latn
+ case 0xC5160000u: // wir -> Latn
+ case 0xD1160000u: // wiu -> Latn
+ case 0xD5160000u: // wiv -> Latn
+ case 0xE1160000u: // wiy -> Latn
+ case 0x81360000u: // wja -> Latn
+ case 0xA1360000u: // wji -> Latn
+ case 0x81560000u: // wka -> Latn
+ case 0x8D560000u: // wkd -> Latn
+ case 0xC5560000u: // wkr -> Latn
+ case 0xD9560000u: // wkw -> Latn
+ case 0xE1560000u: // wky -> Latn
+ case 0x81760000u: // wla -> Latn
+ case 0x99760000u: // wlg -> Latn
+ case 0x9D760000u: // wlh -> Latn
+ case 0xA1760000u: // wli -> Latn
+ case 0xB1760000u: // wlm -> Latn
+ case 0xC5760000u: // wlr -> Latn
+ case 0xC9760000u: // wls -> Latn
+ case 0xD1760000u: // wlu -> Latn
+ case 0xD5760000u: // wlv -> Latn
+ case 0xD9760000u: // wlw -> Latn
+ case 0xDD760000u: // wlx -> Latn
+ case 0x81960000u: // wma -> Latn
+ case 0x85960000u: // wmb -> Latn
+ case 0x89960000u: // wmc -> Latn
+ case 0x8D960000u: // wmd -> Latn
+ case 0x9D960000u: // wmh -> Latn
+ case 0xA1960000u: // wmi -> Latn
+ case 0xB1960000u: // wmm -> Latn
+ case 0xB5960000u: // wmn -> Latn
+ case 0xB9960000u: // wmo -> Latn
+ case 0xC9960000u: // wms -> Latn
+ case 0xCD960000u: // wmt -> Latn
+ case 0xD9960000u: // wmw -> Latn
+ case 0xDD960000u: // wmx -> Latn
+ case 0x85B60000u: // wnb -> Latn
+ case 0x89B60000u: // wnc -> Latn
+ case 0x8DB60000u: // wnd -> Latn
+ case 0x99B60000u: // wng -> Latn
+ case 0xA9B60000u: // wnk -> Latn
+ case 0xB1B60000u: // wnm -> Latn
+ case 0xB5B60000u: // wnn -> Latn
+ case 0xB9B60000u: // wno -> Latn
+ case 0xBDB60000u: // wnp -> Latn
+ case 0xD1B60000u: // wnu -> Latn
+ case 0xD9B60000u: // wnw -> Latn
+ case 0xE1B60000u: // wny -> Latn
+ case 0x776F0000u: // wo -> Latn
+ case 0x81D60000u: // woa -> Latn
+ case 0x85D60000u: // wob -> Latn
+ case 0x89D60000u: // woc -> Latn
+ case 0x8DD60000u: // wod -> Latn
+ case 0x91D60000u: // woe -> Latn
+ case 0x95D60000u: // wof -> Latn
+ case 0x99D60000u: // wog -> Latn
+ case 0xA1D60000u: // woi -> Latn
+ case 0xA9D60000u: // wok -> Latn
+ case 0xB1D60000u: // wom -> Latn
+ case 0xB5D60000u: // won -> Latn
+ case 0xB9D60000u: // woo -> Latn
+ case 0xC5D60000u: // wor -> Latn
+ case 0xC9D60000u: // wos -> Latn
+ case 0xD9D60000u: // wow -> Latn
+ case 0x89F60000u: // wpc -> Latn
+ case 0x86360000u: // wrb -> Latn
+ case 0x9A360000u: // wrg -> Latn
+ case 0x9E360000u: // wrh -> Latn
+ case 0xA2360000u: // wri -> Latn
+ case 0xAA360000u: // wrk -> Latn
+ case 0xAE360000u: // wrl -> Latn
+ case 0xB2360000u: // wrm -> Latn
+ case 0xBA360000u: // wro -> Latn
+ case 0xBE360000u: // wrp -> Latn
+ case 0xC6360000u: // wrr -> Latn
+ case 0xCA360000u: // wrs -> Latn
+ case 0xD2360000u: // wru -> Latn
+ case 0xD6360000u: // wrv -> Latn
+ case 0xDA360000u: // wrw -> Latn
+ case 0xDE360000u: // wrx -> Latn
+ case 0xE6360000u: // wrz -> Latn
+ case 0x82560000u: // wsa -> Latn
+ case 0xA2560000u: // wsi -> Latn
+ case 0xAA560000u: // wsk -> Latn
+ case 0xC6560000u: // wsr -> Latn
+ case 0xCA560000u: // wss -> Latn
+ case 0xD2560000u: // wsu -> Latn
+ case 0x86760000u: // wtb -> Latn
+ case 0x96760000u: // wtf -> Latn
+ case 0x9E760000u: // wth -> Latn
+ case 0xA2760000u: // wti -> Latn
+ case 0xAA760000u: // wtk -> Latn
+ case 0xDA760000u: // wtw -> Latn
+ case 0x82960000u: // wua -> Latn
+ case 0x86960000u: // wub -> Latn
+ case 0x8E960000u: // wud -> Latn
+ case 0xAE960000u: // wul -> Latn
+ case 0xB2960000u: // wum -> Latn
+ case 0xB6960000u: // wun -> Latn
+ case 0xC6960000u: // wur -> Latn
+ case 0xCE960000u: // wut -> Latn
+ case 0xD6960000u: // wuv -> Latn
+ case 0xDE960000u: // wux -> Latn
+ case 0xE2960000u: // wuy -> Latn
+ case 0x82D60000u: // wwa -> Latn
+ case 0x86D60000u: // wwb -> Latn
+ case 0xBAD60000u: // wwo -> Latn
+ case 0xC6D60000u: // wwr -> Latn
+ case 0xDAD60000u: // www -> Latn
+ case 0xDAF60000u: // wxw -> Latn
+ case 0x87160000u: // wyb -> Latn
+ case 0xA3160000u: // wyi -> Latn
+ case 0xB3160000u: // wym -> Latn
+ case 0xB7160000u: // wyn -> Latn
+ case 0xC7160000u: // wyr -> Latn
+ case 0xE3160000u: // wyy -> Latn
+ case 0x80170000u: // xaa -> Latn
+ case 0x84170000u: // xab -> Latn
+ case 0xA0170000u: // xai -> Latn
+ case 0xA4170000u: // xaj -> Latn
+ case 0xA8170000u: // xak -> Latn
+ case 0xB0170000u: // xam -> Latn
+ case 0xB8170000u: // xao -> Latn
+ case 0xC4170000u: // xar -> Latn
+ case 0xCC170000u: // xat -> Latn
+ case 0xD0170000u: // xau -> Latn
+ case 0xD4170000u: // xav -> Latn
+ case 0xD8170000u: // xaw -> Latn
+ case 0xE0170000u: // xay -> Latn
+ case 0x84370000u: // xbb -> Latn
+ case 0x8C370000u: // xbd -> Latn
+ case 0x90370000u: // xbe -> Latn
+ case 0x98370000u: // xbg -> Latn
+ case 0xA0370000u: // xbi -> Latn
+ case 0xA4370000u: // xbj -> Latn
+ case 0xB0370000u: // xbm -> Latn
+ case 0xB4370000u: // xbn -> Latn
+ case 0xBC370000u: // xbp -> Latn
+ case 0xC4370000u: // xbr -> Latn
+ case 0xD8370000u: // xbw -> Latn
+ case 0xE0370000u: // xby -> Latn
+ case 0x9C570000u: // xch -> Latn
+ case 0x80770000u: // xda -> Latn
+ case 0xA8770000u: // xdk -> Latn
+ case 0xB8770000u: // xdo -> Latn
+ case 0xE0770000u: // xdy -> Latn
+ case 0x8C970000u: // xed -> Latn
+ case 0x98970000u: // xeg -> Latn
+ case 0xB0970000u: // xem -> Latn
+ case 0xC4970000u: // xer -> Latn
+ case 0xC8970000u: // xes -> Latn
+ case 0xCC970000u: // xet -> Latn
+ case 0xD0970000u: // xeu -> Latn
+ case 0x84D70000u: // xgb -> Latn
+ case 0x8CD70000u: // xgd -> Latn
+ case 0x98D70000u: // xgg -> Latn
+ case 0xA0D70000u: // xgi -> Latn
+ case 0xB0D70000u: // xgm -> Latn
+ case 0xD0D70000u: // xgu -> Latn
+ case 0xD8D70000u: // xgw -> Latn
+ case 0x78680000u: // xh -> Latn
+ case 0xD4F70000u: // xhv -> Latn
+ case 0xA1170000u: // xii -> Latn
+ case 0xB5170000u: // xin -> Latn
+ case 0xC5170000u: // xir -> Latn
+ case 0xE1170000u: // xiy -> Latn
+ case 0x85370000u: // xjb -> Latn
+ case 0xCD370000u: // xjt -> Latn
+ case 0x85570000u: // xkb -> Latn
+ case 0x8D570000u: // xkd -> Latn
+ case 0x91570000u: // xke -> Latn
+ case 0x99570000u: // xkg -> Latn
+ case 0xAD570000u: // xkl -> Latn
+ case 0xB5570000u: // xkn -> Latn
+ case 0xC1570000u: // xkq -> Latn
+ case 0xC5570000u: // xkr -> Latn
+ case 0xC9570000u: // xks -> Latn
+ case 0xCD570000u: // xkt -> Latn
+ case 0xD1570000u: // xku -> Latn
+ case 0xD5570000u: // xkv -> Latn
+ case 0xD9570000u: // xkw -> Latn
+ case 0xDD570000u: // xkx -> Latn
+ case 0xE1570000u: // xky -> Latn
+ case 0xE5570000u: // xkz -> Latn
+ case 0x81770000u: // xla -> Latn
+ case 0x81970000u: // xma -> Latn
+ case 0x85970000u: // xmb -> Latn
+ case 0x89970000u: // xmc -> Latn
+ case 0x8D970000u: // xmd -> Latn
+ case 0x99970000u: // xmg -> Latn
+ case 0x9D970000u: // xmh -> Latn
+ case 0xA5970000u: // xmj -> Latn
+ case 0xB1970000u: // xmm -> Latn
+ case 0xB9970000u: // xmo -> Latn
+ case 0xBD970000u: // xmp -> Latn
+ case 0xC1970000u: // xmq -> Latn
+ case 0xCD970000u: // xmt -> Latn
+ case 0xD1970000u: // xmu -> Latn
+ case 0xD5970000u: // xmv -> Latn
+ case 0xD9970000u: // xmw -> Latn
+ case 0xDD970000u: // xmx -> Latn
+ case 0xE1970000u: // xmy -> Latn
+ case 0xE5970000u: // xmz -> Latn
+ case 0x85B70000u: // xnb -> Latn
+ case 0xA1B70000u: // xni -> Latn
+ case 0xA5B70000u: // xnj -> Latn
+ case 0xA9B70000u: // xnk -> Latn
+ case 0xB1B70000u: // xnm -> Latn
+ case 0xB5B70000u: // xnn -> Latn
+ case 0xC1B70000u: // xnq -> Latn
+ case 0xCDB70000u: // xnt -> Latn
+ case 0xD1B70000u: // xnu -> Latn
+ case 0xE1B70000u: // xny -> Latn
+ case 0xE5B70000u: // xnz -> Latn
+ case 0x89D70000u: // xoc -> Latn
+ case 0x8DD70000u: // xod -> Latn
+ case 0x99D70000u: // xog -> Latn
+ case 0xA1D70000u: // xoi -> Latn
+ case 0xA9D70000u: // xok -> Latn
+ case 0xB1D70000u: // xom -> Latn
+ case 0xB5D70000u: // xon -> Latn
+ case 0xB9D70000u: // xoo -> Latn
+ case 0xBDD70000u: // xop -> Latn
+ case 0xC5D70000u: // xor -> Latn
+ case 0xD9D70000u: // xow -> Latn
+ case 0x81F70000u: // xpa -> Latn
+ case 0x85F70000u: // xpb -> Latn
+ case 0x8DF70000u: // xpd -> Latn
+ case 0x95F70000u: // xpf -> Latn
+ case 0x9DF70000u: // xph -> Latn
+ case 0xA5F70000u: // xpj -> Latn
+ case 0xA9F70000u: // xpk -> Latn
+ case 0xADF70000u: // xpl -> Latn
+ case 0xB5F70000u: // xpn -> Latn
+ case 0xB9F70000u: // xpo -> Latn
+ case 0xC1F70000u: // xpq -> Latn
+ case 0xCDF70000u: // xpt -> Latn
+ case 0xD5F70000u: // xpv -> Latn
+ case 0xD9F70000u: // xpw -> Latn
+ case 0xDDF70000u: // xpx -> Latn
+ case 0xE5F70000u: // xpz -> Latn
+ case 0x82370000u: // xra -> Latn
+ case 0x86370000u: // xrb -> Latn
+ case 0x8E370000u: // xrd -> Latn
+ case 0x92370000u: // xre -> Latn
+ case 0x9A370000u: // xrg -> Latn
+ case 0xA2370000u: // xri -> Latn
+ case 0xC6370000u: // xrr -> Latn
+ case 0xD2370000u: // xru -> Latn
+ case 0xDA370000u: // xrw -> Latn
+ case 0x86570000u: // xsb -> Latn
+ case 0x92570000u: // xse -> Latn
+ case 0x9E570000u: // xsh -> Latn
+ case 0xA2570000u: // xsi -> Latn
+ case 0xB2570000u: // xsm -> Latn
+ case 0xB6570000u: // xsn -> Latn
+ case 0xBE570000u: // xsp -> Latn
+ case 0xC2570000u: // xsq -> Latn
+ case 0xD2570000u: // xsu -> Latn
+ case 0xE2570000u: // xsy -> Latn
+ case 0x82770000u: // xta -> Latn
+ case 0x86770000u: // xtb -> Latn
+ case 0x8A770000u: // xtc -> Latn
+ case 0x8E770000u: // xtd -> Latn
+ case 0x92770000u: // xte -> Latn
+ case 0x9E770000u: // xth -> Latn
+ case 0xA2770000u: // xti -> Latn
+ case 0xA6770000u: // xtj -> Latn
+ case 0xAE770000u: // xtl -> Latn
+ case 0xB2770000u: // xtm -> Latn
+ case 0xB6770000u: // xtn -> Latn
+ case 0xBE770000u: // xtp -> Latn
+ case 0xCA770000u: // xts -> Latn
+ case 0xCE770000u: // xtt -> Latn
+ case 0xD2770000u: // xtu -> Latn
+ case 0xD6770000u: // xtv -> Latn
+ case 0xDA770000u: // xtw -> Latn
+ case 0xE2770000u: // xty -> Latn
+ case 0x8E970000u: // xud -> Latn
+ case 0xAE970000u: // xul -> Latn
+ case 0xB2970000u: // xum -> Latn
+ case 0xB6970000u: // xun -> Latn
+ case 0xBA970000u: // xuo -> Latn
+ case 0xCE970000u: // xut -> Latn
+ case 0xD2970000u: // xuu -> Latn
+ case 0xB6B70000u: // xvn -> Latn
+ case 0xBAB70000u: // xvo -> Latn
+ case 0xCAB70000u: // xvs -> Latn
+ case 0x82D70000u: // xwa -> Latn
+ case 0x8ED70000u: // xwd -> Latn
+ case 0x92D70000u: // xwe -> Latn
+ case 0xA6D70000u: // xwj -> Latn
+ case 0xAAD70000u: // xwk -> Latn
+ case 0xAED70000u: // xwl -> Latn
+ case 0xC6D70000u: // xwr -> Latn
+ case 0xCED70000u: // xwt -> Latn
+ case 0xDAD70000u: // xww -> Latn
+ case 0x86F70000u: // xxb -> Latn
+ case 0xAAF70000u: // xxk -> Latn
+ case 0xB2F70000u: // xxm -> Latn
+ case 0xC6F70000u: // xxr -> Latn
+ case 0xCEF70000u: // xxt -> Latn
+ case 0x83170000u: // xya -> Latn
+ case 0x87170000u: // xyb -> Latn
+ case 0xA7170000u: // xyj -> Latn
+ case 0xAB170000u: // xyk -> Latn
+ case 0xAF170000u: // xyl -> Latn
+ case 0xCF170000u: // xyt -> Latn
+ case 0xE3170000u: // xyy -> Latn
+ case 0xBF370000u: // xzp -> Latn
+ case 0x80180000u: // yaa -> Latn
+ case 0x84180000u: // yab -> Latn
+ case 0x88180000u: // yac -> Latn
+ case 0x8C180000u: // yad -> Latn
+ case 0x90180000u: // yae -> Latn
+ case 0x94180000u: // yaf -> Latn
+ case 0x98180000u: // yag -> Latn
+ case 0x9C180000u: // yah -> Latn
+ case 0xA4180000u: // yaj -> Latn
+ case 0xA8180000u: // yak -> Latn
+ case 0xAC180000u: // yal -> Latn
+ case 0xB0180000u: // yam -> Latn
+ case 0xB4180000u: // yan -> Latn
+ case 0xB8180000u: // yao -> Latn
+ case 0xBC180000u: // yap -> Latn
+ case 0xC0180000u: // yaq -> Latn
+ case 0xC4180000u: // yar -> Latn
+ case 0xC8180000u: // yas -> Latn
+ case 0xCC180000u: // yat -> Latn
+ case 0xD0180000u: // yau -> Latn
+ case 0xD4180000u: // yav -> Latn
+ case 0xD8180000u: // yaw -> Latn
+ case 0xDC180000u: // yax -> Latn
+ case 0xE0180000u: // yay -> Latn
+ case 0xE4180000u: // yaz -> Latn
+ case 0x80380000u: // yba -> Latn
+ case 0x84380000u: // ybb -> Latn
+ case 0x90380000u: // ybe -> Latn
+ case 0xA4380000u: // ybj -> Latn
+ case 0xAC380000u: // ybl -> Latn
+ case 0xB0380000u: // ybm -> Latn
+ case 0xB4380000u: // ybn -> Latn
+ case 0xB8380000u: // ybo -> Latn
+ case 0xDC380000u: // ybx -> Latn
+ case 0xE0380000u: // yby -> Latn
+ case 0xAC580000u: // ycl -> Latn
+ case 0xB4580000u: // ycn -> Latn
+ case 0xC4580000u: // ycr -> Latn
+ case 0x80780000u: // yda -> Latn
+ case 0x90780000u: // yde -> Latn
+ case 0xA8780000u: // ydk -> Latn
+ case 0x88980000u: // yec -> Latn
+ case 0x90980000u: // yee -> Latn
+ case 0xA0980000u: // yei -> Latn
+ case 0xAC980000u: // yel -> Latn
+ case 0xC4980000u: // yer -> Latn
+ case 0xC8980000u: // yes -> Latn
+ case 0xCC980000u: // yet -> Latn
+ case 0xD4980000u: // yev -> Latn
+ case 0xE0980000u: // yey -> Latn
+ case 0x80D80000u: // yga -> Latn
+ case 0xA0D80000u: // ygi -> Latn
+ case 0xACD80000u: // ygl -> Latn
+ case 0xB0D80000u: // ygm -> Latn
+ case 0xC4D80000u: // ygr -> Latn
+ case 0xD0D80000u: // ygu -> Latn
+ case 0xD8D80000u: // ygw -> Latn
+ case 0x81180000u: // yia -> Latn
+ case 0xA1180000u: // yii -> Latn
+ case 0xA5180000u: // yij -> Latn
+ case 0xAD180000u: // yil -> Latn
+ case 0xB1180000u: // yim -> Latn
+ case 0xC5180000u: // yir -> Latn
+ case 0xC9180000u: // yis -> Latn
+ case 0x81580000u: // yka -> Latn
+ case 0xA1580000u: // yki -> Latn
+ case 0xA9580000u: // ykk -> Latn
+ case 0xB1580000u: // ykm -> Latn
+ case 0xB9580000u: // yko -> Latn
+ case 0xC5580000u: // ykr -> Latn
+ case 0xE1580000u: // yky -> Latn
+ case 0x81780000u: // yla -> Latn
+ case 0x85780000u: // ylb -> Latn
+ case 0x91780000u: // yle -> Latn
+ case 0x99780000u: // ylg -> Latn
+ case 0xA1780000u: // yli -> Latn
+ case 0xAD780000u: // yll -> Latn
+ case 0xC5780000u: // ylr -> Latn
+ case 0xD1780000u: // ylu -> Latn
+ case 0xE1780000u: // yly -> Latn
+ case 0x85980000u: // ymb -> Latn
+ case 0x91980000u: // yme -> Latn
+ case 0x99980000u: // ymg -> Latn
+ case 0xA9980000u: // ymk -> Latn
+ case 0xAD980000u: // yml -> Latn
+ case 0xB1980000u: // ymm -> Latn
+ case 0xB5980000u: // ymn -> Latn
+ case 0xB9980000u: // ymo -> Latn
+ case 0xBD980000u: // ymp -> Latn
+ case 0x8DB80000u: // ynd -> Latn
+ case 0x99B80000u: // yng -> Latn
+ case 0xADB80000u: // ynl -> Latn
+ case 0xC1B80000u: // ynq -> Latn
+ case 0xC9B80000u: // yns -> Latn
+ case 0xD1B80000u: // ynu -> Latn
+ case 0x796F0000u: // yo -> Latn
+ case 0x85D80000u: // yob -> Latn
+ case 0x99D80000u: // yog -> Latn
+ case 0xA9D80000u: // yok -> Latn
+ case 0xADD80000u: // yol -> Latn
+ case 0xB1D80000u: // yom -> Latn
+ case 0xB5D80000u: // yon -> Latn
+ case 0xCDD80000u: // yot -> Latn
+ case 0x82380000u: // yra -> Latn
+ case 0x86380000u: // yrb -> Latn
+ case 0x92380000u: // yre -> Latn
+ case 0xAE380000u: // yrl -> Latn
+ case 0xB2380000u: // yrm -> Latn
+ case 0xBA380000u: // yro -> Latn
+ case 0xCA380000u: // yrs -> Latn
+ case 0xDA380000u: // yrw -> Latn
+ case 0xE2380000u: // yry -> Latn
+ case 0xCA580000u: // yss -> Latn
+ case 0xDA780000u: // ytw -> Latn
+ case 0xE2780000u: // yty -> Latn
+ case 0x82980000u: // yua -> Latn
+ case 0x86980000u: // yub -> Latn
+ case 0x8A980000u: // yuc -> Latn
+ case 0x96980000u: // yuf -> Latn
+ case 0xA2980000u: // yui -> Latn
+ case 0xA6980000u: // yuj -> Latn
+ case 0xAE980000u: // yul -> Latn
+ case 0xB2980000u: // yum -> Latn
+ case 0xB6980000u: // yun -> Latn
+ case 0xBE980000u: // yup -> Latn
+ case 0xC2980000u: // yuq -> Latn
+ case 0xC6980000u: // yur -> Latn
+ case 0xCE980000u: // yut -> Latn
+ case 0xDA980000u: // yuw -> Latn
+ case 0xE6980000u: // yuz -> Latn
+ case 0x82B80000u: // yva -> Latn
+ case 0xCEB80000u: // yvt -> Latn
+ case 0x82D80000u: // ywa -> Latn
+ case 0x9AD80000u: // ywg -> Latn
+ case 0xB6D80000u: // ywn -> Latn
+ case 0xC6D80000u: // ywr -> Latn
+ case 0xDAD80000u: // yww -> Latn
+ case 0x82F80000u: // yxa -> Latn
+ case 0x9AF80000u: // yxg -> Latn
+ case 0xAEF80000u: // yxl -> Latn
+ case 0xB2F80000u: // yxm -> Latn
+ case 0xD2F80000u: // yxu -> Latn
+ case 0xE2F80000u: // yxy -> Latn
+ case 0xC7180000u: // yyr -> Latn
+ case 0xD3180000u: // yyu -> Latn
+ case 0x7A610000u: // za -> Latn
+ case 0x80190000u: // zaa -> Latn
+ case 0x84190000u: // zab -> Latn
+ case 0x88190000u: // zac -> Latn
+ case 0x8C190000u: // zad -> Latn
+ case 0x90190000u: // zae -> Latn
+ case 0x94190000u: // zaf -> Latn
+ case 0x98190000u: // zag -> Latn
+ case 0x9C190000u: // zah -> Latn
+ case 0xA4190000u: // zaj -> Latn
+ case 0xA8190000u: // zak -> Latn
+ case 0xB0190000u: // zam -> Latn
+ case 0xB8190000u: // zao -> Latn
+ case 0xBC190000u: // zap -> Latn
+ case 0xC0190000u: // zaq -> Latn
+ case 0xC4190000u: // zar -> Latn
+ case 0xC8190000u: // zas -> Latn
+ case 0xCC190000u: // zat -> Latn
+ case 0xD4190000u: // zav -> Latn
+ case 0xD8190000u: // zaw -> Latn
+ case 0xDC190000u: // zax -> Latn
+ case 0xE0190000u: // zay -> Latn
+ case 0xE4190000u: // zaz -> Latn
+ case 0x88390000u: // zbc -> Latn
+ case 0x90390000u: // zbe -> Latn
+ case 0xCC390000u: // zbt -> Latn
+ case 0xD0390000u: // zbu -> Latn
+ case 0xD8390000u: // zbw -> Latn
+ case 0x80590000u: // zca -> Latn
+ case 0x80990000u: // zea -> Latn
+ case 0x98990000u: // zeg -> Latn
+ case 0xB0990000u: // zem -> Latn
+ case 0x80D90000u: // zga -> Latn
+ case 0xC4D90000u: // zgr -> Latn
+ case 0xA0F90000u: // zhi -> Latn
+ case 0xB4F90000u: // zhn -> Latn
+ case 0xD8F90000u: // zhw -> Latn
+ case 0x81190000u: // zia -> Latn
+ case 0xA9190000u: // zik -> Latn
+ case 0xAD190000u: // zil -> Latn
+ case 0xB1190000u: // zim -> Latn
+ case 0xB5190000u: // zin -> Latn
+ case 0xD9190000u: // ziw -> Latn
+ case 0xE5190000u: // ziz -> Latn
+ case 0x81590000u: // zka -> Latn
+ case 0x8D590000u: // zkd -> Latn
+ case 0xBD590000u: // zkp -> Latn
+ case 0xD1590000u: // zku -> Latn
+ case 0x81790000u: // zla -> Latn
+ case 0xB1790000u: // zlm -> Latn
+ case 0xD1790000u: // zlu -> Latn
+ case 0x81990000u: // zma -> Latn
+ case 0x85990000u: // zmb -> Latn
+ case 0x89990000u: // zmc -> Latn
+ case 0x8D990000u: // zmd -> Latn
+ case 0x91990000u: // zme -> Latn
+ case 0x95990000u: // zmf -> Latn
+ case 0x99990000u: // zmg -> Latn
+ case 0x9D990000u: // zmh -> Latn
+ case 0xA1990000u: // zmi -> Latn
+ case 0xA5990000u: // zmj -> Latn
+ case 0xA9990000u: // zmk -> Latn
+ case 0xAD990000u: // zml -> Latn
+ case 0xB1990000u: // zmm -> Latn
+ case 0xB5990000u: // zmn -> Latn
+ case 0xB9990000u: // zmo -> Latn
+ case 0xBD990000u: // zmp -> Latn
+ case 0xC1990000u: // zmq -> Latn
+ case 0xC5990000u: // zmr -> Latn
+ case 0xC9990000u: // zms -> Latn
+ case 0xCD990000u: // zmt -> Latn
+ case 0xD1990000u: // zmu -> Latn
+ case 0xD5990000u: // zmv -> Latn
+ case 0xD9990000u: // zmw -> Latn
+ case 0xDD990000u: // zmx -> Latn
+ case 0xE1990000u: // zmy -> Latn
+ case 0xE5990000u: // zmz -> Latn
+ case 0x81B90000u: // zna -> Latn
+ case 0x91B90000u: // zne -> Latn
+ case 0x99B90000u: // zng -> Latn
+ case 0xA9B90000u: // znk -> Latn
+ case 0xC9B90000u: // zns -> Latn
+ case 0x89D90000u: // zoc -> Latn
+ case 0x9DD90000u: // zoh -> Latn
+ case 0xB1D90000u: // zom -> Latn
+ case 0xB9D90000u: // zoo -> Latn
+ case 0xC1D90000u: // zoq -> Latn
+ case 0xC5D90000u: // zor -> Latn
+ case 0xC9D90000u: // zos -> Latn
+ case 0x81F90000u: // zpa -> Latn
+ case 0x85F90000u: // zpb -> Latn
+ case 0x89F90000u: // zpc -> Latn
+ case 0x8DF90000u: // zpd -> Latn
+ case 0x91F90000u: // zpe -> Latn
+ case 0x95F90000u: // zpf -> Latn
+ case 0x99F90000u: // zpg -> Latn
+ case 0x9DF90000u: // zph -> Latn
+ case 0xA1F90000u: // zpi -> Latn
+ case 0xA5F90000u: // zpj -> Latn
+ case 0xA9F90000u: // zpk -> Latn
+ case 0xADF90000u: // zpl -> Latn
+ case 0xB1F90000u: // zpm -> Latn
+ case 0xB5F90000u: // zpn -> Latn
+ case 0xB9F90000u: // zpo -> Latn
+ case 0xBDF90000u: // zpp -> Latn
+ case 0xC1F90000u: // zpq -> Latn
+ case 0xC5F90000u: // zpr -> Latn
+ case 0xC9F90000u: // zps -> Latn
+ case 0xCDF90000u: // zpt -> Latn
+ case 0xD1F90000u: // zpu -> Latn
+ case 0xD5F90000u: // zpv -> Latn
+ case 0xD9F90000u: // zpw -> Latn
+ case 0xDDF90000u: // zpx -> Latn
+ case 0xE1F90000u: // zpy -> Latn
+ case 0xE5F90000u: // zpz -> Latn
+ case 0xB6390000u: // zrn -> Latn
+ case 0xBA390000u: // zro -> Latn
+ case 0xCA390000u: // zrs -> Latn
+ case 0x82590000u: // zsa -> Latn
+ case 0xC6590000u: // zsr -> Latn
+ case 0xD2590000u: // zsu -> Latn
+ case 0x92790000u: // zte -> Latn
+ case 0x9A790000u: // ztg -> Latn
+ case 0xAE790000u: // ztl -> Latn
+ case 0xB2790000u: // ztm -> Latn
+ case 0xB6790000u: // ztn -> Latn
+ case 0xBE790000u: // ztp -> Latn
+ case 0xC2790000u: // ztq -> Latn
+ case 0xCA790000u: // zts -> Latn
+ case 0xCE790000u: // ztt -> Latn
+ case 0xD2790000u: // ztu -> Latn
+ case 0xDE790000u: // ztx -> Latn
+ case 0xE2790000u: // zty -> Latn
+ case 0x7A750000u: // zu -> Latn
+ case 0x9E990000u: // zuh -> Latn
+ case 0xB6990000u: // zun -> Latn
+ case 0xE2990000u: // zuy -> Latn
+ case 0xA7190000u: // zyj -> Latn
+ case 0xBF190000u: // zyp -> Latn
+ case 0x83390000u: // zza -> Latn
+ return SCRIPT_CODES[55u];
+ case 0xBC8B0000u: // lep -> Lepc
+ return SCRIPT_CODES[56u];
+ case 0x840B0000u: // lab -> Lina
+ return SCRIPT_CODES[57u];
+ case 0xE1860000u: // gmy -> Linb
+ return SCRIPT_CODES[58u];
+ case 0xC90B0000u: // lis -> Lisu
+ return SCRIPT_CODES[59u];
+ case 0xE1880000u: // imy -> Lyci
+ case 0x89770000u: // xlc -> Lyci
+ return SCRIPT_CODES[60u];
+ case 0x8D770000u: // xld -> Lydi
+ return SCRIPT_CODES[61u];
+ case 0x8D0C0000u: // mid -> Mand
+ case 0xE70C0000u: // myz -> Mand
+ return SCRIPT_CODES[62u];
+ case 0xB5970000u: // xmn -> Mani
+ return SCRIPT_CODES[63u];
+ case 0x9F370000u: // xzh -> Marc
+ return SCRIPT_CODES[64u];
+ case 0x95830000u: // dmf -> Medf
+ return SCRIPT_CODES[65u];
+ case 0xC5970000u: // xmr -> Merc
+ return SCRIPT_CODES[66u];
+ case 0x94000000u: // aaf -> Mlym
+ case 0xAD600000u: // all -> Mlym
+ case 0xD48A0000u: // kev -> Mlym
+ case 0x9CAA0000u: // kfh -> Mlym
+ case 0xC12C0000u: // mjq -> Mlym
+ case 0xC52C0000u: // mjr -> Mlym
+ case 0xD52C0000u: // mjv -> Mlym
+ case 0x6D6C0000u: // ml -> Mlym
+ case 0x944F0000u: // pcf -> Mlym
+ case 0x984F0000u: // pcg -> Mlym
+ case 0xC54F0000u: // pkr -> Mlym
+ case 0x98740000u: // udg -> Mlym
+ case 0x80980000u: // yea -> Mlym
+ return SCRIPT_CODES[67u];
+ case 0xC58E0000u: // omr -> Modi
+ return SCRIPT_CODES[68u];
+ case 0xD2E10000u: // bxu -> Mong
+ case 0x6D6E434Eu: // mn-CN -> Mong
+ case 0x89AC0000u: // mnc -> Mong
+ case 0x96AC0000u: // mvf -> Mong
+ return SCRIPT_CODES[69u];
+ case 0xBA2C0000u: // mro -> Mroo
+ return SCRIPT_CODES[70u];
+ case 0xBD8E0000u: // omp -> Mtei
+ return SCRIPT_CODES[71u];
+ case 0xB9000000u: // aio -> Mymr
+ case 0xA9610000u: // blk -> Mymr
+ case 0x92C10000u: // bwe -> Mymr
+ case 0x9E420000u: // csh -> Mymr
+ case 0xD1A30000u: // dnu -> Mymr
+ case 0xD5A30000u: // dnv -> Mymr
+ case 0xB9E70000u: // hpo -> Mymr
+ case 0xCDA80000u: // int -> Mymr
+ case 0xB1490000u: // jkm -> Mymr
+ case 0xCCEA0000u: // kht -> Mymr
+ case 0xBD2A0000u: // kjp -> Mymr
+ case 0xD24A0000u: // ksu -> Mymr
+ case 0xDA4A0000u: // ksw -> Mymr
+ case 0xC2AA0000u: // kvq -> Mymr
+ case 0xCEAA0000u: // kvt -> Mymr
+ case 0x96EA0000u: // kxf -> Mymr
+ case 0xAAEA0000u: // kxk -> Mymr
+ case 0xD9AC0000u: // mnw -> Mymr
+ case 0xCECC0000u: // mwt -> Mymr
+ case 0x6D790000u: // my -> Mymr
+ case 0xC42E0000u: // obr -> Mymr
+ case 0xDD8E0000u: // omx -> Mymr
+ case 0x904F0000u: // pce -> Mymr
+ case 0xA8EF0000u: // phk -> Mymr
+ case 0xAD6F0000u: // pll -> Mymr
+ case 0xBACF0000u: // pwo -> Mymr
+ case 0xDF0F0000u: // pyx -> Mymr
+ case 0x84310000u: // rbb -> Mymr
+ case 0xA1510000u: // rki -> Mymr
+ case 0xE5910000u: // rmz -> Mymr
+ case 0xB4F20000u: // shn -> Mymr
+ case 0xB8530000u: // tco -> Mymr
+ case 0xAD330000u: // tjl -> Mymr
+ case 0xB6B30000u: // tvn -> Mymr
+ return SCRIPT_CODES[72u];
+ case 0x81B70000u: // xna -> Narb
+ return SCRIPT_CODES[73u];
+ case 0x8ACD0000u: // nwc -> Newa
+ return SCRIPT_CODES[74u];
+ case 0xB40C474Eu: // man-GN -> Nkoo
+ case 0xBA0D0000u: // nqo -> Nkoo
+ return SCRIPT_CODES[75u];
+ case 0xDCF90000u: // zhx -> Nshu
+ return SCRIPT_CODES[76u];
+ case 0xACCF0000u: // pgl -> Ogam
+ case 0x80D20000u: // sga -> Ogam
+ case 0xA1F70000u: // xpi -> Ogam
+ return SCRIPT_CODES[77u];
+ case 0xCC120000u: // sat -> Olck
+ return SCRIPT_CODES[78u];
+ case 0xAA6E0000u: // otk -> Orkh
+ return SCRIPT_CODES[79u];
+ case 0xD4610000u: // bdv -> Orya
+ case 0xD8A10000u: // bfw -> Orya
+ case 0xBA430000u: // dso -> Orya
+ case 0xAAC30000u: // dwk -> Orya
+ case 0xC0060000u: // gaq -> Orya
+ case 0xA4260000u: // gbj -> Orya
+ case 0x84660000u: // gdb -> Orya
+ case 0xB6890000u: // jun -> Orya
+ case 0xE2890000u: // juy -> Orya
+ case 0x6F720000u: // or -> Orya
+ case 0x988F0000u: // peg -> Orya
+ case 0xA0910000u: // rei -> Orya
+ case 0xD5F20000u: // spv -> Orya
+ case 0xA1540000u: // uki -> Orya
+ case 0xC9170000u: // xis -> Orya
+ case 0x9A390000u: // zrg -> Orya
+ return SCRIPT_CODES[80u];
+ case 0x824E0000u: // osa -> Osge
+ return SCRIPT_CODES[81u];
+ case 0xA28E0000u: // oui -> Ougr
+ return SCRIPT_CODES[82u];
+ case 0x8E620000u: // ctd -> Pauc
+ return SCRIPT_CODES[83u];
+ case 0xAC0F0000u: // pal -> Phli
+ return SCRIPT_CODES[84u];
+ case 0xB02E0000u: // obm -> Phnx
+ case 0xB4EF0000u: // phn -> Phnx
+ return SCRIPT_CODES[85u];
+ case 0x8D870000u: // hmd -> Plrd
+ case 0xBE6A0000u: // ktp -> Plrd
+ case 0xB9EB0000u: // lpo -> Plrd
+ case 0xB0B20000u: // sfm -> Plrd
+ case 0xBCD80000u: // ygp -> Plrd
+ case 0x81B80000u: // yna -> Plrd
+ case 0xE2580000u: // ysy -> Plrd
+ case 0xC2D80000u: // ywq -> Plrd
+ case 0xD2D80000u: // ywu -> Plrd
+ return SCRIPT_CODES[86u];
+ case 0xC5F70000u: // xpr -> Prti
+ return SCRIPT_CODES[87u];
+ case 0xAC200000u: // abl -> Rjng
+ return SCRIPT_CODES[88u];
+ case 0x98F10000u: // rhg -> Rohg
+ return SCRIPT_CODES[89u];
+ case 0xB5CD0000u: // non -> Runr
+ case 0xB62D0000u: // nrn -> Runr
+ case 0xD2F20000u: // sxu -> Runr
+ return SCRIPT_CODES[90u];
+ case 0xB0120000u: // sam -> Samr
+ case 0xBD920000u: // smp -> Samr
+ return SCRIPT_CODES[91u];
+ case 0x82570000u: // xsa -> Sarb
+ return SCRIPT_CODES[92u];
+ case 0xE4120000u: // saz -> Saur
+ return SCRIPT_CODES[93u];
+ case 0x92400000u: // ase -> Sgnw
+ return SCRIPT_CODES[94u];
+ case 0x70690000u: // pi -> Sinh
+ case 0x73690000u: // si -> Sinh
+ return SCRIPT_CODES[95u];
+ case 0x99D20000u: // sog -> Sogd
+ return SCRIPT_CODES[96u];
+ case 0x86320000u: // srb -> Sora
+ return SCRIPT_CODES[97u];
+ case 0x99820000u: // cmg -> Soyo
+ return SCRIPT_CODES[98u];
+ case 0xE6920000u: // suz -> Sunu
+ return SCRIPT_CODES[99u];
+ case 0xA1000000u: // aii -> Syrc
+ case 0xD9800000u: // amw -> Syrc
+ case 0xB4E10000u: // bhn -> Syrc
+ case 0x95210000u: // bjf -> Syrc
+ case 0xCE270000u: // hrt -> Syrc
+ case 0x8E0A0000u: // kqd -> Syrc
+ case 0xC8EB0000u: // lhs -> Syrc
+ case 0xC40E0000u: // oar -> Syrc
+ case 0x8B120000u: // syc -> Syrc
+ case 0xB7120000u: // syn -> Syrc
+ case 0xC7120000u: // syr -> Syrc
+ case 0xC5930000u: // tmr -> Syrc
+ return SCRIPT_CODES[100u];
+ case 0xA8330000u: // tbk -> Tagb
+ return SCRIPT_CODES[101u];
+ case 0xA1070000u: // hii -> Takr
+ case 0x81A90000u: // jna -> Takr
+ case 0xD0520000u: // scu -> Takr
+ return SCRIPT_CODES[102u];
+ case 0x8C730000u: // tdd -> Tale
+ case 0xA0F30000u: // thi -> Tale
+ return SCRIPT_CODES[103u];
+ case 0x84EA0000u: // khb -> Talu
+ return SCRIPT_CODES[104u];
+ case 0xC0A10000u: // bfq -> Taml
+ case 0xCE620000u: // ctt -> Taml
+ case 0xE2620000u: // cty -> Taml
+ case 0x82240000u: // era -> Taml
+ case 0xD2280000u: // iru -> Taml
+ case 0x90AA0000u: // kfe -> Taml
+ case 0xA0AA0000u: // kfi -> Taml
+ case 0xD68C0000u: // muv -> Taml
+ case 0x74610000u: // ta -> Taml
+ case 0xDC530000u: // tcx -> Taml
+ case 0x80150000u: // vaa -> Taml
+ case 0x86970000u: // xub -> Taml
+ case 0xA6970000u: // xuj -> Taml
+ return SCRIPT_CODES[105u];
+ case 0x9AF30000u: // txg -> Tang
+ return SCRIPT_CODES[106u];
+ case 0xCD610000u: // blt -> Tavt
+ case 0x81D20000u: // soa -> Tavt
+ case 0xC7130000u: // tyr -> Tavt
+ return SCRIPT_CODES[107u];
+ case 0x90620000u: // cde -> Telu
+ case 0xD0060000u: // gau -> Telu
+ case 0xE08A0000u: // key -> Telu
+ case 0x88AA0000u: // kfc -> Telu
+ case 0xB58B0000u: // lmn -> Telu
+ case 0xD12C0000u: // mju -> Telu
+ case 0xCD0D0000u: // nit -> Telu
+ case 0xCE2E0000u: // ort -> Telu
+ case 0xA44F0000u: // pcj -> Telu
+ case 0x74650000u: // te -> Telu
+ case 0xC0360000u: // wbq -> Telu
+ case 0xD0980000u: // yeu -> Telu
+ return SCRIPT_CODES[108u];
+ case 0xB8E60000u: // gho -> Tfng
+ case 0xA0F20000u: // shi -> Tfng
+ case 0x80730000u: // tda -> Tfng
+ case 0xB4990000u: // zen -> Tfng
+ case 0x9CD90000u: // zgh -> Tfng
+ return SCRIPT_CODES[109u];
+ case 0x64760000u: // dv -> Thaa
+ return SCRIPT_CODES[110u];
+ case 0xA3210000u: // bzi -> Thai
+ case 0xB4220000u: // cbn -> Thai
+ case 0x99C20000u: // cog -> Thai
+ case 0xCC6A0000u: // kdt -> Thai
+ case 0x94EA0000u: // khf -> Thai
+ case 0xCD2A0000u: // kjt -> Thai
+ case 0xB2EA0000u: // kxm -> Thai
+ case 0xBC4B0000u: // lcp -> Thai
+ case 0xAECB0000u: // lwl -> Thai
+ case 0xB2CB0000u: // lwm -> Thai
+ case 0xB14C0000u: // mkm -> Thai
+ case 0x956C0000u: // mlf -> Thai
+ case 0xE5EC0000u: // mpz -> Thai
+ case 0x822C0000u: // mra -> Thai
+ case 0xAF0D0000u: // nyl -> Thai
+ case 0xDB0D0000u: // nyw -> Thai
+ case 0xCCEF0000u: // pht -> Thai
+ case 0xD0EF0000u: // phu -> Thai
+ case 0xCE2F0000u: // prt -> Thai
+ case 0xDACF0000u: // pww -> Thai
+ case 0x85520000u: // skb -> Thai
+ case 0xD1D20000u: // sou -> Thai
+ case 0x74680000u: // th -> Thai
+ case 0xB0F30000u: // thm -> Thai
+ case 0xCA730000u: // tts -> Thai
+ case 0xB8D40000u: // ugo -> Thai
+ case 0xAA340000u: // urk -> Thai
+ case 0xE1D80000u: // yoy -> Thai
+ return SCRIPT_CODES[111u];
+ case 0xDC600000u: // adx -> Tibt
+ case 0xD0A10000u: // bfu -> Tibt
+ case 0xA9410000u: // bkk -> Tibt
+ case 0x626F0000u: // bo -> Tibt
+ case 0xBA210000u: // bro -> Tibt
+ case 0xA8C20000u: // cgk -> Tibt
+ case 0x81A20000u: // cna -> Tibt
+ case 0x81430000u: // dka -> Tibt
+ case 0x92230000u: // dre -> Tibt
+ case 0x647A0000u: // dz -> Tibt
+ case 0xAF230000u: // dzl -> Tibt
+ case 0xCCE60000u: // ght -> Tibt
+ case 0x91C60000u: // goe -> Tibt
+ case 0x80690000u: // jda -> Tibt
+ case 0x83090000u: // jya -> Tibt
+ case 0x982A0000u: // kbg -> Tibt
+ case 0x98EA0000u: // khg -> Tibt
+ case 0xE52A0000u: // kjz -> Tibt
+ case 0x954A0000u: // kkf -> Tibt
+ case 0xA42B0000u: // lbj -> Tibt
+ case 0x9D4B0000u: // lkh -> Tibt
+ case 0xAA8B0000u: // luk -> Tibt
+ case 0x830B0000u: // lya -> Tibt
+ case 0xAA8C0000u: // muk -> Tibt
+ case 0x9C8D0000u: // neh -> Tibt
+ case 0x85ED0000u: // npb -> Tibt
+ case 0x916E0000u: // ole -> Tibt
+ case 0x866E0000u: // otb -> Tibt
+ case 0xD0320000u: // sbu -> Tibt
+ case 0xCCD20000u: // sgt -> Tibt
+ case 0xBD120000u: // sip -> Tibt
+ case 0xCDF20000u: // spt -> Tibt
+ case 0xB4530000u: // tcn -> Tibt
+ case 0x94D30000u: // tgf -> Tibt
+ case 0xA6530000u: // tsj -> Tibt
+ case 0x95570000u: // xkf -> Tibt
+ case 0xD0190000u: // zau -> Tibt
+ return SCRIPT_CODES[112u];
+ case 0xCE4D0000u: // nst -> Tnsa
+ return SCRIPT_CODES[113u];
+ case 0xBAF30000u: // txo -> Toto
+ return SCRIPT_CODES[114u];
+ case 0x80D40000u: // uga -> Ugar
+ return SCRIPT_CODES[115u];
+ case 0xA0150000u: // vai -> Vaii
+ return SCRIPT_CODES[116u];
+ case 0xBDAD0000u: // nnp -> Wcho
+ return SCRIPT_CODES[117u];
+ case 0xB88F0000u: // peo -> Xpeo
+ return SCRIPT_CODES[118u];
+ case 0xA9400000u: // akk -> Xsux
+ case 0xCD070000u: // hit -> Xsux
+ case 0xDE670000u: // htx -> Xsux
+ case 0xA08D0000u: // nei -> Xsux
+ case 0xCCEE0000u: // oht -> Xsux
+ return SCRIPT_CODES[119u];
+ case 0x69690000u: // ii -> Yiii
+ case 0xC9CD0000u: // nos -> Yiii
+ case 0x8E4D0000u: // nsd -> Yiii
+ case 0x964D0000u: // nsf -> Yiii
+ case 0xD64D0000u: // nsv -> Yiii
+ case 0xE26D0000u: // nty -> Yiii
+ case 0x9D920000u: // smh -> Yiii
+ case 0x99180000u: // yig -> Yiii
+ case 0xD5180000u: // yiv -> Yiii
+ case 0x8E580000u: // ysd -> Yiii
+ case 0xB6580000u: // ysn -> Yiii
+ case 0xBE580000u: // ysp -> Yiii
+ return SCRIPT_CODES[120u];
+ case 0x656E5841u: // en-XA -> ~~~A
+ return SCRIPT_CODES[121u];
+ case 0x61725842u: // ar-XB -> ~~~B
+ return SCRIPT_CODES[122u];
+ default:
+ return nullptr;
+ }
+}
+
+/*
+ * TODO: Consider turning the below switch statement into binary search
+ * to save the disk space when the table is larger in the future.
+ * Disassembled code shows that the jump table emitted by clang can be
+ * 4x larger than the data in disk size, but it depends on the optimization option.
+ * However, a switch statement will benefit from the future of compiler improvement.
+ */
+bool isLocaleRepresentative(uint32_t language_and_region, const char* script) {
+ const uint64_t packed_locale =
+ ((static_cast<uint64_t>(language_and_region)) << 32u) |
+ (static_cast<uint64_t>(packScript(script)));
+ switch(packed_locale) {
+ case 0x616145544C61746ELLU: // aa_Latn_ET
+ case 0x80004E474C61746ELLU: // aaa_Latn_NG
+ case 0x84004E474C61746ELLU: // aab_Latn_NG
+ case 0x880050474C61746ELLU: // aac_Latn_PG
+ case 0x8C0050474C61746ELLU: // aad_Latn_PG
+ case 0x900049544C61746ELLU: // aae_Latn_IT
+ case 0x9400494E4D6C796DLLU: // aaf_Mlym_IN
+ case 0x980050474C61746ELLU: // aag_Latn_PG
+ case 0x9C0050474C61746ELLU: // aah_Latn_PG
+ case 0xA00050474C61746ELLU: // aai_Latn_PG
+ case 0xA80050474C61746ELLU: // aak_Latn_PG
+ case 0xAC00434D4C61746ELLU: // aal_Latn_CM
+ case 0xB40042524C61746ELLU: // aan_Latn_BR
+ case 0xB800445A41726162LLU: // aao_Arab_DZ
+ case 0xBC0042524C61746ELLU: // aap_Latn_BR
+ case 0xC00055534C61746ELLU: // aaq_Latn_US
+ case 0xC800545A4C61746ELLU: // aas_Latn_TZ
+ case 0xCC0047524772656BLLU: // aat_Grek_GR
+ case 0xD00050474C61746ELLU: // aau_Latn_PG
+ case 0xD80050474C61746ELLU: // aaw_Latn_PG
+ case 0xDC0049444C61746ELLU: // aax_Latn_ID
+ case 0xE40049444C61746ELLU: // aaz_Latn_ID
+ case 0x616247454379726CLLU: // ab_Cyrl_GE
+ case 0x802043494C61746ELLU: // aba_Latn_CI
+ case 0x8420434D4C61746ELLU: // abb_Latn_CM
+ case 0x882050484C61746ELLU: // abc_Latn_PH
+ case 0x8C2050484C61746ELLU: // abd_Latn_PH
+ case 0x902043414C61746ELLU: // abe_Latn_CA
+ case 0x94204D594C61746ELLU: // abf_Latn_MY
+ case 0x982050474C61746ELLU: // abg_Latn_PG
+ case 0x9C20544A41726162LLU: // abh_Arab_TJ
+ case 0xA02043494C61746ELLU: // abi_Latn_CI
+ case 0xAC204944526A6E67LLU: // abl_Rjng_ID
+ case 0xB0204E474C61746ELLU: // abm_Latn_NG
+ case 0xB4204E474C61746ELLU: // abn_Latn_NG
+ case 0xB8204E474C61746ELLU: // abo_Latn_NG
+ case 0xBC2050484C61746ELLU: // abp_Latn_PH
+ case 0xC42047484C61746ELLU: // abr_Latn_GH
+ case 0xC82049444C61746ELLU: // abs_Latn_ID
+ case 0xCC2050474C61746ELLU: // abt_Latn_PG
+ case 0xD02043494C61746ELLU: // abu_Latn_CI
+ case 0xD420424841726162LLU: // abv_Arab_BH
+ case 0xD82050474C61746ELLU: // abw_Latn_PG
+ case 0xDC2050484C61746ELLU: // abx_Latn_PH
+ case 0xE02050474C61746ELLU: // aby_Latn_PG
+ case 0xE42049444C61746ELLU: // abz_Latn_ID
+ case 0x8040434F4C61746ELLU: // aca_Latn_CO
+ case 0x84404E474C61746ELLU: // acb_Latn_NG
+ case 0x8C4047484C61746ELLU: // acd_Latn_GH
+ case 0x904049444C61746ELLU: // ace_Latn_ID
+ case 0x94404C434C61746ELLU: // acf_Latn_LC
+ case 0x9C4055474C61746ELLU: // ach_Latn_UG
+ case 0xB040495141726162LLU: // acm_Arab_IQ
+ case 0xB440434E4C61746ELLU: // acn_Latn_CN
+ case 0xBC404E474C61746ELLU: // acp_Latn_NG
+ case 0xC040594541726162LLU: // acq_Arab_YE
+ case 0xC44047544C61746ELLU: // acr_Latn_GT
+ case 0xC84042524C61746ELLU: // acs_Latn_BR
+ case 0xCC404E4C4C61746ELLU: // act_Latn_NL
+ case 0xD04045434C61746ELLU: // acu_Latn_EC
+ case 0xD44055534C61746ELLU: // acv_Latn_US
+ case 0xD840534141726162LLU: // acw_Arab_SA
+ case 0xDC404F4D41726162LLU: // acx_Arab_OM
+ case 0xE04043594C61746ELLU: // acy_Latn_CY
+ case 0xE44053444C61746ELLU: // acz_Latn_SD
+ case 0x806047484C61746ELLU: // ada_Latn_GH
+ case 0x8460544C4C61746ELLU: // adb_Latn_TL
+ case 0x8C60434D4C61746ELLU: // add_Latn_CM
+ case 0x906054474C61746ELLU: // ade_Latn_TG
+ case 0x94604F4D41726162LLU: // adf_Arab_OM
+ case 0x986041554C61746ELLU: // adg_Latn_AU
+ case 0x9C6055474C61746ELLU: // adh_Latn_UG
+ case 0xA060494E4C61746ELLU: // adi_Latn_IN
+ case 0xA46043494C61746ELLU: // adj_Latn_CI
+ case 0xAC60494E4C61746ELLU: // adl_Latn_IN
+ case 0xB46049444C61746ELLU: // adn_Latn_ID
+ case 0xB86050474C61746ELLU: // ado_Latn_PG
+ case 0xC06047484C61746ELLU: // adq_Latn_GH
+ case 0xC46049444C61746ELLU: // adr_Latn_ID
+ case 0xCC6041554C61746ELLU: // adt_Latn_AU
+ case 0xD0604E474C61746ELLU: // adu_Latn_NG
+ case 0xD86042524C61746ELLU: // adw_Latn_BR
+ case 0xDC60434E54696274LLU: // adx_Tibt_CN
+ case 0xE06052554379726CLLU: // ady_Cyrl_RU
+ case 0xE46050474C61746ELLU: // adz_Latn_PG
+ case 0x6165495241767374LLU: // ae_Avst_IR
+ case 0x808041554C61746ELLU: // aea_Latn_AU
+ case 0x8480544E41726162LLU: // aeb_Arab_TN
+ case 0x8880454741726162LLU: // aec_Arab_EG
+ case 0x9080414641726162LLU: // aee_Arab_AF
+ case 0xA8804E434C61746ELLU: // aek_Latn_NC
+ case 0xAC80434D4C61746ELLU: // ael_Latn_CM
+ case 0xB080564E4C61746ELLU: // aem_Latn_VN
+ case 0xC080504B41726162LLU: // aeq_Arab_PK
+ case 0xC48041554C61746ELLU: // aer_Latn_AU
+ case 0xD080434E4C61746ELLU: // aeu_Latn_CN
+ case 0xD88050474C61746ELLU: // aew_Latn_PG
+ case 0xE08050474C61746ELLU: // aey_Latn_PG
+ case 0xE48050474C61746ELLU: // aez_Latn_PG
+ case 0x61665A414C61746ELLU: // af_Latn_ZA
+ case 0x84A04B5741726162LLU: // afb_Arab_KW
+ case 0x8CA050474C61746ELLU: // afd_Latn_PG
+ case 0x90A04E474C61746ELLU: // afe_Latn_NG
+ case 0x9CA047484C61746ELLU: // afh_Latn_GH
+ case 0xA0A050474C61746ELLU: // afi_Latn_PG
+ case 0xA8A050474C61746ELLU: // afk_Latn_PG
+ case 0xB4A04E474C61746ELLU: // afn_Latn_NG
+ case 0xB8A04E474C61746ELLU: // afo_Latn_NG
+ case 0xBCA050474C61746ELLU: // afp_Latn_PG
+ case 0xC8A04D584C61746ELLU: // afs_Latn_MX
+ case 0xD0A047484C61746ELLU: // afu_Latn_GH
+ case 0xE4A049444C61746ELLU: // afz_Latn_ID
+ case 0x80C050454C61746ELLU: // aga_Latn_PE
+ case 0x84C04E474C61746ELLU: // agb_Latn_NG
+ case 0x88C04E474C61746ELLU: // agc_Latn_NG
+ case 0x8CC050474C61746ELLU: // agd_Latn_PG
+ case 0x90C050474C61746ELLU: // age_Latn_PG
+ case 0x94C049444C61746ELLU: // agf_Latn_ID
+ case 0x98C050474C61746ELLU: // agg_Latn_PG
+ case 0x9CC043444C61746ELLU: // agh_Latn_CD
+ case 0xA0C0494E44657661LLU: // agi_Deva_IN
+ case 0xA4C0455445746869LLU: // agj_Ethi_ET
+ case 0xA8C050484C61746ELLU: // agk_Latn_PH
+ case 0xACC050474C61746ELLU: // agl_Latn_PG
+ case 0xB0C050474C61746ELLU: // agm_Latn_PG
+ case 0xB4C050484C61746ELLU: // agn_Latn_PH
+ case 0xB8C050474C61746ELLU: // ago_Latn_PG
+ case 0xC0C0434D4C61746ELLU: // agq_Latn_CM
+ case 0xC4C050454C61746ELLU: // agr_Latn_PE
+ case 0xC8C0434D4C61746ELLU: // ags_Latn_CM
+ case 0xCCC050484C61746ELLU: // agt_Latn_PH
+ case 0xD0C047544C61746ELLU: // agu_Latn_GT
+ case 0xD4C050484C61746ELLU: // agv_Latn_PH
+ case 0xD8C053424C61746ELLU: // agw_Latn_SB
+ case 0xDCC052554379726CLLU: // agx_Cyrl_RU
+ case 0xE0C050484C61746ELLU: // agy_Latn_PH
+ case 0xE4C050484C61746ELLU: // agz_Latn_PH
+ case 0x80E047484C61746ELLU: // aha_Latn_GH
+ case 0x84E056554C61746ELLU: // ahb_Latn_VU
+ case 0x98E0455445746869LLU: // ahg_Ethi_ET
+ case 0x9CE049444C61746ELLU: // ahh_Latn_ID
+ case 0xA0E043494C61746ELLU: // ahi_Latn_CI
+ case 0xA8E04D4D4C61746ELLU: // ahk_Latn_MM
+ case 0xACE054474C61746ELLU: // ahl_Latn_TG
+ case 0xB0E043494C61746ELLU: // ahm_Latn_CI
+ case 0xB4E04E474C61746ELLU: // ahn_Latn_NG
+ case 0xB8E0494E41686F6DLLU: // aho_Ahom_IN
+ case 0xBCE043494C61746ELLU: // ahp_Latn_CI
+ case 0xC4E0494E44657661LLU: // ahr_Deva_IN
+ case 0xC8E04E474C61746ELLU: // ahs_Latn_NG
+ case 0xCCE055534C61746ELLU: // aht_Latn_US
+ case 0x810053424C61746ELLU: // aia_Latn_SB
+ case 0x8500434E41726162LLU: // aib_Arab_CN
+ case 0x890050474C61746ELLU: // aic_Latn_PG
+ case 0x8D0041554C61746ELLU: // aid_Latn_AU
+ case 0x910050474C61746ELLU: // aie_Latn_PG
+ case 0x950050474C61746ELLU: // aif_Latn_PG
+ case 0x990041474C61746ELLU: // aig_Latn_AG
+ case 0xA100495153797263LLU: // aii_Syrc_IQ
+ case 0xA500494C48656272LLU: // aij_Hebr_IL
+ case 0xA9004E474C61746ELLU: // aik_Latn_NG
+ case 0xAD0050474C61746ELLU: // ail_Latn_PG
+ case 0xB100494E4C61746ELLU: // aim_Latn_IN
+ case 0xB5004A504B616E61LLU: // ain_Kana_JP
+ case 0xB900494E4D796D72LLU: // aio_Mymr_IN
+ case 0xBD0049444C61746ELLU: // aip_Latn_ID
+ case 0xC100414641726162LLU: // aiq_Arab_AF
+ case 0xC50049444C61746ELLU: // air_Latn_ID
+ case 0xCD0042524C61746ELLU: // ait_Latn_BR
+ case 0xD90045544C61746ELLU: // aiw_Latn_ET
+ case 0xDD0050474C61746ELLU: // aix_Latn_PG
+ case 0xE10043464C61746ELLU: // aiy_Latn_CF
+ case 0x812053534C61746ELLU: // aja_Latn_SS
+ case 0x9920424A4C61746ELLU: // ajg_Latn_BJ
+ case 0xA1204E434C61746ELLU: // aji_Latn_NC
+ case 0xB52041554C61746ELLU: // ajn_Latn_AU
+ case 0xD9204E474C61746ELLU: // ajw_Latn_NG
+ case 0xE520494E4C61746ELLU: // ajz_Latn_IN
+ case 0x616B47484C61746ELLU: // ak_Latn_GH
+ case 0x854049444C61746ELLU: // akb_Latn_ID
+ case 0x894049444C61746ELLU: // akc_Latn_ID
+ case 0x8D404E474C61746ELLU: // akd_Latn_NG
+ case 0x914047594C61746ELLU: // ake_Latn_GY
+ case 0x95404E474C61746ELLU: // akf_Latn_NG
+ case 0x994049444C61746ELLU: // akg_Latn_ID
+ case 0x9D4050474C61746ELLU: // akh_Latn_PG
+ case 0xA14050474C61746ELLU: // aki_Latn_PG
+ case 0xA940495158737578LLU: // akk_Xsux_IQ
+ case 0xAD4050484C61746ELLU: // akl_Latn_PH
+ case 0xB94053524C61746ELLU: // ako_Latn_SR
+ case 0xBD4047484C61746ELLU: // akp_Latn_GH
+ case 0xC14050474C61746ELLU: // akq_Latn_PG
+ case 0xC54056554C61746ELLU: // akr_Latn_VU
+ case 0xC94054474C61746ELLU: // aks_Latn_TG
+ case 0xCD4050474C61746ELLU: // akt_Latn_PG
+ case 0xD140434D4C61746ELLU: // aku_Latn_CM
+ case 0xD54052554379726CLLU: // akv_Cyrl_RU
+ case 0xD94043474C61746ELLU: // akw_Latn_CG
+ case 0xE54055534C61746ELLU: // akz_Latn_US
+ case 0x81604E474C61746ELLU: // ala_Latn_NG
+ case 0x8960434C4C61746ELLU: // alc_Latn_CL
+ case 0x8D6043494C61746ELLU: // ald_Latn_CI
+ case 0x916055534C61746ELLU: // ale_Latn_US
+ case 0x95604E474C61746ELLU: // alf_Latn_NG
+ case 0x9D6041554C61746ELLU: // alh_Latn_AU
+ case 0xA16050474C61746ELLU: // ali_Latn_PG
+ case 0xA56050484C61746ELLU: // alj_Latn_PH
+ case 0xA9604C414C616F6FLLU: // alk_Laoo_LA
+ case 0xAD60494E4D6C796DLLU: // all_Mlym_IN
+ case 0xB16056554C61746ELLU: // alm_Latn_VU
+ case 0xB560584B4C61746ELLU: // aln_Latn_XK
+ case 0xB96049444C61746ELLU: // alo_Latn_ID
+ case 0xBD6049444C61746ELLU: // alp_Latn_ID
+ case 0xC16043414C61746ELLU: // alq_Latn_CA
+ case 0xC56052554379726CLLU: // alr_Cyrl_RU
+ case 0xCD6052554379726CLLU: // alt_Cyrl_RU
+ case 0xD16053424C61746ELLU: // alu_Latn_SB
+ case 0xD960455445746869LLU: // alw_Ethi_ET
+ case 0xDD6050474C61746ELLU: // alx_Latn_PG
+ case 0xE16041554C61746ELLU: // aly_Latn_AU
+ case 0xE56043444C61746ELLU: // alz_Latn_CD
+ case 0x616D455445746869LLU: // am_Ethi_ET
+ case 0x818042524C61746ELLU: // ama_Latn_BR
+ case 0x85804E474C61746ELLU: // amb_Latn_NG
+ case 0x898050454C61746ELLU: // amc_Latn_PE
+ case 0x918050454C61746ELLU: // ame_Latn_PE
+ case 0x958045544C61746ELLU: // amf_Latn_ET
+ case 0x998041554C61746ELLU: // amg_Latn_AU
+ case 0xA18054574C61746ELLU: // ami_Latn_TW
+ case 0xA58054444C61746ELLU: // amj_Latn_TD
+ case 0xA98049444C61746ELLU: // amk_Latn_ID
+ case 0xB18050474C61746ELLU: // amm_Latn_PG
+ case 0xB58050474C61746ELLU: // amn_Latn_PG
+ case 0xB9804E474C61746ELLU: // amo_Latn_NG
+ case 0xBD8050474C61746ELLU: // amp_Latn_PG
+ case 0xC18049444C61746ELLU: // amq_Latn_ID
+ case 0xC58050454C61746ELLU: // amr_Latn_PE
+ case 0xC9804A504A70616ELLU: // ams_Jpan_JP
+ case 0xCD8050474C61746ELLU: // amt_Latn_PG
+ case 0xD1804D584C61746ELLU: // amu_Latn_MX
+ case 0xD58049444C61746ELLU: // amv_Latn_ID
+ case 0xD980535953797263LLU: // amw_Syrc_SY
+ case 0xDD8041554C61746ELLU: // amx_Latn_AU
+ case 0xE18041554C61746ELLU: // amy_Latn_AU
+ case 0xE58041554C61746ELLU: // amz_Latn_AU
+ case 0x616E45534C61746ELLU: // an_Latn_ES
+ case 0x81A0434F4C61746ELLU: // ana_Latn_CO
+ case 0x85A050454C61746ELLU: // anb_Latn_PE
+ case 0x89A04E474C61746ELLU: // anc_Latn_NG
+ case 0x8DA049444C61746ELLU: // and_Latn_ID
+ case 0x91A04E434C61746ELLU: // ane_Latn_NC
+ case 0x95A047484C61746ELLU: // anf_Latn_GH
+ case 0x99A047424C61746ELLU: // ang_Latn_GB
+ case 0x9DA050474C61746ELLU: // anh_Latn_PG
+ case 0xA1A052554379726CLLU: // ani_Cyrl_RU
+ case 0xA5A050474C61746ELLU: // anj_Latn_PG
+ case 0xA9A04E474C61746ELLU: // ank_Latn_NG
+ case 0xADA04D4D4C61746ELLU: // anl_Latn_MM
+ case 0xB1A0494E4C61746ELLU: // anm_Latn_IN
+ case 0xB5A04E474C61746ELLU: // ann_Latn_NG
+ case 0xB9A0434F4C61746ELLU: // ano_Latn_CO
+ case 0xBDA0494E44657661LLU: // anp_Deva_IN
+ case 0xC1A0494E44657661LLU: // anq_Deva_IN
+ case 0xC5A0494E44657661LLU: // anr_Deva_IN
+ case 0xC9A0434F4C61746ELLU: // ans_Latn_CO
+ case 0xCDA041554C61746ELLU: // ant_Latn_AU
+ case 0xD1A0455445746869LLU: // anu_Ethi_ET
+ case 0xD5A0434D4C61746ELLU: // anv_Latn_CM
+ case 0xD9A04E474C61746ELLU: // anw_Latn_NG
+ case 0xDDA050474C61746ELLU: // anx_Latn_PG
+ case 0xE1A043494C61746ELLU: // any_Latn_CI
+ case 0xE5A050474C61746ELLU: // anz_Latn_PG
+ case 0x81C053544C61746ELLU: // aoa_Latn_ST
+ case 0x85C050474C61746ELLU: // aob_Latn_PG
+ case 0x89C056454C61746ELLU: // aoc_Latn_VE
+ case 0x8DC050474C61746ELLU: // aod_Latn_PG
+ case 0x91C050474C61746ELLU: // aoe_Latn_PG
+ case 0x95C050474C61746ELLU: // aof_Latn_PG
+ case 0x99C050474C61746ELLU: // aog_Latn_PG
+ case 0xA1C041554C61746ELLU: // aoi_Latn_AU
+ case 0xA5C050474C61746ELLU: // aoj_Latn_PG
+ case 0xA9C04E434C61746ELLU: // aok_Latn_NC
+ case 0xADC049444C61746ELLU: // aol_Latn_ID
+ case 0xB1C050474C61746ELLU: // aom_Latn_PG
+ case 0xB5C050474C61746ELLU: // aon_Latn_PG
+ case 0xC5C056554C61746ELLU: // aor_Latn_VU
+ case 0xC9C049444C61746ELLU: // aos_Latn_ID
+ case 0xCDC0424442656E67LLU: // aot_Beng_BD
+ case 0xDDC047594C61746ELLU: // aox_Latn_GY
+ case 0xE5C049444C61746ELLU: // aoz_Latn_ID
+ case 0x85E053424C61746ELLU: // apb_Latn_SB
+ case 0x89E0535941726162LLU: // apc_Arab_SY
+ case 0x8DE0544741726162LLU: // apd_Arab_TG
+ case 0x91E050474C61746ELLU: // ape_Latn_PG
+ case 0x95E050484C61746ELLU: // apf_Latn_PH
+ case 0x99E049444C61746ELLU: // apg_Latn_ID
+ case 0x9DE04E5044657661LLU: // aph_Deva_NP
+ case 0xA1E042524C61746ELLU: // api_Latn_BR
+ case 0xA5E055534C61746ELLU: // apj_Latn_US
+ case 0xA9E055534C61746ELLU: // apk_Latn_US
+ case 0xADE055534C61746ELLU: // apl_Latn_US
+ case 0xB1E055534C61746ELLU: // apm_Latn_US
+ case 0xB5E042524C61746ELLU: // apn_Latn_BR
+ case 0xB9E050474C61746ELLU: // apo_Latn_PG
+ case 0xBDE056554C61746ELLU: // app_Latn_VU
+ case 0xC5E050474C61746ELLU: // apr_Latn_PG
+ case 0xC9E050474C61746ELLU: // aps_Latn_PG
+ case 0xCDE0494E4C61746ELLU: // apt_Latn_IN
+ case 0xD1E042524C61746ELLU: // apu_Latn_BR
+ case 0xD5E042524C61746ELLU: // apv_Latn_BR
+ case 0xD9E055534C61746ELLU: // apw_Latn_US
+ case 0xDDE049444C61746ELLU: // apx_Latn_ID
+ case 0xE1E042524C61746ELLU: // apy_Latn_BR
+ case 0xE5E050474C61746ELLU: // apz_Latn_PG
+ case 0x8A0052554379726CLLU: // aqc_Cyrl_RU
+ case 0x8E004D4C4C61746ELLU: // aqd_Latn_ML
+ case 0x9A004E474C61746ELLU: // aqg_Latn_NG
+ case 0xAA004E474C61746ELLU: // aqk_Latn_NG
+ case 0xB20049444C61746ELLU: // aqm_Latn_ID
+ case 0xB60050484C61746ELLU: // aqn_Latn_PH
+ case 0xC6004E434C61746ELLU: // aqr_Latn_NC
+ case 0xCE0050594C61746ELLU: // aqt_Latn_PY
+ case 0xE60042524C61746ELLU: // aqz_Latn_BR
+ case 0x6172454741726162LLU: // ar_Arab_EG
+ case 0x8A20495241726D69LLU: // arc_Armi_IR
+ case 0x8A20495148617472LLU: // arc_Hatr_IQ
+ case 0x8A204A4F4E626174LLU: // arc_Nbat_JO
+ case 0x8A20535950616C6DLLU: // arc_Palm_SY
+ case 0x8E2041554C61746ELLU: // ard_Latn_AU
+ case 0x922041554C61746ELLU: // are_Latn_AU
+ case 0x9E20434F4C61746ELLU: // arh_Latn_CO
+ case 0xA22055534C61746ELLU: // ari_Latn_US
+ case 0xA62042524C61746ELLU: // arj_Latn_BR
+ case 0xAA2042524C61746ELLU: // ark_Latn_BR
+ case 0xAE2050454C61746ELLU: // arl_Latn_PE
+ case 0xB620434C4C61746ELLU: // arn_Latn_CL
+ case 0xBA20424F4C61746ELLU: // aro_Latn_BO
+ case 0xBE2055534C61746ELLU: // arp_Latn_US
+ case 0xC220445A41726162LLU: // arq_Arab_DZ
+ case 0xC62042524C61746ELLU: // arr_Latn_BR
+ case 0xCA20534141726162LLU: // ars_Arab_SA
+ case 0xD22042524C61746ELLU: // aru_Latn_BR
+ case 0xDA2053524C61746ELLU: // arw_Latn_SR
+ case 0xDE2042524C61746ELLU: // arx_Latn_BR
+ case 0xE2204D4141726162LLU: // ary_Arab_MA
+ case 0xE620454741726162LLU: // arz_Arab_EG
+ case 0x6173494E42656E67LLU: // as_Beng_IN
+ case 0x8240545A4C61746ELLU: // asa_Latn_TZ
+ case 0x864043414C61746ELLU: // asb_Latn_CA
+ case 0x8A4049444C61746ELLU: // asc_Latn_ID
+ case 0x9240555353676E77LLU: // ase_Sgnw_US
+ case 0x9A404E474C61746ELLU: // asg_Latn_NG
+ case 0x9E4050454C61746ELLU: // ash_Latn_PE
+ case 0xA24049444C61746ELLU: // asi_Latn_ID
+ case 0xA640434D4C61746ELLU: // asj_Latn_CM
+ case 0xAA40414641726162LLU: // ask_Arab_AF
+ case 0xAE4049444C61746ELLU: // asl_Latn_ID
+ case 0xB64042524C61746ELLU: // asn_Latn_BR
+ case 0xBA4050474C61746ELLU: // aso_Latn_PG
+ case 0xC640494E44657661LLU: // asr_Deva_IN
+ case 0xCA40434D4C61746ELLU: // ass_Latn_CM
+ case 0xCE4045534C61746ELLU: // ast_Latn_ES
+ case 0xD24042524C61746ELLU: // asu_Latn_BR
+ case 0xD64043444C61746ELLU: // asv_Latn_CD
+ case 0xDE4050474C61746ELLU: // asx_Latn_PG
+ case 0xE24049444C61746ELLU: // asy_Latn_ID
+ case 0xE64049444C61746ELLU: // asz_Latn_ID
+ case 0x826050474C61746ELLU: // ata_Latn_PG
+ case 0x8660434E4C61746ELLU: // atb_Latn_CN
+ case 0x8A6050454C61746ELLU: // atc_Latn_PE
+ case 0x8E6050484C61746ELLU: // atd_Latn_PH
+ case 0x926050474C61746ELLU: // ate_Latn_PG
+ case 0x9A604E474C61746ELLU: // atg_Latn_NG
+ case 0xA26043494C61746ELLU: // ati_Latn_CI
+ case 0xA66043414C61746ELLU: // atj_Latn_CA
+ case 0xAA6050484C61746ELLU: // atk_Latn_PH
+ case 0xAE6050484C61746ELLU: // atl_Latn_PH
+ case 0xB26050484C61746ELLU: // atm_Latn_PH
+ case 0xB660495241726162LLU: // atn_Arab_IR
+ case 0xBA60434D4C61746ELLU: // ato_Latn_CM
+ case 0xBE6050484C61746ELLU: // atp_Latn_PH
+ case 0xC26049444C61746ELLU: // atq_Latn_ID
+ case 0xC66042524C61746ELLU: // atr_Latn_BR
+ case 0xCA6055534C61746ELLU: // ats_Latn_US
+ case 0xCE6050484C61746ELLU: // att_Latn_PH
+ case 0xD26053534C61746ELLU: // atu_Latn_SS
+ case 0xD66052554379726CLLU: // atv_Cyrl_RU
+ case 0xDA6055534C61746ELLU: // atw_Latn_US
+ case 0xDE6042524C61746ELLU: // atx_Latn_BR
+ case 0xE26056554C61746ELLU: // aty_Latn_VU
+ case 0xE66050484C61746ELLU: // atz_Latn_PH
+ case 0x828053424C61746ELLU: // aua_Latn_SB
+ case 0x8A8045434C61746ELLU: // auc_Latn_EC
+ case 0x8E8053424C61746ELLU: // aud_Latn_SB
+ case 0x9A80424A4C61746ELLU: // aug_Latn_BJ
+ case 0x9E805A4D4C61746ELLU: // auh_Latn_ZM
+ case 0xA28050474C61746ELLU: // aui_Latn_PG
+ case 0xA6804C5941726162LLU: // auj_Arab_LY
+ case 0xAA8050474C61746ELLU: // auk_Latn_PG
+ case 0xAE8056554C61746ELLU: // aul_Latn_VU
+ case 0xB2804E474C61746ELLU: // aum_Latn_NG
+ case 0xB68050474C61746ELLU: // aun_Latn_PG
+ case 0xBA804E474C61746ELLU: // auo_Latn_NG
+ case 0xBE8050474C61746ELLU: // aup_Latn_PG
+ case 0xC28049444C61746ELLU: // auq_Latn_ID
+ case 0xC68050474C61746ELLU: // aur_Latn_PG
+ case 0xCE8050464C61746ELLU: // aut_Latn_PF
+ case 0xD28049444C61746ELLU: // auu_Latn_ID
+ case 0xDA8049444C61746ELLU: // auw_Latn_ID
+ case 0xE28050474C61746ELLU: // auy_Latn_PG
+ case 0xE680555A41726162LLU: // auz_Arab_UZ
+ case 0x617652554379726CLLU: // av_Cyrl_RU
+ case 0x86A050474C61746ELLU: // avb_Latn_PG
+ case 0x8EA0495241726162LLU: // avd_Arab_IR
+ case 0xA2A043494C61746ELLU: // avi_Latn_CI
+ case 0xAEA0454741726162LLU: // avl_Arab_EG
+ case 0xB2A041554C61746ELLU: // avm_Latn_AU
+ case 0xB6A047484C61746ELLU: // avn_Latn_GH
+ case 0xBAA042524C61746ELLU: // avo_Latn_BR
+ case 0xCAA050454C61746ELLU: // avs_Latn_PE
+ case 0xCEA050474C61746ELLU: // avt_Latn_PG
+ case 0xD2A053534C61746ELLU: // avu_Latn_SS
+ case 0xD6A042524C61746ELLU: // avv_Latn_BR
+ case 0x82C0494E44657661LLU: // awa_Deva_IN
+ case 0x86C050474C61746ELLU: // awb_Latn_PG
+ case 0x8AC04E474C61746ELLU: // awc_Latn_NG
+ case 0x92C042524C61746ELLU: // awe_Latn_BR
+ case 0x9AC041554C61746ELLU: // awg_Latn_AU
+ case 0x9EC049444C61746ELLU: // awh_Latn_ID
+ case 0xA2C050474C61746ELLU: // awi_Latn_PG
+ case 0xAAC041554C61746ELLU: // awk_Latn_AU
+ case 0xB2C050474C61746ELLU: // awm_Latn_PG
+ case 0xB6C0455445746869LLU: // awn_Ethi_ET
+ case 0xBAC04E474C61746ELLU: // awo_Latn_NG
+ case 0xC6C049444C61746ELLU: // awr_Latn_ID
+ case 0xCAC049444C61746ELLU: // aws_Latn_ID
+ case 0xCEC042524C61746ELLU: // awt_Latn_BR
+ case 0xD2C049444C61746ELLU: // awu_Latn_ID
+ case 0xD6C049444C61746ELLU: // awv_Latn_ID
+ case 0xDAC050474C61746ELLU: // aww_Latn_PG
+ case 0xDEC050474C61746ELLU: // awx_Latn_PG
+ case 0xE2C049444C61746ELLU: // awy_Latn_ID
+ case 0x86E041524C61746ELLU: // axb_Latn_AR
+ case 0x92E041554C61746ELLU: // axe_Latn_AU
+ case 0x9AE042524C61746ELLU: // axg_Latn_BR
+ case 0xAAE043464C61746ELLU: // axk_Latn_CF
+ case 0xAEE041554C61746ELLU: // axl_Latn_AU
+ case 0xB2E0414D41726D6ELLU: // axm_Armn_AM
+ case 0xDEE04E434C61746ELLU: // axx_Latn_NC
+ case 0x6179424F4C61746ELLU: // ay_Latn_BO
+ case 0x830050474C61746ELLU: // aya_Latn_PG
+ case 0x8700424A4C61746ELLU: // ayb_Latn_BJ
+ case 0x8B0050454C61746ELLU: // ayc_Latn_PE
+ case 0x8F0041554C61746ELLU: // ayd_Latn_AU
+ case 0x93004E474C61746ELLU: // aye_Latn_NG
+ case 0x9B0054474C61746ELLU: // ayg_Latn_TG
+ case 0x9F00594541726162LLU: // ayh_Arab_YE
+ case 0xA3004E474C61746ELLU: // ayi_Latn_NG
+ case 0xAB004E474C61746ELLU: // ayk_Latn_NG
+ case 0xAF004C5941726162LLU: // ayl_Arab_LY
+ case 0xB700594541726162LLU: // ayn_Arab_YE
+ case 0xBB0050594C61746ELLU: // ayo_Latn_PY
+ case 0xBF00495141726162LLU: // ayp_Arab_IQ
+ case 0xC30050474C61746ELLU: // ayq_Latn_PG
+ case 0xCB0050484C61746ELLU: // ays_Latn_PH
+ case 0xCF0050484C61746ELLU: // ayt_Latn_PH
+ case 0xD3004E474C61746ELLU: // ayu_Latn_NG
+ case 0xE70049444C61746ELLU: // ayz_Latn_ID
+ case 0x617A495241726162LLU: // az_Arab_IR
+ case 0x617A415A4C61746ELLU: // az_Latn_AZ
+ case 0x8720495241726162LLU: // azb_Arab_IR
+ case 0x8F204D584C61746ELLU: // azd_Latn_MX
+ case 0x9B204D584C61746ELLU: // azg_Latn_MX
+ case 0xB3204D584C61746ELLU: // azm_Latn_MX
+ case 0xB7204D584C61746ELLU: // azn_Latn_MX
+ case 0xBB20434D4C61746ELLU: // azo_Latn_CM
+ case 0xCF2050484C61746ELLU: // azt_Latn_PH
+ case 0xE7204D584C61746ELLU: // azz_Latn_MX
+ case 0x626152554379726CLLU: // ba_Cyrl_RU
+ case 0x800153424C61746ELLU: // baa_Latn_SB
+ case 0x840147574C61746ELLU: // bab_Latn_GW
+ case 0x880149444C61746ELLU: // bac_Latn_ID
+ case 0x900156454C61746ELLU: // bae_Latn_VE
+ case 0x9401434D4C61746ELLU: // baf_Latn_CM
+ case 0x9801434D4C61746ELLU: // bag_Latn_CM
+ case 0x9C0142534C61746ELLU: // bah_Latn_BS
+ case 0xA40149444C61746ELLU: // baj_Latn_ID
+ case 0xAC01504B41726162LLU: // bal_Arab_PK
+ case 0xB40149444C61746ELLU: // ban_Latn_ID
+ case 0xB801434F4C61746ELLU: // bao_Latn_CO
+ case 0xBC014E5044657661LLU: // bap_Deva_NP
+ case 0xBC01494E4B726169LLU: // bap_Krai_IN
+ case 0xC40141544C61746ELLU: // bar_Latn_AT
+ case 0xC801434D4C61746ELLU: // bas_Latn_CM
+ case 0xD0014E474C61746ELLU: // bau_Latn_NG
+ case 0xD401434D4C61746ELLU: // bav_Latn_CM
+ case 0xD801434D4C61746ELLU: // baw_Latn_CM
+ case 0xDC01434D42616D75LLU: // bax_Bamu_CM
+ case 0xE00149444C61746ELLU: // bay_Latn_ID
+ case 0x8021424A4C61746ELLU: // bba_Latn_BJ
+ case 0x842150474C61746ELLU: // bbb_Latn_PG
+ case 0x882149444C61746ELLU: // bbc_Latn_ID
+ case 0x8C2150474C61746ELLU: // bbd_Latn_PG
+ case 0x902143444C61746ELLU: // bbe_Latn_CD
+ case 0x942150474C61746ELLU: // bbf_Latn_PG
+ case 0x982147414C61746ELLU: // bbg_Latn_GA
+ case 0xA021434D4C61746ELLU: // bbi_Latn_CM
+ case 0xA421434D4C61746ELLU: // bbj_Latn_CM
+ case 0xA821434D4C61746ELLU: // bbk_Latn_CM
+ case 0xAC21474547656F72LLU: // bbl_Geor_GE
+ case 0xB02143444C61746ELLU: // bbm_Latn_CD
+ case 0xB42150474C61746ELLU: // bbn_Latn_PG
+ case 0xB82142464C61746ELLU: // bbo_Latn_BF
+ case 0xBC2143464C61746ELLU: // bbp_Latn_CF
+ case 0xC021434D4C61746ELLU: // bbq_Latn_CM
+ case 0xC42150474C61746ELLU: // bbr_Latn_PG
+ case 0xC8214E474C61746ELLU: // bbs_Latn_NG
+ case 0xCC214E474C61746ELLU: // bbt_Latn_NG
+ case 0xD0214E474C61746ELLU: // bbu_Latn_NG
+ case 0xD42150474C61746ELLU: // bbv_Latn_PG
+ case 0xD821434D4C61746ELLU: // bbw_Latn_CM
+ case 0xDC21434D4C61746ELLU: // bbx_Latn_CM
+ case 0xE021434D4C61746ELLU: // bby_Latn_CM
+ case 0x8041434E4C61746ELLU: // bca_Latn_CN
+ case 0x8441534E4C61746ELLU: // bcb_Latn_SN
+ case 0x8C4149444C61746ELLU: // bcd_Latn_ID
+ case 0x9041434D4C61746ELLU: // bce_Latn_CM
+ case 0x944150474C61746ELLU: // bcf_Latn_PG
+ case 0x9841474E4C61746ELLU: // bcg_Latn_GN
+ case 0x9C4150474C61746ELLU: // bch_Latn_PG
+ case 0xA04143494C61746ELLU: // bci_Latn_CI
+ case 0xA44141554C61746ELLU: // bcj_Latn_AU
+ case 0xA84141554C61746ELLU: // bck_Latn_AU
+ case 0xB04150474C61746ELLU: // bcm_Latn_PG
+ case 0xB4414E474C61746ELLU: // bcn_Latn_NG
+ case 0xB84150474C61746ELLU: // bco_Latn_PG
+ case 0xBC4143444C61746ELLU: // bcp_Latn_CD
+ case 0xC041455445746869LLU: // bcq_Ethi_ET
+ case 0xC44143414C61746ELLU: // bcr_Latn_CA
+ case 0xC8414E474C61746ELLU: // bcs_Latn_NG
+ case 0xCC4143444C61746ELLU: // bct_Latn_CD
+ case 0xD04150474C61746ELLU: // bcu_Latn_PG
+ case 0xD4414E474C61746ELLU: // bcv_Latn_NG
+ case 0xD841434D4C61746ELLU: // bcw_Latn_CM
+ case 0xE0414E474C61746ELLU: // bcy_Latn_NG
+ case 0xE441534E4C61746ELLU: // bcz_Latn_SN
+ case 0x8061534E4C61746ELLU: // bda_Latn_SN
+ case 0x846149444C61746ELLU: // bdb_Latn_ID
+ case 0x8861434F4C61746ELLU: // bdc_Latn_CO
+ case 0x8C6150474C61746ELLU: // bdd_Latn_PG
+ case 0x90614E474C61746ELLU: // bde_Latn_NG
+ case 0x946150474C61746ELLU: // bdf_Latn_PG
+ case 0x98614D594C61746ELLU: // bdg_Latn_MY
+ case 0x9C6153534C61746ELLU: // bdh_Latn_SS
+ case 0xA06153444C61746ELLU: // bdi_Latn_SD
+ case 0xA46153534C61746ELLU: // bdj_Latn_SS
+ case 0xA861415A4C61746ELLU: // bdk_Latn_AZ
+ case 0xAC6149444C61746ELLU: // bdl_Latn_ID
+ case 0xB06154444C61746ELLU: // bdm_Latn_TD
+ case 0xB461434D4C61746ELLU: // bdn_Latn_CM
+ case 0xB86154444C61746ELLU: // bdo_Latn_TD
+ case 0xBC61545A4C61746ELLU: // bdp_Latn_TZ
+ case 0xC061564E4C61746ELLU: // bdq_Latn_VN
+ case 0xC4614D594C61746ELLU: // bdr_Latn_MY
+ case 0xC861545A4C61746ELLU: // bds_Latn_TZ
+ case 0xCC6143464C61746ELLU: // bdt_Latn_CF
+ case 0xD061434D4C61746ELLU: // bdu_Latn_CM
+ case 0xD461494E4F727961LLU: // bdv_Orya_IN
+ case 0xD86149444C61746ELLU: // bdw_Latn_ID
+ case 0xDC6149444C61746ELLU: // bdx_Latn_ID
+ case 0xE06141554C61746ELLU: // bdy_Latn_AU
+ case 0xE461504B41726162LLU: // bdz_Arab_PK
+ case 0x626542594379726CLLU: // be_Cyrl_BY
+ case 0x808143414C61746ELLU: // bea_Latn_CA
+ case 0x8481434D4C61746ELLU: // beb_Latn_CM
+ case 0x8881434D4C61746ELLU: // bec_Latn_CM
+ case 0x8C8149444C61746ELLU: // bed_Latn_ID
+ case 0x9081494E44657661LLU: // bee_Deva_IN
+ case 0x948150474C61746ELLU: // bef_Latn_PG
+ case 0x9C81424A4C61746ELLU: // beh_Latn_BJ
+ case 0xA08149444C61746ELLU: // bei_Latn_ID
+ case 0xA481534441726162LLU: // bej_Arab_SD
+ case 0xA88150474C61746ELLU: // bek_Latn_PG
+ case 0xB0815A4D4C61746ELLU: // bem_Latn_ZM
+ case 0xB88150474C61746ELLU: // beo_Latn_PG
+ case 0xBC8149444C61746ELLU: // bep_Latn_ID
+ case 0xC08143474C61746ELLU: // beq_Latn_CG
+ case 0xC88154444C61746ELLU: // bes_Latn_TD
+ case 0xCC8143494C61746ELLU: // bet_Latn_CI
+ case 0xD08149444C61746ELLU: // beu_Latn_ID
+ case 0xD48143494C61746ELLU: // bev_Latn_CI
+ case 0xD88149444C61746ELLU: // bew_Latn_ID
+ case 0xDC8153534C61746ELLU: // bex_Latn_SS
+ case 0xE08150474C61746ELLU: // bey_Latn_PG
+ case 0xE481545A4C61746ELLU: // bez_Latn_TZ
+ case 0x80A153534C61746ELLU: // bfa_Latn_SS
+ case 0x84A1494E44657661LLU: // bfb_Deva_IN
+ case 0x88A1434E4C61746ELLU: // bfc_Latn_CN
+ case 0x8CA1434D4C61746ELLU: // bfd_Latn_CM
+ case 0x90A149444C61746ELLU: // bfe_Latn_ID
+ case 0x94A143464C61746ELLU: // bff_Latn_CF
+ case 0x98A149444C61746ELLU: // bfg_Latn_ID
+ case 0x9CA150474C61746ELLU: // bfh_Latn_PG
+ case 0xA4A1434D4C61746ELLU: // bfj_Latn_CM
+ case 0xACA143464C61746ELLU: // bfl_Latn_CF
+ case 0xB0A1434D4C61746ELLU: // bfm_Latn_CM
+ case 0xB4A1544C4C61746ELLU: // bfn_Latn_TL
+ case 0xB8A142464C61746ELLU: // bfo_Latn_BF
+ case 0xBCA1434D4C61746ELLU: // bfp_Latn_CM
+ case 0xC0A1494E54616D6CLLU: // bfq_Taml_IN
+ case 0xC8A1434E4C61746ELLU: // bfs_Latn_CN
+ case 0xCCA1504B41726162LLU: // bft_Arab_PK
+ case 0xD0A1494E54696274LLU: // bfu_Tibt_IN
+ case 0xD8A1494E4F727961LLU: // bfw_Orya_IN
+ case 0xDCA150484C61746ELLU: // bfx_Latn_PH
+ case 0xE0A1494E44657661LLU: // bfy_Deva_IN
+ case 0xE4A1494E44657661LLU: // bfz_Deva_IN
+ case 0x626742474379726CLLU: // bg_Cyrl_BG
+ case 0x80C14E474C61746ELLU: // bga_Latn_NG
+ case 0x84C149444C61746ELLU: // bgb_Latn_ID
+ case 0x88C1494E44657661LLU: // bgc_Deva_IN
+ case 0x8CC1494E44657661LLU: // bgd_Deva_IN
+ case 0x94C1434D4C61746ELLU: // bgf_Latn_CM
+ case 0x98C1494E4C61746ELLU: // bgg_Latn_IN
+ case 0xA0C150484C61746ELLU: // bgi_Latn_PH
+ case 0xA4C1434D4C61746ELLU: // bgj_Latn_CM
+ case 0xB4C1504B41726162LLU: // bgn_Arab_PK
+ case 0xB8C1474E4C61746ELLU: // bgo_Latn_GN
+ case 0xBCC1504B41726162LLU: // bgp_Arab_PK
+ case 0xC0C1494E44657661LLU: // bgq_Deva_IN
+ case 0xC4C1494E4C61746ELLU: // bgr_Latn_IN
+ case 0xC8C150484C61746ELLU: // bgs_Latn_PH
+ case 0xCCC153424C61746ELLU: // bgt_Latn_SB
+ case 0xD0C14E474C61746ELLU: // bgu_Latn_NG
+ case 0xD4C149444C61746ELLU: // bgv_Latn_ID
+ case 0xD8C1494E44657661LLU: // bgw_Deva_IN
+ case 0xDCC154524772656BLLU: // bgx_Grek_TR
+ case 0xE0C149444C61746ELLU: // bgy_Latn_ID
+ case 0xE4C149444C61746ELLU: // bgz_Latn_ID
+ case 0x80E1494E44657661LLU: // bha_Deva_IN
+ case 0x84E1494E44657661LLU: // bhb_Deva_IN
+ case 0x88E149444C61746ELLU: // bhc_Latn_ID
+ case 0x8CE1494E44657661LLU: // bhd_Deva_IN
+ case 0x90E1504B41726162LLU: // bhe_Arab_PK
+ case 0x94E150474C61746ELLU: // bhf_Latn_PG
+ case 0x98E150474C61746ELLU: // bhg_Latn_PG
+ case 0x9CE1494C4379726CLLU: // bhh_Cyrl_IL
+ case 0xA0E1494E44657661LLU: // bhi_Deva_IN
+ case 0xA4E14E5044657661LLU: // bhj_Deva_NP
+ case 0xACE150474C61746ELLU: // bhl_Latn_PG
+ case 0xB0E14F4D41726162LLU: // bhm_Arab_OM
+ case 0xB4E1474553797263LLU: // bhn_Syrc_GE
+ case 0xB8E1494E44657661LLU: // bho_Deva_IN
+ case 0xBCE149444C61746ELLU: // bhp_Latn_ID
+ case 0xC0E149444C61746ELLU: // bhq_Latn_ID
+ case 0xC4E14D474C61746ELLU: // bhr_Latn_MG
+ case 0xC8E1434D4C61746ELLU: // bhs_Latn_CM
+ case 0xCCE1494E44657661LLU: // bht_Deva_IN
+ case 0xD0E1494E44657661LLU: // bhu_Deva_IN
+ case 0xD4E149444C61746ELLU: // bhv_Latn_ID
+ case 0xD8E149444C61746ELLU: // bhw_Latn_ID
+ case 0xE0E143444C61746ELLU: // bhy_Latn_CD
+ case 0xE4E149444C61746ELLU: // bhz_Latn_ID
+ case 0x626956554C61746ELLU: // bi_Latn_VU
+ case 0x810141554C61746ELLU: // bia_Latn_AU
+ case 0x850142464C61746ELLU: // bib_Latn_BF
+ case 0x8D0154444C61746ELLU: // bid_Latn_TD
+ case 0x910150474C61746ELLU: // bie_Latn_PG
+ case 0x950147574C61746ELLU: // bif_Latn_GW
+ case 0x990150474C61746ELLU: // big_Latn_PG
+ case 0xA90150484C61746ELLU: // bik_Latn_PH
+ case 0xAD014E474C61746ELLU: // bil_Latn_NG
+ case 0xB10147484C61746ELLU: // bim_Latn_GH
+ case 0xB5014E474C61746ELLU: // bin_Latn_NG
+ case 0xB90150474C61746ELLU: // bio_Latn_PG
+ case 0xBD0143444C61746ELLU: // bip_Latn_CD
+ case 0xC10150474C61746ELLU: // biq_Latn_PG
+ case 0xC50150474C61746ELLU: // bir_Latn_PG
+ case 0xCD0150474C61746ELLU: // bit_Latn_PG
+ case 0xD101494E4C61746ELLU: // biu_Latn_IN
+ case 0xD50147484C61746ELLU: // biv_Latn_GH
+ case 0xD901434D4C61746ELLU: // biw_Latn_CM
+ case 0xE101494E44657661LLU: // biy_Deva_IN
+ case 0xE50143444C61746ELLU: // biz_Latn_CD
+ case 0x812143444C61746ELLU: // bja_Latn_CD
+ case 0x852141554C61746ELLU: // bjb_Latn_AU
+ case 0x892150474C61746ELLU: // bjc_Latn_PG
+ case 0x9521494C53797263LLU: // bjf_Syrc_IL
+ case 0x992147574C61746ELLU: // bjg_Latn_GW
+ case 0x9D2150474C61746ELLU: // bjh_Latn_PG
+ case 0xA12145544C61746ELLU: // bji_Latn_ET
+ case 0xA521494E44657661LLU: // bjj_Deva_IN
+ case 0xA92150474C61746ELLU: // bjk_Latn_PG
+ case 0xAD2150474C61746ELLU: // bjl_Latn_PG
+ case 0xB121495141726162LLU: // bjm_Arab_IQ
+ case 0xB52149444C61746ELLU: // bjn_Latn_ID
+ case 0xB92143464C61746ELLU: // bjo_Latn_CF
+ case 0xBD2150474C61746ELLU: // bjp_Latn_PG
+ case 0xC52150474C61746ELLU: // bjr_Latn_PG
+ case 0xC92142424C61746ELLU: // bjs_Latn_BB
+ case 0xCD21534E4C61746ELLU: // bjt_Latn_SN
+ case 0xD121434D4C61746ELLU: // bju_Latn_CM
+ case 0xD52154444C61746ELLU: // bjv_Latn_TD
+ case 0xD92143494C61746ELLU: // bjw_Latn_CI
+ case 0xDD2150484C61746ELLU: // bjx_Latn_PH
+ case 0xE12141554C61746ELLU: // bjy_Latn_AU
+ case 0xE52150474C61746ELLU: // bjz_Latn_PG
+ case 0x81414E474C61746ELLU: // bka_Latn_NG
+ case 0x8941434D4C61746ELLU: // bkc_Latn_CM
+ case 0x8D4150484C61746ELLU: // bkd_Latn_PH
+ case 0x954143444C61746ELLU: // bkf_Latn_CD
+ case 0x994143464C61746ELLU: // bkg_Latn_CF
+ case 0x9D41434D4C61746ELLU: // bkh_Latn_CM
+ case 0xA14156554C61746ELLU: // bki_Latn_VU
+ case 0xA54143464C61746ELLU: // bkj_Latn_CF
+ case 0xA941494E54696274LLU: // bkk_Tibt_IN
+ case 0xAD4149444C61746ELLU: // bkl_Latn_ID
+ case 0xB141434D4C61746ELLU: // bkm_Latn_CM
+ case 0xB54149444C61746ELLU: // bkn_Latn_ID
+ case 0xB941434D4C61746ELLU: // bko_Latn_CM
+ case 0xBD4143444C61746ELLU: // bkp_Latn_CD
+ case 0xC14142524C61746ELLU: // bkq_Latn_BR
+ case 0xC54149444C61746ELLU: // bkr_Latn_ID
+ case 0xC94150484C61746ELLU: // bks_Latn_PH
+ case 0xCD4143444C61746ELLU: // bkt_Latn_CD
+ case 0xD14150484C61746ELLU: // bku_Latn_PH
+ case 0xD5414E474C61746ELLU: // bkv_Latn_NG
+ case 0xD94143474C61746ELLU: // bkw_Latn_CG
+ case 0xDD41544C4C61746ELLU: // bkx_Latn_TL
+ case 0xE1414E474C61746ELLU: // bky_Latn_NG
+ case 0xE54149444C61746ELLU: // bkz_Latn_ID
+ case 0x816143414C61746ELLU: // bla_Latn_CA
+ case 0x856153424C61746ELLU: // blb_Latn_SB
+ case 0x896143414C61746ELLU: // blc_Latn_CA
+ case 0x8D6149444C61746ELLU: // bld_Latn_ID
+ case 0x916147574C61746ELLU: // ble_Latn_GW
+ case 0x956149444C61746ELLU: // blf_Latn_ID
+ case 0x9D614C524C61746ELLU: // blh_Latn_LR
+ case 0xA16143444C61746ELLU: // bli_Latn_CD
+ case 0xA56149444C61746ELLU: // blj_Latn_ID
+ case 0xA9614D4D4D796D72LLU: // blk_Mymr_MM
+ case 0xB16153534C61746ELLU: // blm_Latn_SS
+ case 0xB56150484C61746ELLU: // bln_Latn_PH
+ case 0xB961424A4C61746ELLU: // blo_Latn_BJ
+ case 0xBD6153424C61746ELLU: // blp_Latn_SB
+ case 0xC16150474C61746ELLU: // blq_Latn_PG
+ case 0xC561434E4C61746ELLU: // blr_Latn_CN
+ case 0xC96149444C61746ELLU: // bls_Latn_ID
+ case 0xCD61564E54617674LLU: // blt_Tavt_VN
+ case 0xD561414F4C61746ELLU: // blv_Latn_AO
+ case 0xD96150484C61746ELLU: // blw_Latn_PH
+ case 0xDD6150484C61746ELLU: // blx_Latn_PH
+ case 0xE161424A4C61746ELLU: // bly_Latn_BJ
+ case 0xE56149444C61746ELLU: // blz_Latn_ID
+ case 0x626D4D4C4C61746ELLU: // bm_Latn_ML
+ case 0x81814E474C61746ELLU: // bma_Latn_NG
+ case 0x858143444C61746ELLU: // bmb_Latn_CD
+ case 0x898150474C61746ELLU: // bmc_Latn_PG
+ case 0x8D81474E4C61746ELLU: // bmd_Latn_GN
+ case 0x918143464C61746ELLU: // bme_Latn_CF
+ case 0x9581534C4C61746ELLU: // bmf_Latn_SL
+ case 0x998143444C61746ELLU: // bmg_Latn_CD
+ case 0x9D8150474C61746ELLU: // bmh_Latn_PG
+ case 0xA18154444C61746ELLU: // bmi_Latn_TD
+ case 0xA5814E5044657661LLU: // bmj_Deva_NP
+ case 0xA98150474C61746ELLU: // bmk_Latn_PG
+ case 0xAD8143444C61746ELLU: // bml_Latn_CD
+ case 0xB1814D474C61746ELLU: // bmm_Latn_MG
+ case 0xB58150474C61746ELLU: // bmn_Latn_PG
+ case 0xB981434D4C61746ELLU: // bmo_Latn_CM
+ case 0xBD8150474C61746ELLU: // bmp_Latn_PG
+ case 0xC1814D4C4C61746ELLU: // bmq_Latn_ML
+ case 0xC581434F4C61746ELLU: // bmr_Latn_CO
+ case 0xC9814E454C61746ELLU: // bms_Latn_NE
+ case 0xD18150474C61746ELLU: // bmu_Latn_PG
+ case 0xD581434D4C61746ELLU: // bmv_Latn_CM
+ case 0xD98143474C61746ELLU: // bmw_Latn_CG
+ case 0xDD8150474C61746ELLU: // bmx_Latn_PG
+ case 0xE58150474C61746ELLU: // bmz_Latn_PG
+ case 0x626E424442656E67LLU: // bn_Beng_BD
+ case 0x81A149444C61746ELLU: // bna_Latn_ID
+ case 0x85A14D594C61746ELLU: // bnb_Latn_MY
+ case 0x89A150484C61746ELLU: // bnc_Latn_PH
+ case 0x8DA149444C61746ELLU: // bnd_Latn_ID
+ case 0x91A149444C61746ELLU: // bne_Latn_ID
+ case 0x95A149444C61746ELLU: // bnf_Latn_ID
+ case 0x99A147514C61746ELLU: // bng_Latn_GQ
+ case 0xA1A143444C61746ELLU: // bni_Latn_CD
+ case 0xA5A150484C61746ELLU: // bnj_Latn_PH
+ case 0xA9A156554C61746ELLU: // bnk_Latn_VU
+ case 0xB1A147514C61746ELLU: // bnm_Latn_GQ
+ case 0xB5A154574C61746ELLU: // bnn_Latn_TW
+ case 0xB9A150484C61746ELLU: // bno_Latn_PH
+ case 0xBDA150474C61746ELLU: // bnp_Latn_PG
+ case 0xC1A149444C61746ELLU: // bnq_Latn_ID
+ case 0xC5A156554C61746ELLU: // bnr_Latn_VU
+ case 0xC9A1494E44657661LLU: // bns_Deva_IN
+ case 0xD1A149444C61746ELLU: // bnu_Latn_ID
+ case 0xD5A149444C61746ELLU: // bnv_Latn_ID
+ case 0xD9A150474C61746ELLU: // bnw_Latn_PG
+ case 0xDDA143444C61746ELLU: // bnx_Latn_CD
+ case 0xE1A14D594C61746ELLU: // bny_Latn_MY
+ case 0xE5A1434D4C61746ELLU: // bnz_Latn_CM
+ case 0x626F434E54696274LLU: // bo_Tibt_CN
+ case 0x81C150454C61746ELLU: // boa_Latn_PE
+ case 0x85C14B454C61746ELLU: // bob_Latn_KE
+ case 0x91C1434D4C61746ELLU: // boe_Latn_CM
+ case 0x95C142464C61746ELLU: // bof_Latn_BF
+ case 0x9DC143444C61746ELLU: // boh_Latn_CD
+ case 0xA5C150474C61746ELLU: // boj_Latn_PG
+ case 0xA9C143474C61746ELLU: // bok_Latn_CG
+ case 0xADC14E474C61746ELLU: // bol_Latn_NG
+ case 0xB1C14E474C61746ELLU: // bom_Latn_NG
+ case 0xB5C150474C61746ELLU: // bon_Latn_PG
+ case 0xB9C14D4C4C61746ELLU: // boo_Latn_ML
+ case 0xBDC150474C61746ELLU: // bop_Latn_PG
+ case 0xC1C150474C61746ELLU: // boq_Latn_PG
+ case 0xC5C142524C61746ELLU: // bor_Latn_BR
+ case 0xCDC153534C61746ELLU: // bot_Latn_SS
+ case 0xD1C1545A4C61746ELLU: // bou_Latn_TZ
+ case 0xD5C147484C61746ELLU: // bov_Latn_GH
+ case 0xD9C150474C61746ELLU: // bow_Latn_PG
+ case 0xDDC142464C61746ELLU: // box_Latn_BF
+ case 0xE1C143464C61746ELLU: // boy_Latn_CF
+ case 0xE5C14D4C4C61746ELLU: // boz_Latn_ML
+ case 0x81E156554C61746ELLU: // bpa_Latn_VU
+ case 0x89E1434D4C61746ELLU: // bpc_Latn_CM
+ case 0x8DE143464C61746ELLU: // bpd_Latn_CF
+ case 0x91E150474C61746ELLU: // bpe_Latn_PG
+ case 0x99E149444C61746ELLU: // bpg_Latn_ID
+ case 0x9DE152554379726CLLU: // bph_Cyrl_RU
+ case 0xA1E150474C61746ELLU: // bpi_Latn_PG
+ case 0xA5E143444C61746ELLU: // bpj_Latn_CD
+ case 0xA9E14E434C61746ELLU: // bpk_Latn_NC
+ case 0xADE141554C61746ELLU: // bpl_Latn_AU
+ case 0xB1E150474C61746ELLU: // bpm_Latn_PG
+ case 0xB9E149444C61746ELLU: // bpo_Latn_ID
+ case 0xBDE149444C61746ELLU: // bpp_Latn_ID
+ case 0xC1E149444C61746ELLU: // bpq_Latn_ID
+ case 0xC5E150484C61746ELLU: // bpr_Latn_PH
+ case 0xC9E150484C61746ELLU: // bps_Latn_PH
+ case 0xCDE141554C61746ELLU: // bpt_Latn_AU
+ case 0xD1E150474C61746ELLU: // bpu_Latn_PG
+ case 0xD5E149444C61746ELLU: // bpv_Latn_ID
+ case 0xD9E150474C61746ELLU: // bpw_Latn_PG
+ case 0xDDE1494E44657661LLU: // bpx_Deva_IN
+ case 0xE1E1494E42656E67LLU: // bpy_Beng_IN
+ case 0xE5E149444C61746ELLU: // bpz_Latn_ID
+ case 0x8201424A4C61746ELLU: // bqa_Latn_BJ
+ case 0x860149444C61746ELLU: // bqb_Latn_ID
+ case 0x8A01424A4C61746ELLU: // bqc_Latn_BJ
+ case 0x8E01434D4C61746ELLU: // bqd_Latn_CM
+ case 0x9601474E4C61746ELLU: // bqf_Latn_GN
+ case 0x9A0154474C61746ELLU: // bqg_Latn_TG
+ case 0xA201495241726162LLU: // bqi_Arab_IR
+ case 0xA601534E4C61746ELLU: // bqj_Latn_SN
+ case 0xAA0143464C61746ELLU: // bqk_Latn_CF
+ case 0xAE0150474C61746ELLU: // bql_Latn_PG
+ case 0xB201434D4C61746ELLU: // bqm_Latn_CM
+ case 0xBA01434D4C61746ELLU: // bqo_Latn_CM
+ case 0xBE014E474C61746ELLU: // bqp_Latn_NG
+ case 0xC20149444C61746ELLU: // bqq_Latn_ID
+ case 0xC60149444C61746ELLU: // bqr_Latn_ID
+ case 0xCA0150474C61746ELLU: // bqs_Latn_PG
+ case 0xCE01434D4C61746ELLU: // bqt_Latn_CM
+ case 0xD20143444C61746ELLU: // bqu_Latn_CD
+ case 0xD60143494C61746ELLU: // bqv_Latn_CI
+ case 0xDA014E474C61746ELLU: // bqw_Latn_NG
+ case 0xDE014E474C61746ELLU: // bqx_Latn_NG
+ case 0xE601434D4C61746ELLU: // bqz_Latn_CM
+ case 0x627246524C61746ELLU: // br_Latn_FR
+ case 0x8221494E44657661LLU: // bra_Deva_IN
+ case 0x86214B484B686D72LLU: // brb_Khmr_KH
+ case 0x8A2147594C61746ELLU: // brc_Latn_GY
+ case 0x8E214E5044657661LLU: // brd_Deva_NP
+ case 0x962143444C61746ELLU: // brf_Latn_CD
+ case 0x9A21424F4C61746ELLU: // brg_Latn_BO
+ case 0x9E21504B41726162LLU: // brh_Arab_PK
+ case 0xA221434D4C61746ELLU: // bri_Latn_CM
+ case 0xA62156554C61746ELLU: // brj_Latn_VU
+ case 0xAA21534441726162LLU: // brk_Arab_SD
+ case 0xAE2142574C61746ELLU: // brl_Latn_BW
+ case 0xB22143444C61746ELLU: // brm_Latn_CD
+ case 0xB62143524C61746ELLU: // brn_Latn_CR
+ case 0xBA21425454696274LLU: // bro_Tibt_BT
+ case 0xBE2149444C61746ELLU: // brp_Latn_ID
+ case 0xC22150474C61746ELLU: // brq_Latn_PG
+ case 0xC62153424C61746ELLU: // brr_Latn_SB
+ case 0xCA2149444C61746ELLU: // brs_Latn_ID
+ case 0xCE214E474C61746ELLU: // brt_Latn_NG
+ case 0xD221564E4C61746ELLU: // bru_Latn_VN
+ case 0xD6214C414C616F6FLLU: // brv_Laoo_LA
+ case 0xDA21494E4B6E6461LLU: // brw_Knda_IN
+ case 0xDE21494E44657661LLU: // brx_Deva_IN
+ case 0xE22150474C61746ELLU: // bry_Latn_PG
+ case 0xE62150474C61746ELLU: // brz_Latn_PG
+ case 0x627342414C61746ELLU: // bs_Latn_BA
+ case 0x824149444C61746ELLU: // bsa_Latn_ID
+ case 0x8641424E4C61746ELLU: // bsb_Latn_BN
+ case 0x8A41534E4C61746ELLU: // bsc_Latn_SN
+ case 0x9241434D4C61746ELLU: // bse_Latn_CM
+ case 0x96414E474C61746ELLU: // bsf_Latn_NG
+ case 0x9E41414641726162LLU: // bsh_Arab_AF
+ case 0xA241434D4C61746ELLU: // bsi_Latn_CM
+ case 0xA6414E474C61746ELLU: // bsj_Latn_NG
+ case 0xAA41504B41726162LLU: // bsk_Arab_PK
+ case 0xAE414E474C61746ELLU: // bsl_Latn_NG
+ case 0xB24149444C61746ELLU: // bsm_Latn_ID
+ case 0xB641434F4C61746ELLU: // bsn_Latn_CO
+ case 0xBA4154444C61746ELLU: // bso_Latn_TD
+ case 0xBE41474E4C61746ELLU: // bsp_Latn_GN
+ case 0xC2414C5242617373LLU: // bsq_Bass_LR
+ case 0xC6414E474C61746ELLU: // bsr_Latn_NG
+ case 0xCA41434D4C61746ELLU: // bss_Latn_CM
+ case 0xCE41455445746869LLU: // bst_Ethi_ET
+ case 0xD24149444C61746ELLU: // bsu_Latn_ID
+ case 0xD641474E4C61746ELLU: // bsv_Latn_GN
+ case 0xDA4145544C61746ELLU: // bsw_Latn_ET
+ case 0xDE414E474C61746ELLU: // bsx_Latn_NG
+ case 0xE2414D594C61746ELLU: // bsy_Latn_MY
+ case 0x82614E474C61746ELLU: // bta_Latn_NG
+ case 0x8A61434D4C61746ELLU: // btc_Latn_CM
+ case 0x8E6149444261746BLLU: // btd_Batk_ID
+ case 0x92614E474C61746ELLU: // bte_Latn_NG
+ case 0x966154444C61746ELLU: // btf_Latn_TD
+ case 0x9A6143494C61746ELLU: // btg_Latn_CI
+ case 0x9E614D594C61746ELLU: // bth_Latn_MY
+ case 0xA26149444C61746ELLU: // bti_Latn_ID
+ case 0xA66149444C61746ELLU: // btj_Latn_ID
+ case 0xB26149444261746BLLU: // btm_Batk_ID
+ case 0xB66150484C61746ELLU: // btn_Latn_PH
+ case 0xBA6150484C61746ELLU: // bto_Latn_PH
+ case 0xBE6150474C61746ELLU: // btp_Latn_PG
+ case 0xC2614D594C61746ELLU: // btq_Latn_MY
+ case 0xC66156554C61746ELLU: // btr_Latn_VU
+ case 0xCA6149444C61746ELLU: // bts_Latn_ID
+ case 0xCE614E474C61746ELLU: // btt_Latn_NG
+ case 0xD2614E474C61746ELLU: // btu_Latn_NG
+ case 0xD661504B44657661LLU: // btv_Deva_PK
+ case 0xDA6150484C61746ELLU: // btw_Latn_PH
+ case 0xDE6149444C61746ELLU: // btx_Latn_ID
+ case 0xE26149444C61746ELLU: // bty_Latn_ID
+ case 0xE66149444C61746ELLU: // btz_Latn_ID
+ case 0x828152554379726CLLU: // bua_Cyrl_RU
+ case 0x868154444C61746ELLU: // bub_Latn_TD
+ case 0x8A8159544C61746ELLU: // buc_Latn_YT
+ case 0x8E8154474C61746ELLU: // bud_Latn_TG
+ case 0x928143414C61746ELLU: // bue_Latn_CA
+ case 0x968143444C61746ELLU: // buf_Latn_CD
+ case 0x9A8149444C61746ELLU: // bug_Latn_ID
+ case 0x9E81434E4C61746ELLU: // buh_Latn_CN
+ case 0xA28143474C61746ELLU: // bui_Latn_CG
+ case 0xA6814E474C61746ELLU: // buj_Latn_NG
+ case 0xAA8150474C61746ELLU: // buk_Latn_PG
+ case 0xB281434D4C61746ELLU: // bum_Latn_CM
+ case 0xB681534C4C61746ELLU: // bun_Latn_SL
+ case 0xBA8150474C61746ELLU: // buo_Latn_PG
+ case 0xBE8149444C61746ELLU: // bup_Latn_ID
+ case 0xC28150474C61746ELLU: // buq_Latn_PG
+ case 0xCA814E474C61746ELLU: // bus_Latn_NG
+ case 0xCE8150474C61746ELLU: // but_Latn_PG
+ case 0xD28143444C61746ELLU: // buu_Latn_CD
+ case 0xD68150474C61746ELLU: // buv_Latn_PG
+ case 0xDA8147414C61746ELLU: // buw_Latn_GA
+ case 0xDE814E474C61746ELLU: // bux_Latn_NG
+ case 0xE281534C4C61746ELLU: // buy_Latn_SL
+ case 0xE6814E474C61746ELLU: // buz_Latn_NG
+ case 0x82A154444C61746ELLU: // bva_Latn_TD
+ case 0x86A147514C61746ELLU: // bvb_Latn_GQ
+ case 0x8AA153424C61746ELLU: // bvc_Latn_SB
+ case 0x8EA153424C61746ELLU: // bvd_Latn_SB
+ case 0x92A149444C61746ELLU: // bve_Latn_ID
+ case 0x96A154444C61746ELLU: // bvf_Latn_TD
+ case 0x9AA1434D4C61746ELLU: // bvg_Latn_CM
+ case 0x9EA14E474C61746ELLU: // bvh_Latn_NG
+ case 0xA2A153534C61746ELLU: // bvi_Latn_SS
+ case 0xA6A14E474C61746ELLU: // bvj_Latn_NG
+ case 0xAAA149444C61746ELLU: // bvk_Latn_ID
+ case 0xB2A1434D4C61746ELLU: // bvm_Latn_CM
+ case 0xB6A150474C61746ELLU: // bvn_Latn_PG
+ case 0xBAA154444C61746ELLU: // bvo_Latn_TD
+ case 0xC2A143464C61746ELLU: // bvq_Latn_CF
+ case 0xC6A141554C61746ELLU: // bvr_Latn_AU
+ case 0xCEA149444C61746ELLU: // bvt_Latn_ID
+ case 0xD2A149444C61746ELLU: // bvu_Latn_ID
+ case 0xD6A156454C61746ELLU: // bvv_Latn_VE
+ case 0xDAA14E474C61746ELLU: // bvw_Latn_NG
+ case 0xDEA143474C61746ELLU: // bvx_Latn_CG
+ case 0xE2A150484C61746ELLU: // bvy_Latn_PH
+ case 0xE6A149444C61746ELLU: // bvz_Latn_ID
+ case 0x82C14E434C61746ELLU: // bwa_Latn_NC
+ case 0x86C1464A4C61746ELLU: // bwb_Latn_FJ
+ case 0x8AC15A4D4C61746ELLU: // bwc_Latn_ZM
+ case 0x8EC150474C61746ELLU: // bwd_Latn_PG
+ case 0x92C14D4D4D796D72LLU: // bwe_Mymr_MM
+ case 0x96C150474C61746ELLU: // bwf_Latn_PG
+ case 0x9AC14D5A4C61746ELLU: // bwg_Latn_MZ
+ case 0x9EC1434D4C61746ELLU: // bwh_Latn_CM
+ case 0xA2C156454C61746ELLU: // bwi_Latn_VE
+ case 0xA6C142464C61746ELLU: // bwj_Latn_BF
+ case 0xAAC150474C61746ELLU: // bwk_Latn_PG
+ case 0xAEC143444C61746ELLU: // bwl_Latn_CD
+ case 0xB2C150474C61746ELLU: // bwm_Latn_PG
+ case 0xBAC145544C61746ELLU: // bwo_Latn_ET
+ case 0xBEC149444C61746ELLU: // bwp_Latn_ID
+ case 0xC2C142464C61746ELLU: // bwq_Latn_BF
+ case 0xC6C14E474C61746ELLU: // bwr_Latn_NG
+ case 0xCAC143444C61746ELLU: // bws_Latn_CD
+ case 0xCEC1434D4C61746ELLU: // bwt_Latn_CM
+ case 0xD2C147484C61746ELLU: // bwu_Latn_GH
+ case 0xDAC143444C61746ELLU: // bww_Latn_CD
+ case 0xDEC1434E4C61746ELLU: // bwx_Latn_CN
+ case 0xE2C142464C61746ELLU: // bwy_Latn_BF
+ case 0xE6C143474C61746ELLU: // bwz_Latn_CG
+ case 0x82E153424C61746ELLU: // bxa_Latn_SB
+ case 0x86E153534C61746ELLU: // bxb_Latn_SS
+ case 0x8AE147514C61746ELLU: // bxc_Latn_GQ
+ case 0x96E150474C61746ELLU: // bxf_Latn_PG
+ case 0x9AE143444C61746ELLU: // bxg_Latn_CD
+ case 0x9EE150474C61746ELLU: // bxh_Latn_PG
+ case 0xA2E141554C61746ELLU: // bxi_Latn_AU
+ case 0xA6E141554C61746ELLU: // bxj_Latn_AU
+ case 0xAEE142464C61746ELLU: // bxl_Latn_BF
+ case 0xB2E14D4E4379726CLLU: // bxm_Cyrl_MN
+ case 0xB6E141554C61746ELLU: // bxn_Latn_AU
+ case 0xBAE14E474C61746ELLU: // bxo_Latn_NG
+ case 0xBEE1434D4C61746ELLU: // bxp_Latn_CM
+ case 0xC2E14E474C61746ELLU: // bxq_Latn_NG
+ case 0xCAE1434D4C61746ELLU: // bxs_Latn_CM
+ case 0xD2E1434E4D6F6E67LLU: // bxu_Mong_CN
+ case 0xD6E154444C61746ELLU: // bxv_Latn_TD
+ case 0xDAE14D4C4C61746ELLU: // bxw_Latn_ML
+ case 0xE6E150474C61746ELLU: // bxz_Latn_PG
+ case 0x830150484C61746ELLU: // bya_Latn_PH
+ case 0x8701434D4C61746ELLU: // byb_Latn_CM
+ case 0x8B014E474C61746ELLU: // byc_Latn_NG
+ case 0x8F0149444C61746ELLU: // byd_Latn_ID
+ case 0x930150474C61746ELLU: // bye_Latn_PG
+ case 0x97014E474C61746ELLU: // byf_Latn_NG
+ case 0x9F014E5044657661LLU: // byh_Deva_NP
+ case 0xA30143444C61746ELLU: // byi_Latn_CD
+ case 0xA7014E474C61746ELLU: // byj_Latn_NG
+ case 0xAB01434E4C61746ELLU: // byk_Latn_CN
+ case 0xAF0149444C61746ELLU: // byl_Latn_ID
+ case 0xB30141554C61746ELLU: // bym_Latn_AU
+ case 0xB701455245746869LLU: // byn_Ethi_ER
+ case 0xBF014E474C61746ELLU: // byp_Latn_NG
+ case 0xC70150474C61746ELLU: // byr_Latn_PG
+ case 0xCB014E474C61746ELLU: // bys_Latn_NG
+ case 0xD701434D4C61746ELLU: // byv_Latn_CM
+ case 0xDB014E5044657661LLU: // byw_Deva_NP
+ case 0xDF0150474C61746ELLU: // byx_Latn_PG
+ case 0xE70150474C61746ELLU: // byz_Latn_PG
+ case 0x83214C524C61746ELLU: // bza_Latn_LR
+ case 0x872149444C61746ELLU: // bzb_Latn_ID
+ case 0x8B214D474C61746ELLU: // bzc_Latn_MG
+ case 0x8F2143524C61746ELLU: // bzd_Latn_CR
+ case 0x93214D4C4C61746ELLU: // bze_Latn_ML
+ case 0x972150474C61746ELLU: // bzf_Latn_PG
+ case 0x9F2150474C61746ELLU: // bzh_Latn_PG
+ case 0xA321544854686169LLU: // bzi_Thai_TH
+ case 0xA721425A4C61746ELLU: // bzj_Latn_BZ
+ case 0xAB214E494C61746ELLU: // bzk_Latn_NI
+ case 0xAF2149444C61746ELLU: // bzl_Latn_ID
+ case 0xB32143444C61746ELLU: // bzm_Latn_CD
+ case 0xB72149444C61746ELLU: // bzn_Latn_ID
+ case 0xBB2143444C61746ELLU: // bzo_Latn_CD
+ case 0xBF2149444C61746ELLU: // bzp_Latn_ID
+ case 0xC32149444C61746ELLU: // bzq_Latn_ID
+ case 0xC72141554C61746ELLU: // bzr_Latn_AU
+ case 0xD32149444C61746ELLU: // bzu_Latn_ID
+ case 0xD721434D4C61746ELLU: // bzv_Latn_CM
+ case 0xDB214E474C61746ELLU: // bzw_Latn_NG
+ case 0xDF214D4C4C61746ELLU: // bzx_Latn_ML
+ case 0xE3214E474C61746ELLU: // bzy_Latn_NG
+ case 0xE7214E474C61746ELLU: // bzz_Latn_NG
+ case 0x636145534C61746ELLU: // ca_Latn_ES
+ case 0x800247544C61746ELLU: // caa_Latn_GT
+ case 0x8402484E4C61746ELLU: // cab_Latn_HN
+ case 0x880247544C61746ELLU: // cac_Latn_GT
+ case 0x8C0255534C61746ELLU: // cad_Latn_US
+ case 0x9002534E4C61746ELLU: // cae_Latn_SN
+ case 0x940243414C61746ELLU: // caf_Latn_CA
+ case 0x980250594C61746ELLU: // cag_Latn_PY
+ case 0x9C0250454C61746ELLU: // cah_Latn_PE
+ case 0xA402424F4C61746ELLU: // caj_Latn_BO
+ case 0xA80247544C61746ELLU: // cak_Latn_GT
+ case 0xAC024D504C61746ELLU: // cal_Latn_MP
+ case 0xB0024E434C61746ELLU: // cam_Latn_NC
+ case 0xB40250474C61746ELLU: // can_Latn_PG
+ case 0xB802424F4C61746ELLU: // cao_Latn_BO
+ case 0xBC02424F4C61746ELLU: // cap_Latn_BO
+ case 0xC002494E4C61746ELLU: // caq_Latn_IN
+ case 0xC40256454C61746ELLU: // car_Latn_VE
+ case 0xC802424F4C61746ELLU: // cas_Latn_BO
+ case 0xD402424F4C61746ELLU: // cav_Latn_BO
+ case 0xD802424F4C61746ELLU: // caw_Latn_BO
+ case 0xDC02424F4C61746ELLU: // cax_Latn_BO
+ case 0xE00243414C61746ELLU: // cay_Latn_CA
+ case 0xE402424F4C61746ELLU: // caz_Latn_BO
+ case 0x8422434F4C61746ELLU: // cbb_Latn_CO
+ case 0x8822434F4C61746ELLU: // cbc_Latn_CO
+ case 0x8C22434F4C61746ELLU: // cbd_Latn_CO
+ case 0x9822434F4C61746ELLU: // cbg_Latn_CO
+ case 0xA02245434C61746ELLU: // cbi_Latn_EC
+ case 0xA422424A4C61746ELLU: // cbj_Latn_BJ
+ case 0xA82250484C61746ELLU: // cbk_Latn_PH
+ case 0xAC224D4D4C61746ELLU: // cbl_Latn_MM
+ case 0xB422544854686169LLU: // cbn_Thai_TH
+ case 0xB8224E474C61746ELLU: // cbo_Latn_NG
+ case 0xC0224E474C61746ELLU: // cbq_Latn_NG
+ case 0xC42250454C61746ELLU: // cbr_Latn_PE
+ case 0xC82250454C61746ELLU: // cbs_Latn_PE
+ case 0xCC2250454C61746ELLU: // cbt_Latn_PE
+ case 0xD02250454C61746ELLU: // cbu_Latn_PE
+ case 0xD422434F4C61746ELLU: // cbv_Latn_CO
+ case 0xD82250484C61746ELLU: // cbw_Latn_PH
+ case 0xE022434F4C61746ELLU: // cby_Latn_CO
+ case 0x884250454C61746ELLU: // ccc_Latn_PE
+ case 0x8C4242524C61746ELLU: // ccd_Latn_BR
+ case 0x90424D5A4C61746ELLU: // cce_Latn_MZ
+ case 0x98424E474C61746ELLU: // ccg_Latn_NG
+ case 0x9C424E474C61746ELLU: // cch_Latn_NG
+ case 0xA44247574C61746ELLU: // ccj_Latn_GW
+ case 0xAC42545A4C61746ELLU: // ccl_Latn_TZ
+ case 0xB0424D594C61746ELLU: // ccm_Latn_MY
+ case 0xB8424D584C61746ELLU: // cco_Latn_MX
+ case 0xBC42424443616B6DLLU: // ccp_Cakm_BD
+ case 0xC44253564C61746ELLU: // ccr_Latn_SV
+ case 0x9062494E54656C75LLU: // cde_Telu_IN
+ case 0x9462494E4C61746ELLU: // cdf_Latn_IN
+ case 0x9C62494E44657661LLU: // cdh_Deva_IN
+ case 0xA062494E47756A72LLU: // cdi_Gujr_IN
+ case 0xA462494E44657661LLU: // cdj_Deva_IN
+ case 0xB0624E5044657661LLU: // cdm_Deva_NP
+ case 0xB862434E48616E73LLU: // cdo_Hans_CN
+ case 0xC4624E474C61746ELLU: // cdr_Latn_NG
+ case 0xE462494E42656E67LLU: // cdz_Beng_IN
+ case 0x636552554379726CLLU: // ce_Cyrl_RU
+ case 0x808255534C61746ELLU: // cea_Latn_US
+ case 0x848250484C61746ELLU: // ceb_Latn_PH
+ case 0x988250594C61746ELLU: // ceg_Latn_PY
+ case 0xA8824D4D4C61746ELLU: // cek_Latn_MM
+ case 0xB4824E474C61746ELLU: // cen_Latn_NG
+ case 0xCC824E474C61746ELLU: // cet_Latn_NG
+ case 0xE0824D4D4C61746ELLU: // cey_Latn_MM
+ case 0x80A24E474C61746ELLU: // cfa_Latn_NG
+ case 0x8CA24E474C61746ELLU: // cfd_Latn_NG
+ case 0x98A24E474C61746ELLU: // cfg_Latn_NG
+ case 0xB0A24D4D4C61746ELLU: // cfm_Latn_MM
+ case 0x80C250474C61746ELLU: // cga_Latn_PG
+ case 0x88C250484C61746ELLU: // cgc_Latn_PH
+ case 0x98C255474C61746ELLU: // cgg_Latn_UG
+ case 0xA8C2425454696274LLU: // cgk_Tibt_BT
+ case 0x636847554C61746ELLU: // ch_Latn_GU
+ case 0x84E2434F4C61746ELLU: // chb_Latn_CO
+ case 0x8CE24D584C61746ELLU: // chd_Latn_MX
+ case 0x94E24D584C61746ELLU: // chf_Latn_MX
+ case 0x98E2544D41726162LLU: // chg_Arab_TM
+ case 0x9CE255534C61746ELLU: // chh_Latn_US
+ case 0xA4E24D584C61746ELLU: // chj_Latn_MX
+ case 0xA8E2464D4C61746ELLU: // chk_Latn_FM
+ case 0xACE255534C61746ELLU: // chl_Latn_US
+ case 0xB0E252554379726CLLU: // chm_Cyrl_RU
+ case 0xB4E255534C61746ELLU: // chn_Latn_US
+ case 0xB8E255534C61746ELLU: // cho_Latn_US
+ case 0xBCE243414C61746ELLU: // chp_Latn_CA
+ case 0xC0E24D584C61746ELLU: // chq_Latn_MX
+ case 0xC4E2555343686572LLU: // chr_Cher_US
+ case 0xCCE250454C61746ELLU: // cht_Latn_PE
+ case 0xD8E24D5A4C61746ELLU: // chw_Latn_MZ
+ case 0xDCE24E5044657661LLU: // chx_Deva_NP
+ case 0xE0E255534C61746ELLU: // chy_Latn_US
+ case 0xE4E24D584C61746ELLU: // chz_Latn_MX
+ case 0x810249444C61746ELLU: // cia_Latn_ID
+ case 0x8502424A4C61746ELLU: // cib_Latn_BJ
+ case 0x890255534C61746ELLU: // cic_Latn_US
+ case 0x91024E474C61746ELLU: // cie_Latn_NG
+ case 0x9D02494E44657661LLU: // cih_Deva_IN
+ case 0xB10249544C61746ELLU: // cim_Latn_IT
+ case 0xB50242524C61746ELLU: // cin_Latn_BR
+ case 0xBD024D584C61746ELLU: // cip_Latn_MX
+ case 0xC5024E434C61746ELLU: // cir_Latn_NC
+ case 0xD90255534C61746ELLU: // ciw_Latn_US
+ case 0xE10256454C61746ELLU: // ciy_Latn_VE
+ case 0x81224B4841726162LLU: // cja_Arab_KH
+ case 0x9122564E4C61746ELLU: // cje_Latn_VN
+ case 0x9D2255534C61746ELLU: // cjh_Latn_US
+ case 0xA12252554379726CLLU: // cji_Cyrl_RU
+ case 0xA922414F4C61746ELLU: // cjk_Latn_AO
+ case 0xB122564E4368616DLLU: // cjm_Cham_VN
+ case 0xB52250474C61746ELLU: // cjn_Latn_PG
+ case 0xB92250454C61746ELLU: // cjo_Latn_PE
+ case 0xBD2243524C61746ELLU: // cjp_Latn_CR
+ case 0xC92252554C61746ELLU: // cjs_Latn_RU
+ case 0xD52250474C61746ELLU: // cjv_Latn_PG
+ case 0xE122434E48616E73LLU: // cjy_Hans_CN
+ case 0x8542495141726162LLU: // ckb_Arab_IQ
+ case 0xAD424E474C61746ELLU: // ckl_Latn_NG
+ case 0xB14248524C61746ELLU: // ckm_Latn_HR
+ case 0xB5424D4D4C61746ELLU: // ckn_Latn_MM
+ case 0xB94247484C61746ELLU: // cko_Latn_GH
+ case 0xC14254444C61746ELLU: // ckq_Latn_TD
+ case 0xC54250474C61746ELLU: // ckr_Latn_PG
+ case 0xC9424E434C61746ELLU: // cks_Latn_NC
+ case 0xCD4252554379726CLLU: // ckt_Cyrl_RU
+ case 0xD14255534C61746ELLU: // cku_Latn_US
+ case 0xD54254574C61746ELLU: // ckv_Latn_TW
+ case 0xDD42434D4C61746ELLU: // ckx_Latn_CM
+ case 0xE1424E474C61746ELLU: // cky_Latn_NG
+ case 0xE54247544C61746ELLU: // ckz_Latn_GT
+ case 0x81624E474C61746ELLU: // cla_Latn_NG
+ case 0x896243414C61746ELLU: // clc_Latn_CA
+ case 0x91624D584C61746ELLU: // cle_Latn_MX
+ case 0x9D62504B41726162LLU: // clh_Arab_PK
+ case 0xA16247484C61746ELLU: // cli_Latn_GH
+ case 0xA5624D4D4C61746ELLU: // clj_Latn_MM
+ case 0xA962494E4C61746ELLU: // clk_Latn_IN
+ case 0xAD6247484C61746ELLU: // cll_Latn_GH
+ case 0xB16255534C61746ELLU: // clm_Latn_US
+ case 0xB9624D584C61746ELLU: // clo_Latn_MX
+ case 0xCD624D4D4C61746ELLU: // clt_Latn_MM
+ case 0xD16250484C61746ELLU: // clu_Latn_PH
+ case 0xD96252554379726CLLU: // clw_Cyrl_RU
+ case 0xE1624D584C61746ELLU: // cly_Latn_MX
+ case 0x8182564E4C61746ELLU: // cma_Latn_VN
+ case 0x918242464C61746ELLU: // cme_Latn_BF
+ case 0x99824D4E536F796FLLU: // cmg_Soyo_MN
+ case 0xA182434F4C61746ELLU: // cmi_Latn_CO
+ case 0xAD8249444C61746ELLU: // cml_Latn_ID
+ case 0xB982564E4C61746ELLU: // cmo_Latn_VN
+ case 0xC5824D4D4C61746ELLU: // cmr_Latn_MM
+ case 0xC98249544C61746ELLU: // cms_Latn_IT
+ case 0xCD825A414C61746ELLU: // cmt_Latn_ZA
+ case 0x81A2494E54696274LLU: // cna_Tibt_IN
+ case 0x85A24D4D4C61746ELLU: // cnb_Latn_MM
+ case 0x89A2564E4C61746ELLU: // cnc_Latn_VN
+ case 0x99A2434E4C61746ELLU: // cng_Latn_CN
+ case 0x9DA24D4D4C61746ELLU: // cnh_Latn_MM
+ case 0xA1A250454C61746ELLU: // cni_Latn_PE
+ case 0xA9A24D4D4C61746ELLU: // cnk_Latn_MM
+ case 0xADA24D584C61746ELLU: // cnl_Latn_MX
+ case 0xBDA2434E48616E73LLU: // cnp_Hans_CN
+ case 0xC1A2434D4C61746ELLU: // cnq_Latn_CM
+ case 0xC9A249444C61746ELLU: // cns_Latn_ID
+ case 0xCDA24D584C61746ELLU: // cnt_Latn_MX
+ case 0xD9A24D4D4C61746ELLU: // cnw_Latn_MM
+ case 0xDDA247424C61746ELLU: // cnx_Latn_GB
+ case 0x636F46524C61746ELLU: // co_Latn_FR
+ case 0x81C241554C61746ELLU: // coa_Latn_AU
+ case 0x85C24D584C61746ELLU: // cob_Latn_MX
+ case 0x89C24D584C61746ELLU: // coc_Latn_MX
+ case 0x8DC250454C61746ELLU: // cod_Latn_PE
+ case 0x91C2434F4C61746ELLU: // coe_Latn_CO
+ case 0x95C245434C61746ELLU: // cof_Latn_EC
+ case 0x99C2544854686169LLU: // cog_Thai_TH
+ case 0x9DC24B454C61746ELLU: // coh_Latn_KE
+ case 0xA5C24D584C61746ELLU: // coj_Latn_MX
+ case 0xA9C24D584C61746ELLU: // cok_Latn_MX
+ case 0xADC255534C61746ELLU: // col_Latn_US
+ case 0xB1C255534C61746ELLU: // com_Latn_US
+ case 0xB9C243414C61746ELLU: // coo_Latn_CA
+ case 0xBDC24547436F7074LLU: // cop_Copt_EG
+ case 0xC1C255534C61746ELLU: // coq_Latn_US
+ case 0xCDC250454C61746ELLU: // cot_Latn_PE
+ case 0xD1C2534E4C61746ELLU: // cou_Latn_SN
+ case 0xDDC250454C61746ELLU: // cox_Latn_PE
+ case 0xE5C24D584C61746ELLU: // coz_Latn_MX
+ case 0x81E24D584C61746ELLU: // cpa_Latn_MX
+ case 0x85E250454C61746ELLU: // cpb_Latn_PE
+ case 0x89E250454C61746ELLU: // cpc_Latn_PE
+ case 0x99E247524772656BLLU: // cpg_Grek_GR
+ case 0xA1E24E524C61746ELLU: // cpi_Latn_NR
+ case 0xB5E247484C61746ELLU: // cpn_Latn_GH
+ case 0xB9E242464C61746ELLU: // cpo_Latn_BF
+ case 0xC9E250484C61746ELLU: // cps_Latn_PH
+ case 0xD1E250454C61746ELLU: // cpu_Latn_PE
+ case 0xDDE2434E4C61746ELLU: // cpx_Latn_CN
+ case 0xE1E250454C61746ELLU: // cpy_Latn_PE
+ case 0x8E02434E4C61746ELLU: // cqd_Latn_CN
+ case 0x6372434143616E73LLU: // cr_Cans_CA
+ case 0x822245544C61746ELLU: // cra_Latn_ET
+ case 0x862256434C61746ELLU: // crb_Latn_VC
+ case 0x8A2256554C61746ELLU: // crc_Latn_VU
+ case 0x8E2255534C61746ELLU: // crd_Latn_US
+ case 0x9622434F4C61746ELLU: // crf_Latn_CO
+ case 0x9A2243414C61746ELLU: // crg_Latn_CA
+ case 0x9E2255414379726CLLU: // crh_Cyrl_UA
+ case 0xA22253544C61746ELLU: // cri_Latn_ST
+ case 0xA622434143616E73LLU: // crj_Cans_CA
+ case 0xAA22434143616E73LLU: // crk_Cans_CA
+ case 0xAE22434143616E73LLU: // crl_Cans_CA
+ case 0xB222434143616E73LLU: // crm_Cans_CA
+ case 0xB6224D584C61746ELLU: // crn_Latn_MX
+ case 0xBA2255534C61746ELLU: // cro_Latn_US
+ case 0xC22241524C61746ELLU: // crq_Latn_AR
+ case 0xCA2253434C61746ELLU: // crs_Latn_SC
+ case 0xCE2241524C61746ELLU: // crt_Latn_AR
+ case 0xD622494E4C61746ELLU: // crv_Latn_IN
+ case 0xDA22564E4C61746ELLU: // crw_Latn_VN
+ case 0xDE2243414C61746ELLU: // crx_Latn_CA
+ case 0xE2224E474C61746ELLU: // cry_Latn_NG
+ case 0xE62255534C61746ELLU: // crz_Latn_US
+ case 0x6373435A4C61746ELLU: // cs_Latn_CZ
+ case 0x82424D584C61746ELLU: // csa_Latn_MX
+ case 0x8642504C4C61746ELLU: // csb_Latn_PL
+ case 0x9E424D4D4D796D72LLU: // csh_Mymr_MM
+ case 0xA6424D4D4C61746ELLU: // csj_Latn_MM
+ case 0xAA42534E4C61746ELLU: // csk_Latn_SN
+ case 0xB24255534C61746ELLU: // csm_Latn_US
+ case 0xBA424D584C61746ELLU: // cso_Latn_MX
+ case 0xBE42434E48616E73LLU: // csp_Hans_CN
+ case 0xCA4255534C61746ELLU: // css_Latn_US
+ case 0xCE4255534C61746ELLU: // cst_Latn_US
+ case 0xD6424D4D4C61746ELLU: // csv_Latn_MM
+ case 0xDA42434143616E73LLU: // csw_Cans_CA
+ case 0xE2424D4D4C61746ELLU: // csy_Latn_MM
+ case 0xE64255534C61746ELLU: // csz_Latn_US
+ case 0x82624D584C61746ELLU: // cta_Latn_MX
+ case 0x8A6255534C61746ELLU: // ctc_Latn_US
+ case 0x8E624D4D50617563LLU: // ctd_Pauc_MM
+ case 0x92624D584C61746ELLU: // cte_Latn_MX
+ case 0x9A62424442656E67LLU: // ctg_Beng_BD
+ case 0x9E624D4D4C61746ELLU: // cth_Latn_MM
+ case 0xAE624D584C61746ELLU: // ctl_Latn_MX
+ case 0xB26255534C61746ELLU: // ctm_Latn_US
+ case 0xB6624E5044657661LLU: // ctn_Deva_NP
+ case 0xBA62434F4C61746ELLU: // cto_Latn_CO
+ case 0xBE624D584C61746ELLU: // ctp_Latn_MX
+ case 0xCA6250484C61746ELLU: // cts_Latn_PH
+ case 0xCE62494E54616D6CLLU: // ctt_Taml_IN
+ case 0xD2624D584C61746ELLU: // ctu_Latn_MX
+ case 0xE262494E54616D6CLLU: // cty_Taml_IN
+ case 0xE6624D584C61746ELLU: // ctz_Latn_MX
+ case 0x637552554379726CLLU: // cu_Cyrl_RU
+ case 0x63754247476C6167LLU: // cu_Glag_BG
+ case 0x8282564E4C61746ELLU: // cua_Latn_VN
+ case 0x8682434F4C61746ELLU: // cub_Latn_CO
+ case 0x8A824D584C61746ELLU: // cuc_Latn_MX
+ case 0x9E824B454C61746ELLU: // cuh_Latn_KE
+ case 0xA282434F4C61746ELLU: // cui_Latn_CO
+ case 0xA68250454C61746ELLU: // cuj_Latn_PE
+ case 0xAA8250414C61746ELLU: // cuk_Latn_PA
+ case 0xAE8242524C61746ELLU: // cul_Latn_BR
+ case 0xBA8256454C61746ELLU: // cuo_Latn_VE
+ case 0xBE8255534C61746ELLU: // cup_Latn_US
+ case 0xCE824D584C61746ELLU: // cut_Latn_MX
+ case 0xD282434E4C616E61LLU: // cuu_Lana_CN
+ case 0xD682434D4C61746ELLU: // cuv_Latn_CM
+ case 0xDE824D584C61746ELLU: // cux_Latn_MX
+ case 0xE2824D584C61746ELLU: // cuy_Latn_MX
+ case 0x637652554379726CLLU: // cv_Cyrl_RU
+ case 0x9AA2494E4C61746ELLU: // cvg_Latn_IN
+ case 0xB6A24D584C61746ELLU: // cvn_Latn_MX
+ case 0x82C2545A4C61746ELLU: // cwa_Latn_TZ
+ case 0x86C24D5A4C61746ELLU: // cwb_Latn_MZ
+ case 0x92C2545A4C61746ELLU: // cwe_Latn_TZ
+ case 0x9AC24D594C61746ELLU: // cwg_Latn_MY
+ case 0xCEC2534E4C61746ELLU: // cwt_Latn_SN
+ case 0x9EE24E474C61746ELLU: // cxh_Latn_NG
+ case 0x637947424C61746ELLU: // cy_Latn_GB
+ case 0x83024D584C61746ELLU: // cya_Latn_MX
+ case 0x8702424F4C61746ELLU: // cyb_Latn_BO
+ case 0xBB0250484C61746ELLU: // cyo_Latn_PH
+ case 0x9F22434E48616E73LLU: // czh_Hans_CN
+ case 0xAB22435A48656272LLU: // czk_Hebr_CZ
+ case 0xB7224D584C61746ELLU: // czn_Latn_MX
+ case 0xCF224D4D4C61746ELLU: // czt_Latn_MM
+ case 0x6461444B4C61746ELLU: // da_Latn_DK
+ case 0x800354444C61746ELLU: // daa_Latn_TD
+ case 0x880350474C61746ELLU: // dac_Latn_PG
+ case 0x8C0350474C61746ELLU: // dad_Latn_PG
+ case 0x9003434D4C61746ELLU: // dae_Latn_CM
+ case 0x980347484C61746ELLU: // dag_Latn_GH
+ case 0x9C0350474C61746ELLU: // dah_Latn_PG
+ case 0xA00354444C61746ELLU: // dai_Latn_TD
+ case 0xA40353444C61746ELLU: // daj_Latn_SD
+ case 0xA80355534C61746ELLU: // dak_Latn_US
+ case 0xAC034B454C61746ELLU: // dal_Latn_KE
+ case 0xB0034E474C61746ELLU: // dam_Latn_NG
+ case 0xB8034D4D4C61746ELLU: // dao_Latn_MM
+ case 0xC003494E44657661LLU: // daq_Deva_IN
+ case 0xC40352554379726CLLU: // dar_Cyrl_RU
+ case 0xC80343494C61746ELLU: // das_Latn_CI
+ case 0xD00354444C61746ELLU: // dau_Latn_TD
+ case 0xD4034B454C61746ELLU: // dav_Latn_KE
+ case 0xD80350484C61746ELLU: // daw_Latn_PH
+ case 0xDC0341554C61746ELLU: // dax_Latn_AU
+ case 0xE40349444C61746ELLU: // daz_Latn_ID
+ case 0x80234D4C4C61746ELLU: // dba_Latn_ML
+ case 0x84234E474C61746ELLU: // dbb_Latn_NG
+ case 0x8C234E474C61746ELLU: // dbd_Latn_NG
+ case 0x902349444C61746ELLU: // dbe_Latn_ID
+ case 0x942349444C61746ELLU: // dbf_Latn_ID
+ case 0x98234D4C4C61746ELLU: // dbg_Latn_ML
+ case 0xA0234E474C61746ELLU: // dbi_Latn_NG
+ case 0xA4234D594C61746ELLU: // dbj_Latn_MY
+ case 0xAC2341554C61746ELLU: // dbl_Latn_AU
+ case 0xB0234E474C61746ELLU: // dbm_Latn_NG
+ case 0xB42349444C61746ELLU: // dbn_Latn_ID
+ case 0xB8234E474C61746ELLU: // dbo_Latn_NG
+ case 0xBC234E474C61746ELLU: // dbp_Latn_NG
+ case 0xC023434D4C61746ELLU: // dbq_Latn_CM
+ case 0xCC234D4C4C61746ELLU: // dbt_Latn_ML
+ case 0xD0234D4C4C61746ELLU: // dbu_Latn_ML
+ case 0xD4234E474C61746ELLU: // dbv_Latn_NG
+ case 0xD8234D4C4C61746ELLU: // dbw_Latn_ML
+ case 0xE02350474C61746ELLU: // dby_Latn_PG
+ case 0x8843494E41726162LLU: // dcc_Arab_IN
+ case 0xC44356494C61746ELLU: // dcr_Latn_VI
+ case 0x806341554C61746ELLU: // dda_Latn_AU
+ case 0x8C6353534C61746ELLU: // ddd_Latn_SS
+ case 0x906343474C61746ELLU: // dde_Latn_CG
+ case 0x9863544C4C61746ELLU: // ddg_Latn_TL
+ case 0xA06350474C61746ELLU: // ddi_Latn_PG
+ case 0xA46341554C61746ELLU: // ddj_Latn_AU
+ case 0xB463424A4C61746ELLU: // ddn_Latn_BJ
+ case 0xB86352554379726CLLU: // ddo_Cyrl_RU
+ case 0xC46341554C61746ELLU: // ddr_Latn_AU
+ case 0xC8634D4C4C61746ELLU: // dds_Latn_ML
+ case 0xD86349444C61746ELLU: // ddw_Latn_ID
+ case 0x646544454C61746ELLU: // de_Latn_DE
+ case 0x888353444C61746ELLU: // dec_Latn_SD
+ case 0x8C8350474C61746ELLU: // ded_Latn_PG
+ case 0x90834C524C61746ELLU: // dee_Latn_LR
+ case 0x9483495241726162LLU: // def_Arab_IR
+ case 0x98834E474C61746ELLU: // deg_Latn_NG
+ case 0x9C83504B41726162LLU: // deh_Arab_PK
+ case 0xA08349444C61746ELLU: // dei_Latn_ID
+ case 0xA883434D4C61746ELLU: // dek_Latn_CM
+ case 0xAC8355534C61746ELLU: // del_Latn_US
+ case 0xB08349444C61746ELLU: // dem_Latn_ID
+ case 0xB48343414C61746ELLU: // den_Latn_CA
+ case 0xC08343464C61746ELLU: // deq_Latn_CF
+ case 0xC483494E42656E67LLU: // der_Beng_IN
+ case 0xC88342524C61746ELLU: // des_Latn_BR
+ case 0xD48350474C61746ELLU: // dev_Latn_PG
+ case 0xE48343444C61746ELLU: // dez_Latn_CD
+ case 0x80C347484C61746ELLU: // dga_Latn_GH
+ case 0x84C34D4C4C61746ELLU: // dgb_Latn_ML
+ case 0x88C350484C61746ELLU: // dgc_Latn_PH
+ case 0x8CC342464C61746ELLU: // dgd_Latn_BF
+ case 0x90C350474C61746ELLU: // dge_Latn_PG
+ case 0x98C350474C61746ELLU: // dgg_Latn_PG
+ case 0x9CC34E474C61746ELLU: // dgh_Latn_NG
+ case 0xA0C342464C61746ELLU: // dgi_Latn_BF
+ case 0xA8C343464C61746ELLU: // dgk_Latn_CF
+ case 0xACC3534441726162LLU: // dgl_Arab_SD
+ case 0xB4C341554C61746ELLU: // dgn_Latn_AU
+ case 0xC4C343414C61746ELLU: // dgr_Latn_CA
+ case 0xC8C342464C61746ELLU: // dgs_Latn_BF
+ case 0xCCC341554C61746ELLU: // dgt_Latn_AU
+ case 0xD8C341554C61746ELLU: // dgw_Latn_AU
+ case 0xDCC350474C61746ELLU: // dgx_Latn_PG
+ case 0xE4C350474C61746ELLU: // dgz_Latn_PG
+ case 0x98E341554C61746ELLU: // dhg_Latn_AU
+ case 0xA0E34E5044657661LLU: // dhi_Deva_NP
+ case 0xACE341554C61746ELLU: // dhl_Latn_AU
+ case 0xB0E3414F4C61746ELLU: // dhm_Latn_AO
+ case 0xB4E3494E47756A72LLU: // dhn_Gujr_IN
+ case 0xB8E3494E44657661LLU: // dho_Deva_IN
+ case 0xC4E341554C61746ELLU: // dhr_Latn_AU
+ case 0xC8E3545A4C61746ELLU: // dhs_Latn_TZ
+ case 0xD0E341554C61746ELLU: // dhu_Latn_AU
+ case 0xD4E34E434C61746ELLU: // dhv_Latn_NC
+ case 0xD8E34E5044657661LLU: // dhw_Deva_NP
+ case 0xDCE341554C61746ELLU: // dhx_Latn_AU
+ case 0x810350474C61746ELLU: // dia_Latn_PG
+ case 0x850353534C61746ELLU: // dib_Latn_SS
+ case 0x890343494C61746ELLU: // dic_Latn_CI
+ case 0x8D0353534C61746ELLU: // did_Latn_SS
+ case 0x950341554C61746ELLU: // dif_Latn_AU
+ case 0x99034B454C61746ELLU: // dig_Latn_KE
+ case 0x9D034D584C61746ELLU: // dih_Latn_MX
+ case 0xA103434D4C61746ELLU: // dii_Latn_CM
+ case 0xA50349444C61746ELLU: // dij_Latn_ID
+ case 0xAD0353444C61746ELLU: // dil_Latn_SD
+ case 0xB50353534C61746ELLU: // din_Latn_SS
+ case 0xB9034E474C61746ELLU: // dio_Latn_NG
+ case 0xBD0353534C61746ELLU: // dip_Latn_SS
+ case 0xC5034E474C61746ELLU: // dir_Latn_NG
+ case 0xC903494E4C61746ELLU: // dis_Latn_IN
+ case 0xD1034E414C61746ELLU: // diu_Latn_NA
+ case 0xD90353534C61746ELLU: // diw_Latn_SS
+ case 0xDD0356554C61746ELLU: // dix_Latn_VU
+ case 0xE10349444C61746ELLU: // diy_Latn_ID
+ case 0xE50343444C61746ELLU: // diz_Latn_CD
+ case 0x812341554C61746ELLU: // dja_Latn_AU
+ case 0x852341554C61746ELLU: // djb_Latn_AU
+ case 0x892354444C61746ELLU: // djc_Latn_TD
+ case 0x8D2341554C61746ELLU: // djd_Latn_AU
+ case 0x91234E454C61746ELLU: // dje_Latn_NE
+ case 0x952341554C61746ELLU: // djf_Latn_AU
+ case 0xA12341554C61746ELLU: // dji_Latn_AU
+ case 0xA52341554C61746ELLU: // djj_Latn_AU
+ case 0xA92353524C61746ELLU: // djk_Latn_SR
+ case 0xB1234D4C4C61746ELLU: // djm_Latn_ML
+ case 0xB52341554C61746ELLU: // djn_Latn_AU
+ case 0xB92349444C61746ELLU: // djo_Latn_ID
+ case 0xC52341554C61746ELLU: // djr_Latn_AU
+ case 0xD12350474C61746ELLU: // dju_Latn_PG
+ case 0xD92341554C61746ELLU: // djw_Latn_AU
+ case 0x8143425454696274LLU: // dka_Tibt_BT
+ case 0x99434E474C61746ELLU: // dkg_Latn_NG
+ case 0xA94349444C61746ELLU: // dkk_Latn_ID
+ case 0xC5434D594C61746ELLU: // dkr_Latn_MY
+ case 0xC94353534C61746ELLU: // dks_Latn_SS
+ case 0xDD43434D4C61746ELLU: // dkx_Latn_CM
+ case 0x996352554379726CLLU: // dlg_Cyrl_RU
+ case 0xB16348524C61746ELLU: // dlm_Latn_HR
+ case 0xB563494E4C61746ELLU: // dln_Latn_IN
+ case 0x818347414C61746ELLU: // dma_Latn_GA
+ case 0x85834D4C4C61746ELLU: // dmb_Latn_ML
+ case 0x898350474C61746ELLU: // dmc_Latn_PG
+ case 0x8D8341554C61746ELLU: // dmd_Latn_AU
+ case 0x9183434D4C61746ELLU: // dme_Latn_CM
+ case 0x95834E474D656466LLU: // dmf_Medf_NG
+ case 0x99834D594C61746ELLU: // dmg_Latn_MY
+ case 0xA983504B41726162LLU: // dmk_Arab_PK
+ case 0xAD83504B41726162LLU: // dml_Arab_PK
+ case 0xB183434D4C61746ELLU: // dmm_Latn_CM
+ case 0xB983434D4C61746ELLU: // dmo_Latn_CM
+ case 0xC58349444C61746ELLU: // dmr_Latn_ID
+ case 0xC98349444C61746ELLU: // dms_Latn_ID
+ case 0xD18349444C61746ELLU: // dmu_Latn_ID
+ case 0xD5834D594C61746ELLU: // dmv_Latn_MY
+ case 0xD98341554C61746ELLU: // dmw_Latn_AU
+ case 0xDD834D5A4C61746ELLU: // dmx_Latn_MZ
+ case 0xE18349444C61746ELLU: // dmy_Latn_ID
+ case 0x81A349444C61746ELLU: // dna_Latn_ID
+ case 0x8DA350474C61746ELLU: // dnd_Latn_PG
+ case 0x91A3545A4C61746ELLU: // dne_Latn_TZ
+ case 0x99A34B474379726CLLU: // dng_Cyrl_KG
+ case 0xA1A349444C61746ELLU: // dni_Latn_ID
+ case 0xA5A343494C61746ELLU: // dnj_Latn_CI
+ case 0xA9A349444C61746ELLU: // dnk_Latn_ID
+ case 0xB5A342464C61746ELLU: // dnn_Latn_BF
+ case 0xB9A343444C61746ELLU: // dno_Latn_CD
+ case 0xC5A350474C61746ELLU: // dnr_Latn_PG
+ case 0xCDA349444C61746ELLU: // dnt_Latn_ID
+ case 0xD1A34D4D4D796D72LLU: // dnu_Mymr_MM
+ case 0xD5A34D4D4D796D72LLU: // dnv_Mymr_MM
+ case 0xD9A349444C61746ELLU: // dnw_Latn_ID
+ case 0xE1A342524C61746ELLU: // dny_Latn_BR
+ case 0x81C350474C61746ELLU: // doa_Latn_PG
+ case 0x85C350474C61746ELLU: // dob_Latn_PG
+ case 0x89C3434E4C61746ELLU: // doc_Latn_CN
+ case 0x91C3545A4C61746ELLU: // doe_Latn_TZ
+ case 0x95C350474C61746ELLU: // dof_Latn_PG
+ case 0x9DC34E474C61746ELLU: // doh_Latn_NG
+ case 0xA1C3494E44657661LLU: // doi_Deva_IN
+ case 0xA9C349444C61746ELLU: // dok_Latn_ID
+ case 0xADC350474C61746ELLU: // dol_Latn_PG
+ case 0xB5C350474C61746ELLU: // don_Latn_PG
+ case 0xB9C343444C61746ELLU: // doo_Latn_CD
+ case 0xBDC3424A4C61746ELLU: // dop_Latn_BJ
+ case 0xC5C353424C61746ELLU: // dor_Latn_SB
+ case 0xC9C342464C61746ELLU: // dos_Latn_BF
+ case 0xCDC34E474C61746ELLU: // dot_Latn_NG
+ case 0xD5C35A574C61746ELLU: // dov_Latn_ZW
+ case 0xD9C3434D4C61746ELLU: // dow_Latn_CM
+ case 0xDDC3455445746869LLU: // dox_Ethi_ET
+ case 0xE1C347484C61746ELLU: // doy_Latn_GH
+ case 0xBDE34D594C61746ELLU: // dpp_Latn_MY
+ case 0x8A2350544C61746ELLU: // drc_Latn_PT
+ case 0x92234E5054696274LLU: // dre_Tibt_NP
+ case 0x9A234D594C61746ELLU: // drg_Latn_MY
+ case 0xA2234E474C61746ELLU: // dri_Latn_NG
+ case 0xAE2341554C61746ELLU: // drl_Latn_AU
+ case 0xB62349444C61746ELLU: // drn_Latn_ID
+ case 0xBA234D594C61746ELLU: // dro_Latn_MY
+ case 0xC2234E5044657661LLU: // drq_Deva_NP
+ case 0xCA23455445746869LLU: // drs_Ethi_ET
+ case 0xCE234E4C4C61746ELLU: // drt_Latn_NL
+ case 0xD22354574C61746ELLU: // dru_Latn_TW
+ case 0xE2234E5044657661LLU: // dry_Deva_NP
+ case 0x864344454C61746ELLU: // dsb_Latn_DE
+ case 0x9E434B454C61746ELLU: // dsh_Latn_KE
+ case 0xA24354444C61746ELLU: // dsi_Latn_TD
+ case 0xAA434E474C61746ELLU: // dsk_Latn_NG
+ case 0xB64349444C61746ELLU: // dsn_Latn_ID
+ case 0xBA43494E4F727961LLU: // dso_Orya_IN
+ case 0xC2434D4C4C61746ELLU: // dsq_Latn_ML
+ case 0x8263434E4C61746ELLU: // dta_Latn_CN
+ case 0x86634D594C61746ELLU: // dtb_Latn_MY
+ case 0x8E6343414C61746ELLU: // dtd_Latn_CA
+ case 0x9E6341554C61746ELLU: // dth_Latn_AU
+ case 0xA2634D4C4C61746ELLU: // dti_Latn_ML
+ case 0xAA634D4C4C61746ELLU: // dtk_Latn_ML
+ case 0xB2634D4C4C61746ELLU: // dtm_Latn_ML
+ case 0xBA634D4C4C61746ELLU: // dto_Latn_ML
+ case 0xBE634D594C61746ELLU: // dtp_Latn_MY
+ case 0xC6634D594C61746ELLU: // dtr_Latn_MY
+ case 0xCA634D4C4C61746ELLU: // dts_Latn_ML
+ case 0xCE634D4C4C61746ELLU: // dtt_Latn_ML
+ case 0xD2634D4C4C61746ELLU: // dtu_Latn_ML
+ case 0xE2634E5044657661LLU: // dty_Deva_NP
+ case 0x8283434D4C61746ELLU: // dua_Latn_CM
+ case 0x8683494E47756A72LLU: // dub_Gujr_IN
+ case 0x8A8350474C61746ELLU: // duc_Latn_PG
+ case 0x928350484C61746ELLU: // due_Latn_PH
+ case 0x96834E434C61746ELLU: // duf_Latn_NC
+ case 0x9A834B454C61746ELLU: // dug_Latn_KE
+ case 0x9E83494E44657661LLU: // duh_Deva_IN
+ case 0xA28350474C61746ELLU: // dui_Latn_PG
+ case 0xAA8350474C61746ELLU: // duk_Latn_PG
+ case 0xAE8350484C61746ELLU: // dul_Latn_PH
+ case 0xB2834E4C4C61746ELLU: // dum_Latn_NL
+ case 0xB68349444C61746ELLU: // dun_Latn_ID
+ case 0xBA8350484C61746ELLU: // duo_Latn_PH
+ case 0xBE8349444C61746ELLU: // dup_Latn_ID
+ case 0xC28349444C61746ELLU: // duq_Latn_ID
+ case 0xC683434D4C61746ELLU: // dur_Latn_CM
+ case 0xCA834E5044657661LLU: // dus_Deva_NP
+ case 0xD283434E4C61746ELLU: // duu_Latn_CN
+ case 0xD68349444C61746ELLU: // duv_Latn_ID
+ case 0xDA8349444C61746ELLU: // duw_Latn_ID
+ case 0xDE834D4C4C61746ELLU: // dux_Latn_ML
+ case 0xE28350484C61746ELLU: // duy_Latn_PH
+ case 0xE683434D4C61746ELLU: // duz_Latn_CM
+ case 0x64764D5654686161LLU: // dv_Thaa_MV
+ case 0x82A350474C61746ELLU: // dva_Latn_PG
+ case 0x82C34E474C61746ELLU: // dwa_Latn_NG
+ case 0xAAC3494E4F727961LLU: // dwk_Orya_IN
+ case 0xC6C345544C61746ELLU: // dwr_Latn_ET
+ case 0xD2C341554C61746ELLU: // dwu_Latn_AU
+ case 0xDAC350474C61746ELLU: // dww_Latn_PG
+ case 0xE2C341554C61746ELLU: // dwy_Latn_AU
+ case 0xE6C34E5044657661LLU: // dwz_Deva_NP
+ case 0x830342464C61746ELLU: // dya_Latn_BF
+ case 0x870341554C61746ELLU: // dyb_Latn_AU
+ case 0x8F0341554C61746ELLU: // dyd_Latn_AU
+ case 0x9B0350484C61746ELLU: // dyg_Latn_PH
+ case 0xA30343494C61746ELLU: // dyi_Latn_CI
+ case 0xB3034D4C4C61746ELLU: // dym_Latn_ML
+ case 0xB70341554C61746ELLU: // dyn_Latn_AU
+ case 0xBB03534E4C61746ELLU: // dyo_Latn_SN
+ case 0xC7034E474C61746ELLU: // dyr_Latn_NG
+ case 0xD30342464C61746ELLU: // dyu_Latn_BF
+ case 0xE30341554C61746ELLU: // dyy_Latn_AU
+ case 0x647A425454696274LLU: // dz_Tibt_BT
+ case 0x83234E474C61746ELLU: // dza_Latn_NG
+ case 0x8F234E474C61746ELLU: // dzd_Latn_NG
+ case 0x932341554C61746ELLU: // dze_Latn_AU
+ case 0x9B2354444C61746ELLU: // dzg_Latn_TD
+ case 0xAF23425454696274LLU: // dzl_Tibt_BT
+ case 0xB72343444C61746ELLU: // dzn_Latn_CD
+ case 0x800441554C61746ELLU: // eaa_Latn_AU
+ case 0x882449444C61746ELLU: // ebc_Latn_ID
+ case 0x98244E474C61746ELLU: // ebg_Latn_NG
+ case 0xA82450484C61746ELLU: // ebk_Latn_PH
+ case 0xB82443474C61746ELLU: // ebo_Latn_CG
+ case 0xC42443494C61746ELLU: // ebr_Latn_CI
+ case 0xD0244B454C61746ELLU: // ebu_Latn_KE
+ case 0xC44447524772656BLLU: // ecr_Grek_GR
+ case 0xE044435943707274LLU: // ecy_Cprt_CY
+ case 0x656547484C61746ELLU: // ee_Latn_GH
+ case 0x80A44E474C61746ELLU: // efa_Latn_NG
+ case 0x90A443444C61746ELLU: // efe_Latn_CD
+ case 0xA0A44E474C61746ELLU: // efi_Latn_NG
+ case 0x80C443494C61746ELLU: // ega_Latn_CI
+ case 0xACC449544C61746ELLU: // egl_Latn_IT
+ case 0xB0C4545A4C61746ELLU: // egm_Latn_TZ
+ case 0xB8C44E474C61746ELLU: // ego_Latn_NG
+ case 0xE0C4454745677970LLU: // egy_Egyp_EG
+ case 0xD0E44E474C61746ELLU: // ehu_Latn_NG
+ case 0xBD0449444C61746ELLU: // eip_Latn_ID
+ case 0xCD0450474C61746ELLU: // eit_Latn_PG
+ case 0xD50450474C61746ELLU: // eiv_Latn_PG
+ case 0x812447574C61746ELLU: // eja_Latn_GW
+ case 0x81444E474C61746ELLU: // eka_Latn_NG
+ case 0x91444E474C61746ELLU: // eke_Latn_NG
+ case 0x994449444C61746ELLU: // ekg_Latn_ID
+ case 0xA1444E474C61746ELLU: // eki_Latn_NG
+ case 0xAD4442444C61746ELLU: // ekl_Latn_BD
+ case 0xB144434D4C61746ELLU: // ekm_Latn_CM
+ case 0xB9444D5A4C61746ELLU: // eko_Latn_MZ
+ case 0xBD444E474C61746ELLU: // ekp_Latn_NG
+ case 0xC5444E474C61746ELLU: // ekr_Latn_NG
+ case 0xE1444D4D4B616C69LLU: // eky_Kali_MM
+ case 0x656C47524772656BLLU: // el_Grek_GR
+ case 0x916450474C61746ELLU: // ele_Latn_PG
+ case 0xA96450474C61746ELLU: // elk_Latn_PG
+ case 0xB1644E474C61746ELLU: // elm_Latn_NG
+ case 0xB9644B454C61746ELLU: // elo_Latn_KE
+ case 0xD16450474C61746ELLU: // elu_Latn_PG
+ case 0x81844E474C61746ELLU: // ema_Latn_NG
+ case 0x858449444C61746ELLU: // emb_Latn_ID
+ case 0x918447464C61746ELLU: // eme_Latn_GF
+ case 0x99844E5044657661LLU: // emg_Deva_NP
+ case 0xA18450474C61746ELLU: // emi_Latn_PG
+ case 0xB1844D584C61746ELLU: // emm_Latn_MX
+ case 0xB584434D4C61746ELLU: // emn_Latn_CM
+ case 0xBD8450414C61746ELLU: // emp_Latn_PA
+ case 0xC98455534C61746ELLU: // ems_Latn_US
+ case 0xD184494E44657661LLU: // emu_Deva_IN
+ case 0xD98449444C61746ELLU: // emw_Latn_ID
+ case 0xDD8446524C61746ELLU: // emx_Latn_FR
+ case 0xE584434D4C61746ELLU: // emz_Latn_CM
+ case 0x656E47424C61746ELLU: // en_Latn_GB
+ case 0x656E55534C61746ELLU: // en_Latn_US
+ case 0x656E474253686177LLU: // en_Shaw_GB
+ case 0x81A450474C61746ELLU: // ena_Latn_PG
+ case 0x85A44B454C61746ELLU: // enb_Latn_KE
+ case 0x89A4564E4C61746ELLU: // enc_Latn_VN
+ case 0x8DA449444C61746ELLU: // end_Latn_ID
+ case 0x95A452554379726CLLU: // enf_Cyrl_RU
+ case 0x9DA452554379726CLLU: // enh_Cyrl_RU
+ case 0xADA450594C61746ELLU: // enl_Latn_PY
+ case 0xB1A447424C61746ELLU: // enm_Latn_GB
+ case 0xB5A44E474C61746ELLU: // enn_Latn_NG
+ case 0xB9A449444C61746ELLU: // eno_Latn_ID
+ case 0xC1A450474C61746ELLU: // enq_Latn_PG
+ case 0xC5A449444C61746ELLU: // enr_Latn_ID
+ case 0xD5A44E474C61746ELLU: // env_Latn_NG
+ case 0xD9A44E474C61746ELLU: // enw_Latn_NG
+ case 0xDDA450594C61746ELLU: // enx_Latn_PY
+ case 0xCDC443494C61746ELLU: // eot_Latn_CI
+ case 0xA1E44E474C61746ELLU: // epi_Latn_NG
+ case 0x8224494E54616D6CLLU: // era_Taml_IN
+ case 0x9A2456554C61746ELLU: // erg_Latn_VU
+ case 0x9E244E474C61746ELLU: // erh_Latn_NG
+ case 0xA22450474C61746ELLU: // eri_Latn_PG
+ case 0xAA2456554C61746ELLU: // erk_Latn_VU
+ case 0xC62441554C61746ELLU: // err_Latn_AU
+ case 0xCA24434E4C61746ELLU: // ers_Latn_CN
+ case 0xCE2449444C61746ELLU: // ert_Latn_ID
+ case 0xDA2449444C61746ELLU: // erw_Latn_ID
+ case 0x657345534C61746ELLU: // es_Latn_ES
+ case 0x65734D584C61746ELLU: // es_Latn_MX
+ case 0x657355534C61746ELLU: // es_Latn_US
+ case 0x9244424F4C61746ELLU: // ese_Latn_BO
+ case 0x9A44494E476F6E6DLLU: // esg_Gonm_IN
+ case 0x9E44495241726162LLU: // esh_Arab_IR
+ case 0xA24455534C61746ELLU: // esi_Latn_US
+ case 0xB24443494C61746ELLU: // esm_Latn_CI
+ case 0xCA4455534C61746ELLU: // ess_Latn_US
+ case 0xD24455534C61746ELLU: // esu_Latn_US
+ case 0xE24450484C61746ELLU: // esy_Latn_PH
+ case 0x657445454C61746ELLU: // et_Latn_EE
+ case 0x86644E474C61746ELLU: // etb_Latn_NG
+ case 0xB66456554C61746ELLU: // etn_Latn_VU
+ case 0xBA64434D4C61746ELLU: // eto_Latn_CM
+ case 0xC66450474C61746ELLU: // etr_Latn_PG
+ case 0xCA644E474C61746ELLU: // ets_Latn_NG
+ case 0xCE6449544974616CLLU: // ett_Ital_IT
+ case 0xD2644E474C61746ELLU: // etu_Latn_NG
+ case 0xDE644E474C61746ELLU: // etx_Latn_NG
+ case 0xE66449444C61746ELLU: // etz_Latn_ID
+ case 0x657545534C61746ELLU: // eu_Latn_ES
+ case 0x8E844D584C61746ELLU: // eud_Latn_MX
+ case 0x92A452554379726CLLU: // eve_Cyrl_RU
+ case 0x9EA44E474C61746ELLU: // evh_Latn_NG
+ case 0xB6A452554379726CLLU: // evn_Cyrl_RU
+ case 0xBAC4434D4C61746ELLU: // ewo_Latn_CM
+ case 0xCEE445534C61746ELLU: // ext_Latn_ES
+ case 0x830455534C61746ELLU: // eya_Latn_US
+ case 0xBB044B454C61746ELLU: // eyo_Latn_KE
+ case 0x83244E474C61746ELLU: // eza_Latn_NG
+ case 0x93244E474C61746ELLU: // eze_Latn_NG
+ case 0x6661495241726162LLU: // fa_Arab_IR
+ case 0x800550474C61746ELLU: // faa_Latn_PG
+ case 0x840547514C61746ELLU: // fab_Latn_GQ
+ case 0x8C0550474C61746ELLU: // fad_Latn_PG
+ case 0x940553424C61746ELLU: // faf_Latn_SB
+ case 0x980550474C61746ELLU: // fag_Latn_PG
+ case 0x9C054E474C61746ELLU: // fah_Latn_NG
+ case 0xA00550474C61746ELLU: // fai_Latn_PG
+ case 0xA40550474C61746ELLU: // faj_Latn_PG
+ case 0xA805434D4C61746ELLU: // fak_Latn_CM
+ case 0xAC05434D4C61746ELLU: // fal_Latn_CM
+ case 0xB0054E474C61746ELLU: // fam_Latn_NG
+ case 0xB40547514C61746ELLU: // fan_Latn_GQ
+ case 0xBC05534E4C61746ELLU: // fap_Latn_SN
+ case 0xC40553424C61746ELLU: // far_Latn_SB
+ case 0xD00549444C61746ELLU: // fau_Latn_ID
+ case 0xDC0545534C61746ELLU: // fax_Latn_ES
+ case 0xE005495241726162LLU: // fay_Arab_IR
+ case 0xE405495241726162LLU: // faz_Arab_IR
+ case 0xAC2550484C61746ELLU: // fbl_Latn_PH
+ case 0xC48553534C61746ELLU: // fer_Latn_SS
+ case 0x6666474E41646C6DLLU: // ff_Adlm_GN
+ case 0x6666534E4C61746ELLU: // ff_Latn_SN
+ case 0xA0A550474C61746ELLU: // ffi_Latn_PG
+ case 0xB0A54D4C4C61746ELLU: // ffm_Latn_ML
+ case 0xC4C554444C61746ELLU: // fgr_Latn_TD
+ case 0x666946494C61746ELLU: // fi_Latn_FI
+ case 0x8105534441726162LLU: // fia_Arab_SD
+ case 0x91054E474C61746ELLU: // fie_Latn_NG
+ case 0x950553414C61746ELLU: // fif_Latn_SA
+ case 0xAD0550484C61746ELLU: // fil_Latn_PH
+ case 0xBD05545A4C61746ELLU: // fip_Latn_TZ
+ case 0xC5054E474C61746ELLU: // fir_Latn_NG
+ case 0xCD0553454C61746ELLU: // fit_Latn_SE
+ case 0xD90550474C61746ELLU: // fiw_Latn_PG
+ case 0x666A464A4C61746ELLU: // fj_Latn_FJ
+ case 0xA9454E474C61746ELLU: // fkk_Latn_NG
+ case 0xD5454E4F4C61746ELLU: // fkv_Latn_NO
+ case 0x816555534C61746ELLU: // fla_Latn_US
+ case 0x9D6549444C61746ELLU: // flh_Latn_ID
+ case 0xA1654E474C61746ELLU: // fli_Latn_NG
+ case 0xAD65434D4C61746ELLU: // fll_Latn_CM
+ case 0xB56541554C61746ELLU: // fln_Latn_AU
+ case 0xC56543444C61746ELLU: // flr_Latn_CD
+ case 0xE1655A414C61746ELLU: // fly_Latn_ZA
+ case 0xBD85434D4C61746ELLU: // fmp_Latn_CM
+ case 0xD185494E44657661LLU: // fmu_Deva_IN
+ case 0x85A556554C61746ELLU: // fnb_Latn_VU
+ case 0x99A55A414C61746ELLU: // fng_Latn_ZA
+ case 0xA1A554444C61746ELLU: // fni_Latn_TD
+ case 0x666F464F4C61746ELLU: // fo_Latn_FO
+ case 0x8DC5424A4C61746ELLU: // fod_Latn_BJ
+ case 0xA1C550474C61746ELLU: // foi_Latn_PG
+ case 0xB1C543444C61746ELLU: // fom_Latn_CD
+ case 0xB5C5424A4C61746ELLU: // fon_Latn_BJ
+ case 0xC5C550474C61746ELLU: // for_Latn_PG
+ case 0xC9C554574C61746ELLU: // fos_Latn_TW
+ case 0x91E547514C61746ELLU: // fpe_Latn_GQ
+ case 0xCA0550474C61746ELLU: // fqs_Latn_PG
+ case 0x667246524C61746ELLU: // fr_Latn_FR
+ case 0x8A2555534C61746ELLU: // frc_Latn_US
+ case 0x8E2549444C61746ELLU: // frd_Latn_ID
+ case 0xAA2544454C61746ELLU: // frk_Latn_DE
+ case 0xB22546524C61746ELLU: // frm_Latn_FR
+ case 0xBA2546524C61746ELLU: // fro_Latn_FR
+ case 0xBE2546524C61746ELLU: // frp_Latn_FR
+ case 0xC22550474C61746ELLU: // frq_Latn_PG
+ case 0xC62544454C61746ELLU: // frr_Latn_DE
+ case 0xCA2544454C61746ELLU: // frs_Latn_DE
+ case 0xCE2556554C61746ELLU: // frt_Latn_VU
+ case 0x8685434D41726162LLU: // fub_Arab_CM
+ case 0x8E8557464C61746ELLU: // fud_Latn_WF
+ case 0x9285424A4C61746ELLU: // fue_Latn_BJ
+ case 0x9685474E4C61746ELLU: // fuf_Latn_GN
+ case 0x9E854E454C61746ELLU: // fuh_Latn_NE
+ case 0xA28554444C61746ELLU: // fui_Latn_TD
+ case 0xB2854E474C61746ELLU: // fum_Latn_NG
+ case 0xB68542524C61746ELLU: // fun_Latn_BR
+ case 0xC2854E454C61746ELLU: // fuq_Latn_NE
+ case 0xC68549544C61746ELLU: // fur_Latn_IT
+ case 0xCE8556554C61746ELLU: // fut_Latn_VU
+ case 0xD28543444C61746ELLU: // fuu_Latn_CD
+ case 0xD6854E474C61746ELLU: // fuv_Latn_NG
+ case 0xE28550474C61746ELLU: // fuy_Latn_PG
+ case 0xC6A553444C61746ELLU: // fvr_Latn_SD
+ case 0x82C54E434C61746ELLU: // fwa_Latn_NC
+ case 0x92C54E414C61746ELLU: // fwe_Latn_NA
+ case 0x66794E4C4C61746ELLU: // fy_Latn_NL
+ case 0x676149454C61746ELLU: // ga_Latn_IE
+ case 0x800647484C61746ELLU: // gaa_Latn_GH
+ case 0x840654444C61746ELLU: // gab_Latn_TD
+ case 0x8806494E4C61746ELLU: // gac_Latn_IN
+ case 0x8C0650484C61746ELLU: // gad_Latn_PH
+ case 0x900656454C61746ELLU: // gae_Latn_VE
+ case 0x940650474C61746ELLU: // gaf_Latn_PG
+ case 0x98064D444C61746ELLU: // gag_Latn_MD
+ case 0x9C0650474C61746ELLU: // gah_Latn_PG
+ case 0xA00650474C61746ELLU: // gai_Latn_PG
+ case 0xA40650474C61746ELLU: // gaj_Latn_PG
+ case 0xA80649444C61746ELLU: // gak_Latn_ID
+ case 0xAC06544C4C61746ELLU: // gal_Latn_TL
+ case 0xB00650474C61746ELLU: // gam_Latn_PG
+ case 0xB406434E48616E73LLU: // gan_Hans_CN
+ case 0xB80650474C61746ELLU: // gao_Latn_PG
+ case 0xBC0650474C61746ELLU: // gap_Latn_PG
+ case 0xC006494E4F727961LLU: // gaq_Orya_IN
+ case 0xC40650474C61746ELLU: // gar_Latn_PG
+ case 0xC806494E47756A72LLU: // gas_Gujr_IN
+ case 0xCC0650474C61746ELLU: // gat_Latn_PG
+ case 0xD006494E54656C75LLU: // gau_Telu_IN
+ case 0xD80650474C61746ELLU: // gaw_Latn_PG
+ case 0xDC0645544C61746ELLU: // gax_Latn_ET
+ case 0xE00649444C61746ELLU: // gay_Latn_ID
+ case 0x802643464C61746ELLU: // gba_Latn_CF
+ case 0x842641554C61746ELLU: // gbb_Latn_AU
+ case 0x8C2641554C61746ELLU: // gbd_Latn_AU
+ case 0x902650474C61746ELLU: // gbe_Latn_PG
+ case 0x942650474C61746ELLU: // gbf_Latn_PG
+ case 0x982643464C61746ELLU: // gbg_Latn_CF
+ case 0x9C26424A4C61746ELLU: // gbh_Latn_BJ
+ case 0xA02649444C61746ELLU: // gbi_Latn_ID
+ case 0xA426494E4F727961LLU: // gbj_Orya_IN
+ case 0xA826494E44657661LLU: // gbk_Deva_IN
+ case 0xAC26494E47756A72LLU: // gbl_Gujr_IN
+ case 0xB026494E44657661LLU: // gbm_Deva_IN
+ case 0xB42653534C61746ELLU: // gbn_Latn_SS
+ case 0xBC2643464C61746ELLU: // gbp_Latn_CF
+ case 0xC02643464C61746ELLU: // gbq_Latn_CF
+ case 0xC4264E474C61746ELLU: // gbr_Latn_NG
+ case 0xC826424A4C61746ELLU: // gbs_Latn_BJ
+ case 0xD02641554C61746ELLU: // gbu_Latn_AU
+ case 0xD42643464C61746ELLU: // gbv_Latn_CF
+ case 0xD82641554C61746ELLU: // gbw_Latn_AU
+ case 0xDC26424A4C61746ELLU: // gbx_Latn_BJ
+ case 0xE0264E474C61746ELLU: // gby_Latn_NG
+ case 0xE426495241726162LLU: // gbz_Arab_IR
+ case 0x884650474C61746ELLU: // gcc_Latn_PG
+ case 0x8C4641554C61746ELLU: // gcd_Latn_AU
+ case 0x944647504C61746ELLU: // gcf_Latn_GP
+ case 0xAC4647444C61746ELLU: // gcl_Latn_GD
+ case 0xB44650474C61746ELLU: // gcn_Latn_PG
+ case 0xC44647464C61746ELLU: // gcr_Latn_GF
+ case 0xCC4656454C61746ELLU: // gct_Latn_VE
+ case 0x676447424C61746ELLU: // gd_Latn_GB
+ case 0x8466494E4F727961LLU: // gdb_Orya_IN
+ case 0x886641554C61746ELLU: // gdc_Latn_AU
+ case 0x8C6650474C61746ELLU: // gdd_Latn_PG
+ case 0x90664E474C61746ELLU: // gde_Latn_NG
+ case 0x94664E474C61746ELLU: // gdf_Latn_NG
+ case 0x986650484C61746ELLU: // gdg_Latn_PH
+ case 0x9C6641554C61746ELLU: // gdh_Latn_AU
+ case 0xA06643464C61746ELLU: // gdi_Latn_CF
+ case 0xA46641554C61746ELLU: // gdj_Latn_AU
+ case 0xA86654444C61746ELLU: // gdk_Latn_TD
+ case 0xAC6645544C61746ELLU: // gdl_Latn_ET
+ case 0xB06654444C61746ELLU: // gdm_Latn_TD
+ case 0xB46650474C61746ELLU: // gdn_Latn_PG
+ case 0xB86652554379726CLLU: // gdo_Cyrl_RU
+ case 0xC06659454C61746ELLU: // gdq_Latn_YE
+ case 0xC46650474C61746ELLU: // gdr_Latn_PG
+ case 0xCC6641554C61746ELLU: // gdt_Latn_AU
+ case 0xD0664E474C61746ELLU: // gdu_Latn_NG
+ case 0xDC66494E44657661LLU: // gdx_Deva_IN
+ case 0x80864E474C61746ELLU: // gea_Latn_NG
+ case 0x848650474C61746ELLU: // geb_Latn_PG
+ case 0x88864C524C61746ELLU: // gec_Latn_LR
+ case 0x8C864E474C61746ELLU: // ged_Latn_NG
+ case 0x948649444C61746ELLU: // gef_Latn_ID
+ case 0x98864E474C61746ELLU: // geg_Latn_NG
+ case 0x9C8643414C61746ELLU: // geh_Latn_CA
+ case 0xA08649444C61746ELLU: // gei_Latn_ID
+ case 0xA48654474C61746ELLU: // gej_Latn_TG
+ case 0xA8864E474C61746ELLU: // gek_Latn_NG
+ case 0xAC864E474C61746ELLU: // gel_Latn_NG
+ case 0xC08643464C61746ELLU: // geq_Latn_CF
+ case 0xC88649444C61746ELLU: // ges_Latn_ID
+ case 0xD48647414C61746ELLU: // gev_Latn_GA
+ case 0xD8864E474C61746ELLU: // gew_Latn_NG
+ case 0xDC86534F4C61746ELLU: // gex_Latn_SO
+ case 0xE08643444C61746ELLU: // gey_Latn_CD
+ case 0xE486455445746869LLU: // gez_Ethi_ET
+ case 0xA8A650474C61746ELLU: // gfk_Latn_PG
+ case 0x80C653424C61746ELLU: // gga_Latn_SB
+ case 0x84C64C524C61746ELLU: // ggb_Latn_LR
+ case 0x8CC641554C61746ELLU: // ggd_Latn_AU
+ case 0x90C641554C61746ELLU: // gge_Latn_AU
+ case 0x98C6504B41726162LLU: // ggg_Arab_PK
+ case 0xA8C641554C61746ELLU: // ggk_Latn_AU
+ case 0xACC650474C61746ELLU: // ggl_Latn_PG
+ case 0xCCC650474C61746ELLU: // ggt_Latn_PG
+ case 0xD0C643494C61746ELLU: // ggu_Latn_CI
+ case 0xD8C650474C61746ELLU: // ggw_Latn_PG
+ case 0x80E64C5941726162LLU: // gha_Arab_LY
+ case 0x88E647424C61746ELLU: // ghc_Latn_GB
+ case 0x90E64E5044657661LLU: // ghe_Deva_NP
+ case 0xA8E64D4D4C61746ELLU: // ghk_Latn_MM
+ case 0xB4E653424C61746ELLU: // ghn_Latn_SB
+ case 0xB8E64D4154666E67LLU: // gho_Tfng_MA
+ case 0xC4E6504B41726162LLU: // ghr_Arab_PK
+ case 0xC8E650474C61746ELLU: // ghs_Latn_PG
+ case 0xCCE64E5054696274LLU: // ght_Tibt_NP
+ case 0x810641554C61746ELLU: // gia_Latn_AU
+ case 0x85064E474C61746ELLU: // gib_Latn_NG
+ case 0x89065A414C61746ELLU: // gic_Latn_ZA
+ case 0x8D06434D4C61746ELLU: // gid_Latn_CM
+ case 0x910643494C61746ELLU: // gie_Latn_CI
+ case 0x9906504B41726162LLU: // gig_Arab_PK
+ case 0x9D0641554C61746ELLU: // gih_Latn_AU
+ case 0xAD064B494C61746ELLU: // gil_Latn_KI
+ case 0xB10650474C61746ELLU: // gim_Latn_PG
+ case 0xB50652554379726CLLU: // gin_Cyrl_RU
+ case 0xBD0650474C61746ELLU: // gip_Latn_PG
+ case 0xC106564E4C61746ELLU: // giq_Latn_VN
+ case 0xC506564E4C61746ELLU: // gir_Latn_VN
+ case 0xC906434D4C61746ELLU: // gis_Latn_CM
+ case 0xCD0643414C61746ELLU: // git_Latn_CA
+ case 0xDD0643444C61746ELLU: // gix_Latn_CD
+ case 0xE10641554C61746ELLU: // giy_Latn_AU
+ case 0xE506434D4C61746ELLU: // giz_Latn_CM
+ case 0xA926504B41726162LLU: // gjk_Arab_PK
+ case 0xB12641554C61746ELLU: // gjm_Latn_AU
+ case 0xB52647484C61746ELLU: // gjn_Latn_GH
+ case 0xC52641554C61746ELLU: // gjr_Latn_AU
+ case 0xD126504B41726162LLU: // gju_Arab_PK
+ case 0x814650474C61746ELLU: // gka_Latn_PG
+ case 0x8D4650474C61746ELLU: // gkd_Latn_PG
+ case 0x9146434D4C61746ELLU: // gke_Latn_CM
+ case 0xB5464E474C61746ELLU: // gkn_Latn_NG
+ case 0xB94641554C61746ELLU: // gko_Latn_AU
+ case 0xBD46474E4C61746ELLU: // gkp_Latn_GN
+ case 0xD1465A414C61746ELLU: // gku_Latn_ZA
+ case 0x676C45534C61746ELLU: // gl_Latn_ES
+ case 0x85664E474C61746ELLU: // glb_Latn_NG
+ case 0x896654444C61746ELLU: // glc_Latn_TD
+ case 0x8D6652554379726CLLU: // gld_Cyrl_RU
+ case 0x9D66414641726162LLU: // glh_Arab_AF
+ case 0xA56654444C61746ELLU: // glj_Latn_TD
+ case 0xA966495241726162LLU: // glk_Arab_IR
+ case 0xAD6641554C61746ELLU: // gll_Latn_AU
+ case 0xB9664E474C61746ELLU: // glo_Latn_NG
+ case 0xC5664C524C61746ELLU: // glr_Latn_LR
+ case 0xD16654444C61746ELLU: // glu_Latn_TD
+ case 0xD9664E474C61746ELLU: // glw_Latn_NG
+ case 0x818641554C61746ELLU: // gma_Latn_AU
+ case 0x858653424C61746ELLU: // gmb_Latn_SB
+ case 0x8D864E474C61746ELLU: // gmd_Latn_NG
+ case 0x998650474C61746ELLU: // gmg_Latn_PG
+ case 0x9D8644454C61746ELLU: // gmh_Latn_DE
+ case 0xAD8644454C617466LLU: // gml_Latf_DE
+ case 0xB186434D4C61746ELLU: // gmm_Latn_CM
+ case 0xB586434D4C61746ELLU: // gmn_Latn_CM
+ case 0xC58641554C61746ELLU: // gmr_Latn_AU
+ case 0xD18650474C61746ELLU: // gmu_Latn_PG
+ case 0xD586455445746869LLU: // gmv_Ethi_ET
+ case 0xDD86545A4C61746ELLU: // gmx_Latn_TZ
+ case 0xE18647524C696E62LLU: // gmy_Linb_GR
+ case 0xE5864E474C61746ELLU: // gmz_Latn_NG
+ case 0x676E50594C61746ELLU: // gn_Latn_PY
+ case 0x81A642464C61746ELLU: // gna_Latn_BF
+ case 0x85A6494E4C61746ELLU: // gnb_Latn_IN
+ case 0x89A645534C61746ELLU: // gnc_Latn_ES
+ case 0x8DA6434D4C61746ELLU: // gnd_Latn_CM
+ case 0x91A64E474C61746ELLU: // gne_Latn_NG
+ case 0x99A654474C61746ELLU: // gng_Latn_TG
+ case 0x9DA64E474C61746ELLU: // gnh_Latn_NG
+ case 0xA1A641554C61746ELLU: // gni_Latn_AU
+ case 0xA5A643494C61746ELLU: // gnj_Latn_CI
+ case 0xA9A642574C61746ELLU: // gnk_Latn_BW
+ case 0xADA641554C61746ELLU: // gnl_Latn_AU
+ case 0xB1A650474C61746ELLU: // gnm_Latn_PG
+ case 0xB5A641554C61746ELLU: // gnn_Latn_AU
+ case 0xC1A64D594C61746ELLU: // gnq_Latn_MY
+ case 0xC5A641554C61746ELLU: // gnr_Latn_AU
+ case 0xCDA650474C61746ELLU: // gnt_Latn_PG
+ case 0xD1A650474C61746ELLU: // gnu_Latn_PG
+ case 0xD9A6424F4C61746ELLU: // gnw_Latn_BO
+ case 0xE5A643464C61746ELLU: // gnz_Latn_CF
+ case 0x81C643494C61746ELLU: // goa_Latn_CI
+ case 0x85C6434F4C61746ELLU: // gob_Latn_CO
+ case 0x89C650474C61746ELLU: // goc_Latn_PG
+ case 0x8DC643494C61746ELLU: // god_Latn_CI
+ case 0x91C6425454696274LLU: // goe_Tibt_BT
+ case 0x95C6455445746869LLU: // gof_Ethi_ET
+ case 0x99C6545A4C61746ELLU: // gog_Latn_TZ
+ case 0x9DC644454C61746ELLU: // goh_Latn_DE
+ case 0xA1C650474C61746ELLU: // goi_Latn_PG
+ case 0xA5C6494E44657661LLU: // goj_Deva_IN
+ case 0xA9C6494E44657661LLU: // gok_Deva_IN
+ case 0xADC64C524C61746ELLU: // gol_Latn_LR
+ case 0xB5C6494E44657661LLU: // gon_Deva_IN
+ case 0xB9C6464A4C61746ELLU: // goo_Latn_FJ
+ case 0xBDC649444C61746ELLU: // gop_Latn_ID
+ case 0xC1C649444C61746ELLU: // goq_Latn_ID
+ case 0xC5C649444C61746ELLU: // gor_Latn_ID
+ case 0xC9C64E4C4C61746ELLU: // gos_Latn_NL
+ case 0xCDC65541476F7468LLU: // got_Goth_UA
+ case 0xD1C6434D4C61746ELLU: // gou_Latn_CM
+ case 0xD5C643494C61746ELLU: // gov_Latn_CI
+ case 0xD9C6545A4C61746ELLU: // gow_Latn_TZ
+ case 0xDDC643444C61746ELLU: // gox_Latn_CD
+ case 0xE1C654444C61746ELLU: // goy_Latn_TD
+ case 0x81E64E474C61746ELLU: // gpa_Latn_NG
+ case 0x91E647484C61746ELLU: // gpe_Latn_GH
+ case 0xB5E650474C61746ELLU: // gpn_Latn_PG
+ case 0x82064E474C61746ELLU: // gqa_Latn_NG
+ case 0xB60642524C61746ELLU: // gqn_Latn_BR
+ case 0xC60654444C61746ELLU: // gqr_Latn_TD
+ case 0x8226494E44657661LLU: // gra_Deva_IN
+ case 0x86264C524C61746ELLU: // grb_Latn_LR
+ case 0x8A26435943707274LLU: // grc_Cprt_CY
+ case 0x8A2647524C696E62LLU: // grc_Linb_GR
+ case 0x8E264E474C61746ELLU: // grd_Latn_NG
+ case 0x9A2650474C61746ELLU: // grg_Latn_PG
+ case 0x9E264E474C61746ELLU: // grh_Latn_NG
+ case 0xA22653424C61746ELLU: // gri_Latn_SB
+ case 0xA6264C524C61746ELLU: // grj_Latn_LR
+ case 0xB2264D594C61746ELLU: // grm_Latn_MY
+ case 0xC22650474C61746ELLU: // grq_Latn_PG
+ case 0xCA2649444C61746ELLU: // grs_Latn_ID
+ case 0xCE26494E42656E67LLU: // grt_Beng_IN
+ case 0xD226455445746869LLU: // gru_Ethi_ET
+ case 0xD6264C524C61746ELLU: // grv_Latn_LR
+ case 0xDA2650474C61746ELLU: // grw_Latn_PG
+ case 0xDE2650474C61746ELLU: // grx_Latn_PG
+ case 0xE2264C524C61746ELLU: // gry_Latn_LR
+ case 0xE62650474C61746ELLU: // grz_Latn_PG
+ case 0xAE46534E4C61746ELLU: // gsl_Latn_SN
+ case 0xB64650474C61746ELLU: // gsn_Latn_PG
+ case 0xBA4643464C61746ELLU: // gso_Latn_CF
+ case 0xBE4650474C61746ELLU: // gsp_Latn_PG
+ case 0xDA4643484C61746ELLU: // gsw_Latn_CH
+ case 0x826642524C61746ELLU: // gta_Latn_BR
+ case 0xD26641554C61746ELLU: // gtu_Latn_AU
+ case 0x6775494E47756A72LLU: // gu_Gujr_IN
+ case 0x82864E474C61746ELLU: // gua_Latn_NG
+ case 0x868642524C61746ELLU: // gub_Latn_BR
+ case 0x8A86434F4C61746ELLU: // guc_Latn_CO
+ case 0x8E8643494C61746ELLU: // gud_Latn_CI
+ case 0x928641554C61746ELLU: // gue_Latn_AU
+ case 0x968641554C61746ELLU: // guf_Latn_AU
+ case 0x9E86434F4C61746ELLU: // guh_Latn_CO
+ case 0xA286424F4C61746ELLU: // gui_Latn_BO
+ case 0xAA8645544C61746ELLU: // guk_Latn_ET
+ case 0xAE8655534C61746ELLU: // gul_Latn_US
+ case 0xB286434F4C61746ELLU: // gum_Latn_CO
+ case 0xB68642524C61746ELLU: // gun_Latn_BR
+ case 0xBA86434F4C61746ELLU: // guo_Latn_CO
+ case 0xBE8641554C61746ELLU: // gup_Latn_AU
+ case 0xC28650594C61746ELLU: // guq_Latn_PY
+ case 0xC68647484C61746ELLU: // gur_Latn_GH
+ case 0xCE8643524C61746ELLU: // gut_Latn_CR
+ case 0xD28656454C61746ELLU: // guu_Latn_VE
+ case 0xDA86424A4C61746ELLU: // guw_Latn_BJ
+ case 0xDE8642464C61746ELLU: // gux_Latn_BF
+ case 0xE6864B454C61746ELLU: // guz_Latn_KE
+ case 0x6776494D4C61746ELLU: // gv_Latn_IM
+ case 0x82A650594C61746ELLU: // gva_Latn_PY
+ case 0x8AA642524C61746ELLU: // gvc_Latn_BR
+ case 0x92A650474C61746ELLU: // gve_Latn_PG
+ case 0x96A650474C61746ELLU: // gvf_Latn_PG
+ case 0xA6A642524C61746ELLU: // gvj_Latn_BR
+ case 0xAEA654444C61746ELLU: // gvl_Latn_TD
+ case 0xB2A64E474C61746ELLU: // gvm_Latn_NG
+ case 0xB6A641554C61746ELLU: // gvn_Latn_AU
+ case 0xBAA642524C61746ELLU: // gvo_Latn_BR
+ case 0xBEA642524C61746ELLU: // gvp_Latn_BR
+ case 0xC6A64E5044657661LLU: // gvr_Deva_NP
+ case 0xCAA650474C61746ELLU: // gvs_Latn_PG
+ case 0xE2A641554C61746ELLU: // gvy_Latn_AU
+ case 0x82C643494C61746ELLU: // gwa_Latn_CI
+ case 0x86C64E474C61746ELLU: // gwb_Latn_NG
+ case 0x8AC6504B41726162LLU: // gwc_Arab_PK
+ case 0x8EC645544C61746ELLU: // gwd_Latn_ET
+ case 0x92C6545A4C61746ELLU: // gwe_Latn_TZ
+ case 0x96C6504B41726162LLU: // gwf_Arab_PK
+ case 0x9AC64E474C61746ELLU: // gwg_Latn_NG
+ case 0xA2C643414C61746ELLU: // gwi_Latn_CA
+ case 0xA6C642574C61746ELLU: // gwj_Latn_BW
+ case 0xB2C641554C61746ELLU: // gwm_Latn_AU
+ case 0xB6C64E474C61746ELLU: // gwn_Latn_NG
+ case 0xC6C655474C61746ELLU: // gwr_Latn_UG
+ case 0xCEC6414641726162LLU: // gwt_Arab_AF
+ case 0xD2C641554C61746ELLU: // gwu_Latn_AU
+ case 0xDAC641554C61746ELLU: // gww_Latn_AU
+ case 0xDEC647484C61746ELLU: // gwx_Latn_GH
+ case 0xDEE643494C61746ELLU: // gxx_Latn_CI
+ case 0x870650474C61746ELLU: // gyb_Latn_PG
+ case 0x8F0641554C61746ELLU: // gyd_Latn_AU
+ case 0x93064E474C61746ELLU: // gye_Latn_NG
+ case 0x970641554C61746ELLU: // gyf_Latn_AU
+ case 0x9B0643464C61746ELLU: // gyg_Latn_CF
+ case 0xA306434D4C61746ELLU: // gyi_Latn_CM
+ case 0xAF0645544C61746ELLU: // gyl_Latn_ET
+ case 0xB30650414C61746ELLU: // gym_Latn_PA
+ case 0xB70647594C61746ELLU: // gyn_Latn_GY
+ case 0xBB064E5044657661LLU: // gyo_Deva_NP
+ case 0xC706424F4C61746ELLU: // gyr_Latn_BO
+ case 0xE30641554C61746ELLU: // gyy_Latn_AU
+ case 0xE7064E474C61746ELLU: // gyz_Latn_NG
+ case 0x832653444C61746ELLU: // gza_Latn_SD
+ case 0xA326495241726162LLU: // gzi_Arab_IR
+ case 0xB72649444C61746ELLU: // gzn_Latn_ID
+ case 0x68614E474C61746ELLU: // ha_Latn_NG
+ case 0x800755534C61746ELLU: // haa_Latn_US
+ case 0x8807495241726162LLU: // hac_Arab_IR
+ case 0x8C0749444C61746ELLU: // had_Latn_ID
+ case 0x900745544C61746ELLU: // hae_Latn_ET
+ case 0x980747484C61746ELLU: // hag_Latn_GH
+ case 0x9C0750474C61746ELLU: // hah_Latn_PG
+ case 0xA00743414C61746ELLU: // hai_Latn_CA
+ case 0xA407494E4C61746ELLU: // haj_Latn_IN
+ case 0xA807434E48616E73LLU: // hak_Hans_CN
+ case 0xAC07564E4C61746ELLU: // hal_Latn_VN
+ case 0xB00750474C61746ELLU: // ham_Latn_PG
+ case 0xB407545A4C61746ELLU: // han_Latn_TZ
+ case 0xB80750474C61746ELLU: // hao_Latn_PG
+ case 0xBC0749444C61746ELLU: // hap_Latn_ID
+ case 0xC007545A4C61746ELLU: // haq_Latn_TZ
+ case 0xC407455445746869LLU: // har_Ethi_ET
+ case 0xC80743414C61746ELLU: // has_Latn_CA
+ case 0xD40743444C61746ELLU: // hav_Latn_CD
+ case 0xD80755534C61746ELLU: // haw_Latn_US
+ case 0xDC0743414C61746ELLU: // hax_Latn_CA
+ case 0xE007545A4C61746ELLU: // hay_Latn_TZ
+ case 0xE407414641726162LLU: // haz_Arab_AF
+ case 0x802743444C61746ELLU: // hba_Latn_CD
+ case 0x84274E474C61746ELLU: // hbb_Latn_NG
+ case 0xB42753444C61746ELLU: // hbn_Latn_SD
+ case 0xB827494C48656272LLU: // hbo_Hebr_IL
+ case 0xD027544C4C61746ELLU: // hbu_Latn_TL
+ case 0x9C474D584C61746ELLU: // hch_Latn_MX
+ case 0xE067455445746869LLU: // hdy_Ethi_ET
+ case 0x6865494C48656272LLU: // he_Hebr_IL
+ case 0x8C8754444C61746ELLU: // hed_Latn_TD
+ case 0x988749444C61746ELLU: // heg_Latn_ID
+ case 0x9C87545A4C61746ELLU: // heh_Latn_TZ
+ case 0xA08743414C61746ELLU: // hei_Latn_CA
+ case 0xB08743444C61746ELLU: // hem_Latn_CD
+ case 0xB0C74E414C61746ELLU: // hgm_Latn_NA
+ case 0xD8C750474C61746ELLU: // hgw_Latn_PG
+ case 0xA0E750474C61746ELLU: // hhi_Latn_PG
+ case 0xC4E7534E4C61746ELLU: // hhr_Latn_SN
+ case 0xE0E750474C61746ELLU: // hhy_Latn_PG
+ case 0x6869494E44657661LLU: // hi_Deva_IN
+ case 0x81074E474C61746ELLU: // hia_Latn_NG
+ case 0x850750454C61746ELLU: // hib_Latn_PE
+ case 0x8D0755534C61746ELLU: // hid_Latn_US
+ case 0x9507464A44657661LLU: // hif_Deva_FJ
+ case 0x99074E474C61746ELLU: // hig_Latn_NG
+ case 0x9D0750474C61746ELLU: // hih_Latn_PG
+ case 0xA107494E54616B72LLU: // hii_Takr_IN
+ case 0xA507434D4C61746ELLU: // hij_Latn_CM
+ case 0xA90749444C61746ELLU: // hik_Latn_ID
+ case 0xAD0750484C61746ELLU: // hil_Latn_PH
+ case 0xB90742574C61746ELLU: // hio_Latn_BW
+ case 0xC50742524C61746ELLU: // hir_Latn_BR
+ case 0xCD07545258737578LLU: // hit_Xsux_TR
+ case 0xD90756554C61746ELLU: // hiw_Latn_VU
+ case 0xDD0742524C61746ELLU: // hix_Latn_BR
+ case 0xA12749444C61746ELLU: // hji_Latn_ID
+ case 0x8147545A4C61746ELLU: // hka_Latn_TZ
+ case 0x914743444C61746ELLU: // hke_Latn_CD
+ case 0x9D47494E41726162LLU: // hkh_Arab_IN
+ case 0xA94750474C61746ELLU: // hkk_Latn_PG
+ case 0x816750474C61746ELLU: // hla_Latn_PG
+ case 0x8567494E44657661LLU: // hlb_Deva_IN
+ case 0x8D67564E4C61746ELLU: // hld_Latn_VN
+ case 0xCD674D4D4C61746ELLU: // hlt_Latn_MM
+ case 0xD1675452486C7577LLU: // hlu_Hluw_TR
+ case 0x8187434E4C61746ELLU: // hma_Latn_CN
+ case 0x85874D4C4C61746ELLU: // hmb_Latn_ML
+ case 0x8D87434E506C7264LLU: // hmd_Plrd_CN
+ case 0x9587564E4C61746ELLU: // hmf_Latn_VN
+ case 0xA587434E426F706FLLU: // hmj_Bopo_CN
+ case 0xB187434E4C61746ELLU: // hmm_Latn_CN
+ case 0xB587434E4C61746ELLU: // hmn_Latn_CN
+ case 0xBD87434E4C61746ELLU: // hmp_Latn_CN
+ case 0xC187434E426F706FLLU: // hmq_Bopo_CN
+ case 0xC587494E4C61746ELLU: // hmr_Latn_IN
+ case 0xC987434E4C61746ELLU: // hms_Latn_CN
+ case 0xCD8750474C61746ELLU: // hmt_Latn_PG
+ case 0xD18749444C61746ELLU: // hmu_Latn_ID
+ case 0xD587564E4C61746ELLU: // hmv_Latn_VN
+ case 0xD987434E4C61746ELLU: // hmw_Latn_CN
+ case 0xE187434E4C61746ELLU: // hmy_Latn_CN
+ case 0xE587434E4C61746ELLU: // hmz_Latn_CN
+ case 0x81A7434D4C61746ELLU: // hna_Latn_CM
+ case 0x8DA7504B41726162LLU: // hnd_Arab_PK
+ case 0x91A7494E44657661LLU: // hne_Deva_IN
+ case 0x99A7414F4C61746ELLU: // hng_Latn_AO
+ case 0x9DA742574C61746ELLU: // hnh_Latn_BW
+ case 0xA1A7434E4C61746ELLU: // hni_Latn_CN
+ case 0xA5A74C41486D6E67LLU: // hnj_Hmng_LA
+ case 0xA5A75553486D6E70LLU: // hnj_Hmnp_US
+ case 0xB5A750484C61746ELLU: // hnn_Latn_PH
+ case 0xB9A7504B41726162LLU: // hno_Arab_PK
+ case 0xC9A753524C61746ELLU: // hns_Latn_SR
+ case 0x686F50474C61746ELLU: // ho_Latn_PG
+ case 0x81C753424C61746ELLU: // hoa_Latn_SB
+ case 0x85C750474C61746ELLU: // hob_Latn_PG
+ case 0x89C7494E44657661LLU: // hoc_Deva_IN
+ case 0x8DC74E474C61746ELLU: // hod_Latn_NG
+ case 0x91C74E474C61746ELLU: // hoe_Latn_NG
+ case 0x9DC74F4D41726162LLU: // hoh_Arab_OM
+ case 0xA1C755534C61746ELLU: // hoi_Latn_US
+ case 0xA5C7494E44657661LLU: // hoj_Deva_IN
+ case 0xADC7414F4C61746ELLU: // hol_Latn_AO
+ case 0xB1C753534C61746ELLU: // hom_Latn_SS
+ case 0xB9C743444C61746ELLU: // hoo_Latn_CD
+ case 0xBDC755534C61746ELLU: // hop_Latn_US
+ case 0xC5C754444C61746ELLU: // hor_Latn_TD
+ case 0xCDC750474C61746ELLU: // hot_Latn_PG
+ case 0xD5C749444C61746ELLU: // hov_Latn_ID
+ case 0xD9C7434E48616E69LLU: // how_Hani_CN
+ case 0xE1C7494E44657661LLU: // hoy_Deva_IN
+ case 0xB9E74D4D4D796D72LLU: // hpo_Mymr_MM
+ case 0x687248524C61746ELLU: // hr_Latn_HR
+ case 0x8227494E4C61746ELLU: // hra_Latn_IN
+ case 0x8A2750474C61746ELLU: // hrc_Latn_PG
+ case 0x9227564E4C61746ELLU: // hre_Latn_VN
+ case 0xAA2749444C61746ELLU: // hrk_Latn_ID
+ case 0xB227434E4C61746ELLU: // hrm_Latn_CN
+ case 0xBA27564E4C61746ELLU: // hro_Latn_VN
+ case 0xBE2741554C61746ELLU: // hrp_Latn_AU
+ case 0xCE27545253797263LLU: // hrt_Syrc_TR
+ case 0xD227494E4C61746ELLU: // hru_Latn_IN
+ case 0xDA2750474C61746ELLU: // hrw_Latn_PG
+ case 0xDE2742524C61746ELLU: // hrx_Latn_BR
+ case 0xE627495241726162LLU: // hrz_Arab_IR
+ case 0x864744454C61746ELLU: // hsb_Latn_DE
+ case 0xB647434E48616E73LLU: // hsn_Hans_CN
+ case 0xCA474F4D41726162LLU: // hss_Arab_OM
+ case 0x687448544C61746ELLU: // ht_Latn_HT
+ case 0xA26749444C61746ELLU: // hti_Latn_ID
+ case 0xBA67434F4C61746ELLU: // hto_Latn_CO
+ case 0xCA67545A4C61746ELLU: // hts_Latn_TZ
+ case 0xD26749444C61746ELLU: // htu_Latn_ID
+ case 0xDE67545258737578LLU: // htx_Xsux_TR
+ case 0x687548554C61746ELLU: // hu_Latn_HU
+ case 0x868750454C61746ELLU: // hub_Latn_PE
+ case 0x8A8742574C61746ELLU: // huc_Latn_BW
+ case 0x8E8749444C61746ELLU: // hud_Latn_ID
+ case 0x92874D584C61746ELLU: // hue_Latn_MX
+ case 0x968750474C61746ELLU: // huf_Latn_PG
+ case 0x9A8750454C61746ELLU: // hug_Latn_PE
+ case 0x9E87434C4C61746ELLU: // huh_Latn_CL
+ case 0xA28750474C61746ELLU: // hui_Latn_PG
+ case 0xAA8749444C61746ELLU: // huk_Latn_ID
+ case 0xAE8750474C61746ELLU: // hul_Latn_PG
+ case 0xB28743444C61746ELLU: // hum_Latn_CD
+ case 0xBE8755534C61746ELLU: // hup_Latn_US
+ case 0xC68743414C61746ELLU: // hur_Latn_CA
+ case 0xCA874D584C61746ELLU: // hus_Latn_MX
+ case 0xCE874E5044657661LLU: // hut_Deva_NP
+ case 0xD28750454C61746ELLU: // huu_Latn_PE
+ case 0xD6874D584C61746ELLU: // huv_Latn_MX
+ case 0xDA8749444C61746ELLU: // huw_Latn_ID
+ case 0xDE8750454C61746ELLU: // hux_Latn_PE
+ case 0xE287494C48656272LLU: // huy_Hebr_IL
+ case 0xE68752554379726CLLU: // huz_Cyrl_RU
+ case 0x8AA748544C61746ELLU: // hvc_Latn_HT
+ case 0x92A74D584C61746ELLU: // hve_Latn_MX
+ case 0xAAA74E434C61746ELLU: // hvk_Latn_NC
+ case 0xB6A749444C61746ELLU: // hvn_Latn_ID
+ case 0xD6A74D584C61746ELLU: // hvv_Latn_MX
+ case 0x82C743494C61746ELLU: // hwa_Latn_CI
+ case 0x8AC755534C61746ELLU: // hwc_Latn_US
+ case 0xBAC74E474C61746ELLU: // hwo_Latn_NG
+ case 0x6879414D41726D6ELLU: // hy_Armn_AM
+ case 0x8307434D4C61746ELLU: // hya_Latn_CM
+ case 0xDB07414D41726D6ELLU: // hyw_Armn_AM
+ case 0x687A4E414C61746ELLU: // hz_Latn_NA
+ case 0xA0084E434C61746ELLU: // iai_Latn_NC
+ case 0xB40850474C61746ELLU: // ian_Latn_PG
+ case 0xC40850474C61746ELLU: // iar_Latn_PG
+ case 0x80284D594C61746ELLU: // iba_Latn_MY
+ case 0x84284E474C61746ELLU: // ibb_Latn_NG
+ case 0x8C2841554C61746ELLU: // ibd_Latn_AU
+ case 0x90284E474C61746ELLU: // ibe_Latn_NG
+ case 0x982850484C61746ELLU: // ibg_Latn_PH
+ case 0x9C28564E4C61746ELLU: // ibh_Latn_VN
+ case 0xAC2850484C61746ELLU: // ibl_Latn_PH
+ case 0xB0284E474C61746ELLU: // ibm_Latn_NG
+ case 0xB4284E474C61746ELLU: // ibn_Latn_NG
+ case 0xC4284E474C61746ELLU: // ibr_Latn_NG
+ case 0xD02849444C61746ELLU: // ibu_Latn_ID
+ case 0xE0284E474C61746ELLU: // iby_Latn_NG
+ case 0x8048424A4C61746ELLU: // ica_Latn_BJ
+ case 0x9C484E474C61746ELLU: // ich_Latn_NG
+ case 0xC448434F4C61746ELLU: // icr_Latn_CO
+ case 0x696449444C61746ELLU: // id_Latn_ID
+ case 0x80684B454C61746ELLU: // ida_Latn_KE
+ case 0x8468494E4C61746ELLU: // idb_Latn_IN
+ case 0x88684E474C61746ELLU: // idc_Latn_NG
+ case 0x8C68424A4C61746ELLU: // idd_Latn_BJ
+ case 0x90684E474C61746ELLU: // ide_Latn_NG
+ case 0xA06850474C61746ELLU: // idi_Latn_PG
+ case 0xC46853534C61746ELLU: // idr_Latn_SS
+ case 0xC8684E474C61746ELLU: // ids_Latn_NG
+ case 0xCC68544C4C61746ELLU: // idt_Latn_TL
+ case 0xD0684E474C61746ELLU: // idu_Latn_NG
+ case 0x696545454C61746ELLU: // ie_Latn_EE
+ case 0x80A850484C61746ELLU: // ifa_Latn_PH
+ case 0x84A850484C61746ELLU: // ifb_Latn_PH
+ case 0x90A854474C61746ELLU: // ife_Latn_TG
+ case 0x94A856554C61746ELLU: // iff_Latn_VU
+ case 0xA8A850484C61746ELLU: // ifk_Latn_PH
+ case 0xB0A843474C61746ELLU: // ifm_Latn_CG
+ case 0xD0A850484C61746ELLU: // ifu_Latn_PH
+ case 0xE0A850484C61746ELLU: // ify_Latn_PH
+ case 0x69674E474C61746ELLU: // ig_Latn_NG
+ case 0x84C84E474C61746ELLU: // igb_Latn_NG
+ case 0x90C84E474C61746ELLU: // ige_Latn_NG
+ case 0x98C850474C61746ELLU: // igg_Latn_PG
+ case 0xACC84E474C61746ELLU: // igl_Latn_NG
+ case 0xB0C850474C61746ELLU: // igm_Latn_PG
+ case 0xB4C8424F4C61746ELLU: // ign_Latn_BO
+ case 0xB8C850474C61746ELLU: // igo_Latn_PG
+ case 0xD8C84E474C61746ELLU: // igw_Latn_NG
+ case 0x84E849444C61746ELLU: // ihb_Latn_ID
+ case 0xA0E84E474C61746ELLU: // ihi_Latn_NG
+ case 0xBCE849444C61746ELLU: // ihp_Latn_ID
+ case 0xD8E841554C61746ELLU: // ihw_Latn_AU
+ case 0x6969434E59696969LLU: // ii_Yiii_CN
+ case 0xB50841554C61746ELLU: // iin_Latn_AU
+ case 0x89284E474C61746ELLU: // ijc_Latn_NG
+ case 0x91284E474C61746ELLU: // ije_Latn_NG
+ case 0xA528424A4C61746ELLU: // ijj_Latn_BJ
+ case 0xB5284E474C61746ELLU: // ijn_Latn_NG
+ case 0xC9284E474C61746ELLU: // ijs_Latn_NG
+ case 0x696B55534C61746ELLU: // ik_Latn_US
+ case 0x9D484E474C61746ELLU: // ikh_Latn_NG
+ case 0xA1484E474C61746ELLU: // iki_Latn_NG
+ case 0xA9484E474C61746ELLU: // ikk_Latn_NG
+ case 0xAD484E474C61746ELLU: // ikl_Latn_NG
+ case 0xB9484E474C61746ELLU: // iko_Latn_NG
+ case 0xBD484E474C61746ELLU: // ikp_Latn_NG
+ case 0xC54841554C61746ELLU: // ikr_Latn_AU
+ case 0xCD4843414C61746ELLU: // ikt_Latn_CA
+ case 0xD5484E474C61746ELLU: // ikv_Latn_NG
+ case 0xD9484E474C61746ELLU: // ikw_Latn_NG
+ case 0xDD4855474C61746ELLU: // ikx_Latn_UG
+ case 0xE548545A4C61746ELLU: // ikz_Latn_TZ
+ case 0x816849444C61746ELLU: // ila_Latn_ID
+ case 0x85685A4D4C61746ELLU: // ilb_Latn_ZM
+ case 0x996841554C61746ELLU: // ilg_Latn_AU
+ case 0xA168434E4C61746ELLU: // ili_Latn_CN
+ case 0xA96850484C61746ELLU: // ilk_Latn_PH
+ case 0xB1684D594C61746ELLU: // ilm_Latn_MY
+ case 0xB96850484C61746ELLU: // ilo_Latn_PH
+ case 0xBD6850484C61746ELLU: // ilp_Latn_PH
+ case 0xD16849444C61746ELLU: // ilu_Latn_ID
+ case 0xD5684E474C61746ELLU: // ilv_Latn_NG
+ case 0xA18850474C61746ELLU: // imi_Latn_PG
+ case 0xAD8855534C61746ELLU: // iml_Latn_US
+ case 0xB58850474C61746ELLU: // imn_Latn_PG
+ case 0xB98850474C61746ELLU: // imo_Latn_PG
+ case 0xC58849444C61746ELLU: // imr_Latn_ID
+ case 0xC98849544C61746ELLU: // ims_Latn_IT
+ case 0xCD8853534C61746ELLU: // imt_Latn_SS
+ case 0xE18854524C796369LLU: // imy_Lyci_TR
+ case 0x696E49444C61746ELLU: // in_Latn_ID
+ case 0x85A8434F4C61746ELLU: // inb_Latn_CO
+ case 0x99A855534C61746ELLU: // ing_Latn_US
+ case 0x9DA852554379726CLLU: // inh_Cyrl_RU
+ case 0xA5A8434F4C61746ELLU: // inj_Latn_CO
+ case 0xB5A850484C61746ELLU: // inn_Latn_PH
+ case 0xB9A850474C61746ELLU: // ino_Latn_PG
+ case 0xBDA850454C61746ELLU: // inp_Latn_PE
+ case 0xCDA84D4D4D796D72LLU: // int_Mymr_MM
+ case 0xC5C8455445746869LLU: // ior_Ethi_ET
+ case 0xD1C850474C61746ELLU: // iou_Latn_PG
+ case 0xD9C855534C61746ELLU: // iow_Latn_US
+ case 0xA1E850474C61746ELLU: // ipi_Latn_PG
+ case 0xB9E850474C61746ELLU: // ipo_Latn_PG
+ case 0xD20850454C61746ELLU: // iqu_Latn_PE
+ case 0xDA084E474C61746ELLU: // iqw_Latn_NG
+ case 0x922849444C61746ELLU: // ire_Latn_ID
+ case 0x9E2849444C61746ELLU: // irh_Latn_ID
+ case 0xA2284E474C61746ELLU: // iri_Latn_NG
+ case 0xAA28545A4C61746ELLU: // irk_Latn_TZ
+ case 0xB62842524C61746ELLU: // irn_Latn_BR
+ case 0xD228494E54616D6CLLU: // iru_Taml_IN
+ case 0xDE2849444C61746ELLU: // irx_Latn_ID
+ case 0xE22850484C61746ELLU: // iry_Latn_PH
+ case 0x697349534C61746ELLU: // is_Latn_IS
+ case 0x824850474C61746ELLU: // isa_Latn_PG
+ case 0x8A4850454C61746ELLU: // isc_Latn_PE
+ case 0x8E4850484C61746ELLU: // isd_Latn_PH
+ case 0x9E484E474C61746ELLU: // ish_Latn_NG
+ case 0xA2484E474C61746ELLU: // isi_Latn_NG
+ case 0xAA48414641726162LLU: // isk_Arab_AF
+ case 0xB24849444C61746ELLU: // ism_Latn_ID
+ case 0xB648545A4C61746ELLU: // isn_Latn_TZ
+ case 0xBA484E474C61746ELLU: // iso_Latn_NG
+ case 0xCE4848524C61746ELLU: // ist_Latn_HR
+ case 0xD248434D4C61746ELLU: // isu_Latn_CM
+ case 0x697449544C61746ELLU: // it_Latn_IT
+ case 0x866850484C61746ELLU: // itb_Latn_PH
+ case 0x8E6849444C61746ELLU: // itd_Latn_ID
+ case 0x9268424F4C61746ELLU: // ite_Latn_BO
+ case 0xA26850484C61746ELLU: // iti_Latn_PH
+ case 0xAA68495448656272LLU: // itk_Hebr_IT
+ case 0xAE6852554379726CLLU: // itl_Cyrl_RU
+ case 0xB2684E474C61746ELLU: // itm_Latn_NG
+ case 0xBA68424F4C61746ELLU: // ito_Latn_BO
+ case 0xC66850474C61746ELLU: // itr_Latn_PG
+ case 0xCA684E474C61746ELLU: // its_Latn_NG
+ case 0xCE6850484C61746ELLU: // itt_Latn_PH
+ case 0xD66850484C61746ELLU: // itv_Latn_PH
+ case 0xDA684E474C61746ELLU: // itw_Latn_NG
+ case 0xDE6849444C61746ELLU: // itx_Latn_ID
+ case 0xE26850484C61746ELLU: // ity_Latn_PH
+ case 0xE66847544C61746ELLU: // itz_Latn_GT
+ case 0x6975434143616E73LLU: // iu_Cans_CA
+ case 0xB288434E4C61746ELLU: // ium_Latn_CN
+ case 0x86A850484C61746ELLU: // ivb_Latn_PH
+ case 0xD6A850484C61746ELLU: // ivv_Latn_PH
+ case 0x6977494C48656272LLU: // iw_Hebr_IL
+ case 0xAAC850484C61746ELLU: // iwk_Latn_PH
+ case 0xB2C850474C61746ELLU: // iwm_Latn_PG
+ case 0xBAC849444C61746ELLU: // iwo_Latn_ID
+ case 0xCAC850474C61746ELLU: // iws_Latn_PG
+ case 0x8AE84D584C61746ELLU: // ixc_Latn_MX
+ case 0xAEE847544C61746ELLU: // ixl_Latn_GT
+ case 0x83084E474C61746ELLU: // iya_Latn_NG
+ case 0xBB08434D4C61746ELLU: // iyo_Latn_CM
+ case 0xDF0843474C61746ELLU: // iyx_Latn_CG
+ case 0x9F2852554C61746ELLU: // izh_Latn_RU
+ case 0xB3284E474C61746ELLU: // izm_Latn_NG
+ case 0xC7284E474C61746ELLU: // izr_Latn_NG
+ case 0xE7284E474C61746ELLU: // izz_Latn_NG
+ case 0x6A614A504A70616ELLU: // ja_Jpan_JP
+ case 0x800942524C61746ELLU: // jaa_Latn_BR
+ case 0x84094E474C61746ELLU: // jab_Latn_NG
+ case 0x880947544C61746ELLU: // jac_Latn_GT
+ case 0x8C09474E41726162LLU: // jad_Arab_GN
+ case 0x900950474C61746ELLU: // jae_Latn_PG
+ case 0x94094E474C61746ELLU: // jaf_Latn_NG
+ case 0x9C094D594C61746ELLU: // jah_Latn_MY
+ case 0xA40953424C61746ELLU: // jaj_Latn_SB
+ case 0xA8094D594C61746ELLU: // jak_Latn_MY
+ case 0xAC0949444C61746ELLU: // jal_Latn_ID
+ case 0xB0094A4D4C61746ELLU: // jam_Latn_JM
+ case 0xB40941554C61746ELLU: // jan_Latn_AU
+ case 0xB80941554C61746ELLU: // jao_Latn_AU
+ case 0xC00949444C61746ELLU: // jaq_Latn_ID
+ case 0xC8094E434C61746ELLU: // jas_Latn_NC
+ case 0xCC09414641726162LLU: // jat_Arab_AF
+ case 0xD00949444C61746ELLU: // jau_Latn_ID
+ case 0xDC0949444C61746ELLU: // jax_Latn_ID
+ case 0xE00941554C61746ELLU: // jay_Latn_AU
+ case 0xE4094E434C61746ELLU: // jaz_Latn_NC
+ case 0x9029494C48656272LLU: // jbe_Hebr_IL
+ case 0xA02941554C61746ELLU: // jbi_Latn_AU
+ case 0xA42949444C61746ELLU: // jbj_Latn_ID
+ case 0xA82950474C61746ELLU: // jbk_Latn_PG
+ case 0xB0294E474C61746ELLU: // jbm_Latn_NG
+ case 0xB4294C5941726162LLU: // jbn_Arab_LY
+ case 0xC42949444C61746ELLU: // jbr_Latn_ID
+ case 0xCC2942524C61746ELLU: // jbt_Latn_BR
+ case 0xD029434D4C61746ELLU: // jbu_Latn_CM
+ case 0xD82941554C61746ELLU: // jbw_Latn_AU
+ case 0xCC4955414379726CLLU: // jct_Cyrl_UA
+ case 0x8069494E54696274LLU: // jda_Tibt_IN
+ case 0x9869504B41726162LLU: // jdg_Arab_PK
+ case 0xCC6952554379726CLLU: // jdt_Cyrl_RU
+ case 0x848950454C61746ELLU: // jeb_Latn_PE
+ case 0x90894E5044657661LLU: // jee_Deva_NP
+ case 0x9C89564E4C61746ELLU: // jeh_Latn_VN
+ case 0xA08949444C61746ELLU: // jei_Latn_ID
+ case 0xA88943494C61746ELLU: // jek_Latn_CI
+ case 0xAC8949444C61746ELLU: // jel_Latn_ID
+ case 0xB4894E474C61746ELLU: // jen_Latn_NG
+ case 0xC4894E474C61746ELLU: // jer_Latn_NG
+ case 0xCC8950474C61746ELLU: // jet_Latn_PG
+ case 0xD08954444C61746ELLU: // jeu_Latn_TD
+ case 0x84C943444C61746ELLU: // jgb_Latn_CD
+ case 0x90C9474547656F72LLU: // jge_Geor_GE
+ case 0xA8C94E474C61746ELLU: // jgk_Latn_NG
+ case 0xB8C9434D4C61746ELLU: // jgo_Latn_CM
+ case 0xA0E94D594C61746ELLU: // jhi_Latn_MY
+ case 0x6A69554148656272LLU: // ji_Hebr_UA
+ case 0x8109434D4C61746ELLU: // jia_Latn_CM
+ case 0x85094E474C61746ELLU: // jib_Latn_NG
+ case 0x8909484E4C61746ELLU: // jic_Latn_HN
+ case 0x8D094E474C61746ELLU: // jid_Latn_NG
+ case 0x91094E474C61746ELLU: // jie_Latn_NG
+ case 0x990941554C61746ELLU: // jig_Latn_AU
+ case 0xAD0950474C61746ELLU: // jil_Latn_PG
+ case 0xB109434D4C61746ELLU: // jim_Latn_CM
+ case 0xCD09545A4C61746ELLU: // jit_Latn_TZ
+ case 0xD109434E4C61746ELLU: // jiu_Latn_CN
+ case 0xD50945434C61746ELLU: // jiv_Latn_EC
+ case 0xE109434E4C61746ELLU: // jiy_Latn_CN
+ case 0x91294B5248616E67LLU: // jje_Hang_KR
+ case 0xC5294E474C61746ELLU: // jjr_Latn_NG
+ case 0x814949444C61746ELLU: // jka_Latn_ID
+ case 0xB1494D4D4D796D72LLU: // jkm_Mymr_MM
+ case 0xB94950474C61746ELLU: // jko_Latn_PG
+ case 0xD1494E474C61746ELLU: // jku_Latn_NG
+ case 0x916953444C61746ELLU: // jle_Latn_SD
+ case 0x818950474C61746ELLU: // jma_Latn_PG
+ case 0x85894E474C61746ELLU: // jmb_Latn_NG
+ case 0x8989545A4C61746ELLU: // jmc_Latn_TZ
+ case 0x8D8949444C61746ELLU: // jmd_Latn_ID
+ case 0xA1894E474C61746ELLU: // jmi_Latn_NG
+ case 0xAD894E5044657661LLU: // jml_Deva_NP
+ case 0xB5894D4D4C61746ELLU: // jmn_Latn_MM
+ case 0xC58947484C61746ELLU: // jmr_Latn_GH
+ case 0xC9894E474C61746ELLU: // jms_Latn_NG
+ case 0xD98950474C61746ELLU: // jmw_Latn_PG
+ case 0xDD894D584C61746ELLU: // jmx_Latn_MX
+ case 0x81A9494E54616B72LLU: // jna_Takr_IN
+ case 0x8DA9504B41726162LLU: // jnd_Arab_PK
+ case 0x99A941554C61746ELLU: // jng_Latn_AU
+ case 0xA1A94E474C61746ELLU: // jni_Latn_NG
+ case 0xA5A945544C61746ELLU: // jnj_Latn_ET
+ case 0xADA9494E44657661LLU: // jnl_Deva_IN
+ case 0xC9A9494E44657661LLU: // jns_Deva_IN
+ case 0x85C943444C61746ELLU: // job_Latn_CD
+ case 0x8DC943494C61746ELLU: // jod_Latn_CI
+ case 0x99C9504B41726162LLU: // jog_Arab_PK
+ case 0xC5C9424F4C61746ELLU: // jor_Latn_BO
+ case 0xD9C94D4C4C61746ELLU: // jow_Latn_ML
+ case 0x81E9505348656272LLU: // jpa_Hebr_PS
+ case 0xC5E9494C48656272LLU: // jpr_Hebr_IL
+ case 0xC60950454C61746ELLU: // jqr_Latn_PE
+ case 0x8229564E4C61746ELLU: // jra_Latn_VN
+ case 0x8629494C48656272LLU: // jrb_Hebr_IL
+ case 0xC6294E474C61746ELLU: // jrr_Latn_NG
+ case 0xCE294E474C61746ELLU: // jrt_Latn_NG
+ case 0xD22956454C61746ELLU: // jru_Latn_VE
+ case 0x828942524C61746ELLU: // jua_Latn_BR
+ case 0x86894E474C61746ELLU: // jub_Latn_NG
+ case 0x8E8943494C61746ELLU: // jud_Latn_CI
+ case 0x9E894E474C61746ELLU: // juh_Latn_NG
+ case 0xA28941554C61746ELLU: // jui_Latn_AU
+ case 0xAA894E474C61746ELLU: // juk_Latn_NG
+ case 0xAE894E5044657661LLU: // jul_Deva_NP
+ case 0xB28953444C61746ELLU: // jum_Latn_SD
+ case 0xB689494E4F727961LLU: // jun_Orya_IN
+ case 0xBA894E474C61746ELLU: // juo_Latn_NG
+ case 0xBE8942524C61746ELLU: // jup_Latn_BR
+ case 0xC68942524C61746ELLU: // jur_Latn_BR
+ case 0xCE89444B4C61746ELLU: // jut_Latn_DK
+ case 0xD2894E474C61746ELLU: // juu_Latn_NG
+ case 0xDA894E474C61746ELLU: // juw_Latn_NG
+ case 0xE289494E4F727961LLU: // juy_Orya_IN
+ case 0x6A7649444C61746ELLU: // jv_Latn_ID
+ case 0x8EA949444C61746ELLU: // jvd_Latn_ID
+ case 0xB6A953524C61746ELLU: // jvn_Latn_SR
+ case 0x6A7749444C61746ELLU: // jw_Latn_ID
+ case 0xA2C947484C61746ELLU: // jwi_Latn_GH
+ case 0x8309434E54696274LLU: // jya_Tibt_CN
+ case 0x9309494C48656272LLU: // jye_Hebr_IL
+ case 0xE30954444C61746ELLU: // jyy_Latn_TD
+ case 0x6B61474547656F72LLU: // ka_Geor_GE
+ case 0x800A555A4379726CLLU: // kaa_Cyrl_UZ
+ case 0x840A445A4C61746ELLU: // kab_Latn_DZ
+ case 0x880A4D4D4C61746ELLU: // kac_Latn_MM
+ case 0x8C0A4E474C61746ELLU: // kad_Latn_NG
+ case 0x980A4D594C61746ELLU: // kag_Latn_MY
+ case 0x9C0A43464C61746ELLU: // kah_Latn_CF
+ case 0xA00A4E474C61746ELLU: // kai_Latn_NG
+ case 0xA40A4E474C61746ELLU: // kaj_Latn_NG
+ case 0xA80A50484C61746ELLU: // kak_Latn_PH
+ case 0xB00A4B454C61746ELLU: // kam_Latn_KE
+ case 0xB80A4D4C4C61746ELLU: // kao_Latn_ML
+ case 0xBC0A52554379726CLLU: // kap_Cyrl_RU
+ case 0xC00A50454C61746ELLU: // kaq_Latn_PE
+ case 0xD40A42524C61746ELLU: // kav_Latn_BR
+ case 0xD80A49444B617769LLU: // kaw_Kawi_ID
+ case 0xDC0A49444C61746ELLU: // kax_Latn_ID
+ case 0xE00A42524C61746ELLU: // kay_Latn_BR
+ case 0x802A41554C61746ELLU: // kba_Latn_AU
+ case 0x842A42524C61746ELLU: // kbb_Latn_BR
+ case 0x882A42524C61746ELLU: // kbc_Latn_BR
+ case 0x8C2A52554379726CLLU: // kbd_Cyrl_RU
+ case 0x902A41554C61746ELLU: // kbe_Latn_AU
+ case 0x982A494E54696274LLU: // kbg_Tibt_IN
+ case 0x9C2A434F4C61746ELLU: // kbh_Latn_CO
+ case 0xA02A49444C61746ELLU: // kbi_Latn_ID
+ case 0xA42A43444C61746ELLU: // kbj_Latn_CD
+ case 0xA82A50474C61746ELLU: // kbk_Latn_PG
+ case 0xAC2A54444C61746ELLU: // kbl_Latn_TD
+ case 0xB02A50474C61746ELLU: // kbm_Latn_PG
+ case 0xB42A43464C61746ELLU: // kbn_Latn_CF
+ case 0xB82A53534C61746ELLU: // kbo_Latn_SS
+ case 0xBC2A54474C61746ELLU: // kbp_Latn_TG
+ case 0xC02A50474C61746ELLU: // kbq_Latn_PG
+ case 0xC42A45544C61746ELLU: // kbr_Latn_ET
+ case 0xC82A47414C61746ELLU: // kbs_Latn_GA
+ case 0xCC2A50474C61746ELLU: // kbt_Latn_PG
+ case 0xD02A504B41726162LLU: // kbu_Arab_PK
+ case 0xD42A49444C61746ELLU: // kbv_Latn_ID
+ case 0xD82A50474C61746ELLU: // kbw_Latn_PG
+ case 0xDC2A50474C61746ELLU: // kbx_Latn_PG
+ case 0xE02A4E4541726162LLU: // kby_Arab_NE
+ case 0xE42A4E474C61746ELLU: // kbz_Latn_NG
+ case 0x804A52554379726CLLU: // kca_Cyrl_RU
+ case 0x844A50474C61746ELLU: // kcb_Latn_PG
+ case 0x884A4E474C61746ELLU: // kcc_Latn_NG
+ case 0x8C4A49444C61746ELLU: // kcd_Latn_ID
+ case 0x904A4E474C61746ELLU: // kce_Latn_NG
+ case 0x944A4E474C61746ELLU: // kcf_Latn_NG
+ case 0x984A4E474C61746ELLU: // kcg_Latn_NG
+ case 0x9C4A4E474C61746ELLU: // kch_Latn_NG
+ case 0xA04A4E474C61746ELLU: // kci_Latn_NG
+ case 0xA44A47574C61746ELLU: // kcj_Latn_GW
+ case 0xA84A5A574C61746ELLU: // kck_Latn_ZW
+ case 0xAC4A50474C61746ELLU: // kcl_Latn_PG
+ case 0xB04A43464C61746ELLU: // kcm_Latn_CF
+ case 0xB44A55474C61746ELLU: // kcn_Latn_UG
+ case 0xB84A50474C61746ELLU: // kco_Latn_PG
+ case 0xBC4A53444C61746ELLU: // kcp_Latn_SD
+ case 0xC04A4E474C61746ELLU: // kcq_Latn_NG
+ case 0xC84A4E474C61746ELLU: // kcs_Latn_NG
+ case 0xCC4A50474C61746ELLU: // kct_Latn_PG
+ case 0xD04A545A4C61746ELLU: // kcu_Latn_TZ
+ case 0xD44A43444C61746ELLU: // kcv_Latn_CD
+ case 0xD84A43444C61746ELLU: // kcw_Latn_CD
+ case 0xE04A445A41726162LLU: // kcy_Arab_DZ
+ case 0xE44A545A4C61746ELLU: // kcz_Latn_TZ
+ case 0x806A41554C61746ELLU: // kda_Latn_AU
+ case 0x886A545A4C61746ELLU: // kdc_Latn_TZ
+ case 0x8C6A41554C61746ELLU: // kdd_Latn_AU
+ case 0x906A545A4C61746ELLU: // kde_Latn_TZ
+ case 0x946A50474C61746ELLU: // kdf_Latn_PG
+ case 0x986A43444C61746ELLU: // kdg_Latn_CD
+ case 0x9C6A54474C61746ELLU: // kdh_Latn_TG
+ case 0xA06A55474C61746ELLU: // kdi_Latn_UG
+ case 0xA46A55474C61746ELLU: // kdj_Latn_UG
+ case 0xA86A4E434C61746ELLU: // kdk_Latn_NC
+ case 0xAC6A4E474C61746ELLU: // kdl_Latn_NG
+ case 0xB06A4E474C61746ELLU: // kdm_Latn_NG
+ case 0xB46A5A574C61746ELLU: // kdn_Latn_ZW
+ case 0xBC6A4E474C61746ELLU: // kdp_Latn_NG
+ case 0xC06A494E42656E67LLU: // kdq_Beng_IN
+ case 0xC46A4C544C61746ELLU: // kdr_Latn_LT
+ case 0xCC6A544854686169LLU: // kdt_Thai_TH
+ case 0xD86A49444C61746ELLU: // kdw_Latn_ID
+ case 0xDC6A4E474C61746ELLU: // kdx_Latn_NG
+ case 0xE06A49444C61746ELLU: // kdy_Latn_ID
+ case 0xE46A434D4C61746ELLU: // kdz_Latn_CM
+ case 0x808A43564C61746ELLU: // kea_Latn_CV
+ case 0x848A47414C61746ELLU: // keb_Latn_GA
+ case 0x888A53444C61746ELLU: // kec_Latn_SD
+ case 0x8C8A545A4C61746ELLU: // ked_Latn_TZ
+ case 0x908A55534C61746ELLU: // kee_Latn_US
+ case 0x948A54474C61746ELLU: // kef_Latn_TG
+ case 0x988A53444C61746ELLU: // keg_Latn_SD
+ case 0x9C8A50474C61746ELLU: // keh_Latn_PG
+ case 0xA08A49444C61746ELLU: // kei_Latn_ID
+ case 0xA88A47544C61746ELLU: // kek_Latn_GT
+ case 0xAC8A43444C61746ELLU: // kel_Latn_CD
+ case 0xB08A544C4C61746ELLU: // kem_Latn_TL
+ case 0xB48A434D4C61746ELLU: // ken_Latn_CM
+ case 0xB88A55474C61746ELLU: // keo_Latn_UG
+ case 0xC48A54444C61746ELLU: // ker_Latn_TD
+ case 0xC88A4E474C61746ELLU: // kes_Latn_NG
+ case 0xCC8A52554379726CLLU: // ket_Cyrl_RU
+ case 0xD08A54474C61746ELLU: // keu_Latn_TG
+ case 0xD48A494E4D6C796DLLU: // kev_Mlym_IN
+ case 0xD88A50474C61746ELLU: // kew_Latn_PG
+ case 0xDC8A494E44657661LLU: // kex_Deva_IN
+ case 0xE08A494E54656C75LLU: // key_Telu_IN
+ case 0xE48A4E474C61746ELLU: // kez_Latn_NG
+ case 0x80AA494E4B6E6461LLU: // kfa_Knda_IN
+ case 0x84AA494E44657661LLU: // kfb_Deva_IN
+ case 0x88AA494E54656C75LLU: // kfc_Telu_IN
+ case 0x8CAA494E4B6E6461LLU: // kfd_Knda_IN
+ case 0x90AA494E54616D6CLLU: // kfe_Taml_IN
+ case 0x94AA494E4C61746ELLU: // kff_Latn_IN
+ case 0x98AA494E4B6E6461LLU: // kfg_Knda_IN
+ case 0x9CAA494E4D6C796DLLU: // kfh_Mlym_IN
+ case 0xA0AA494E54616D6CLLU: // kfi_Taml_IN
+ case 0xA8AA494E44657661LLU: // kfk_Deva_IN
+ case 0xACAA434D4C61746ELLU: // kfl_Latn_CM
+ case 0xB0AA495241726162LLU: // kfm_Arab_IR
+ case 0xB4AA434D4C61746ELLU: // kfn_Latn_CM
+ case 0xB8AA43494C61746ELLU: // kfo_Latn_CI
+ case 0xBCAA494E44657661LLU: // kfp_Deva_IN
+ case 0xC0AA494E44657661LLU: // kfq_Deva_IN
+ case 0xC4AA494E44657661LLU: // kfr_Deva_IN
+ case 0xC8AA494E44657661LLU: // kfs_Deva_IN
+ case 0xD0AA494E44657661LLU: // kfu_Deva_IN
+ case 0xD4AA494E4C61746ELLU: // kfv_Latn_IN
+ case 0xD8AA494E4C61746ELLU: // kfw_Latn_IN
+ case 0xDCAA494E44657661LLU: // kfx_Deva_IN
+ case 0xE0AA494E44657661LLU: // kfy_Deva_IN
+ case 0xE4AA42464C61746ELLU: // kfz_Latn_BF
+ case 0x6B6743444C61746ELLU: // kg_Latn_CD
+ case 0x80CA43494C61746ELLU: // kga_Latn_CI
+ case 0x84CA49444C61746ELLU: // kgb_Latn_ID
+ case 0x90CA49444C61746ELLU: // kge_Latn_ID
+ case 0x94CA50474C61746ELLU: // kgf_Latn_PG
+ case 0xA4CA4E5044657661LLU: // kgj_Deva_NP
+ case 0xA8CA42524C61746ELLU: // kgk_Latn_BR
+ case 0xACCA41554C61746ELLU: // kgl_Latn_AU
+ case 0xB8CA53444C61746ELLU: // kgo_Latn_SD
+ case 0xBCCA42524C61746ELLU: // kgp_Latn_BR
+ case 0xC0CA49444C61746ELLU: // kgq_Latn_ID
+ case 0xC4CA49444C61746ELLU: // kgr_Latn_ID
+ case 0xC8CA41554C61746ELLU: // kgs_Latn_AU
+ case 0xCCCA4E474C61746ELLU: // kgt_Latn_NG
+ case 0xD0CA50474C61746ELLU: // kgu_Latn_PG
+ case 0xD4CA49444C61746ELLU: // kgv_Latn_ID
+ case 0xD8CA49444C61746ELLU: // kgw_Latn_ID
+ case 0xDCCA49444C61746ELLU: // kgx_Latn_ID
+ case 0xE0CA4E5044657661LLU: // kgy_Deva_NP
+ case 0x80EA494E4C61746ELLU: // kha_Latn_IN
+ case 0x84EA434E54616C75LLU: // khb_Talu_CN
+ case 0x88EA49444C61746ELLU: // khc_Latn_ID
+ case 0x8CEA49444C61746ELLU: // khd_Latn_ID
+ case 0x90EA49444C61746ELLU: // khe_Latn_ID
+ case 0x94EA4C4154686169LLU: // khf_Thai_LA
+ case 0x98EA434E54696274LLU: // khg_Tibt_CN
+ case 0x9CEA49444C61746ELLU: // khh_Latn_ID
+ case 0xA4EA4E474C61746ELLU: // khj_Latn_NG
+ case 0xACEA50474C61746ELLU: // khl_Latn_PG
+ case 0xB4EA494E44657661LLU: // khn_Deva_IN
+ case 0xB8EA495242726168LLU: // kho_Brah_IR
+ case 0xBCEA49444C61746ELLU: // khp_Latn_ID
+ case 0xC0EA4D4C4C61746ELLU: // khq_Latn_ML
+ case 0xC4EA494E4C61746ELLU: // khr_Latn_IN
+ case 0xC8EA50474C61746ELLU: // khs_Latn_PG
+ case 0xCCEA494E4D796D72LLU: // kht_Mymr_IN
+ case 0xD0EA414F4C61746ELLU: // khu_Latn_AO
+ case 0xD4EA52554379726CLLU: // khv_Cyrl_RU
+ case 0xD8EA504B41726162LLU: // khw_Arab_PK
+ case 0xDCEA43444C61746ELLU: // khx_Latn_CD
+ case 0xE0EA43444C61746ELLU: // khy_Latn_CD
+ case 0xE4EA50474C61746ELLU: // khz_Latn_PG
+ case 0x6B694B454C61746ELLU: // ki_Latn_KE
+ case 0x810A54444C61746ELLU: // kia_Latn_TD
+ case 0x850A53444C61746ELLU: // kib_Latn_SD
+ case 0x890A55534C61746ELLU: // kic_Latn_US
+ case 0x8D0A434D4C61746ELLU: // kid_Latn_CM
+ case 0x910A54444C61746ELLU: // kie_Latn_TD
+ case 0x950A4E5044657661LLU: // kif_Deva_NP
+ case 0x990A49444C61746ELLU: // kig_Latn_ID
+ case 0x9D0A50474C61746ELLU: // kih_Latn_PG
+ case 0xA50A50474C61746ELLU: // kij_Latn_PG
+ case 0xAD0A4E474C61746ELLU: // kil_Latn_NG
+ case 0xB10A52554379726CLLU: // kim_Cyrl_RU
+ case 0xB90A55534C61746ELLU: // kio_Latn_US
+ case 0xBD0A4E5044657661LLU: // kip_Deva_NP
+ case 0xC10A49444C61746ELLU: // kiq_Latn_ID
+ case 0xC90A50474C61746ELLU: // kis_Latn_PG
+ case 0xCD0A50474C61746ELLU: // kit_Latn_PG
+ case 0xD10A54524C61746ELLU: // kiu_Latn_TR
+ case 0xD50A545A4C61746ELLU: // kiv_Latn_TZ
+ case 0xD90A50474C61746ELLU: // kiw_Latn_PG
+ case 0xDD0A494E4C61746ELLU: // kix_Latn_IN
+ case 0xE10A49444C61746ELLU: // kiy_Latn_ID
+ case 0xE50A545A4C61746ELLU: // kiz_Latn_TZ
+ case 0x6B6A4E414C61746ELLU: // kj_Latn_NA
+ case 0x812A49444C61746ELLU: // kja_Latn_ID
+ case 0x852A47544C61746ELLU: // kjb_Latn_GT
+ case 0x892A49444C61746ELLU: // kjc_Latn_ID
+ case 0x8D2A50474C61746ELLU: // kjd_Latn_PG
+ case 0x912A49444C61746ELLU: // kje_Latn_ID
+ case 0x992A4C414C616F6FLLU: // kjg_Laoo_LA
+ case 0x9D2A52554379726CLLU: // kjh_Cyrl_RU
+ case 0xA12A53424C61746ELLU: // kji_Latn_SB
+ case 0xA52A415A4C61746ELLU: // kjj_Latn_AZ
+ case 0xA92A49444C61746ELLU: // kjk_Latn_ID
+ case 0xAD2A4E5044657661LLU: // kjl_Deva_NP
+ case 0xB12A564E4C61746ELLU: // kjm_Latn_VN
+ case 0xB52A41554C61746ELLU: // kjn_Latn_AU
+ case 0xB92A494E44657661LLU: // kjo_Deva_IN
+ case 0xBD2A4D4D4D796D72LLU: // kjp_Mymr_MM
+ case 0xC12A55534C61746ELLU: // kjq_Latn_US
+ case 0xC52A49444C61746ELLU: // kjr_Latn_ID
+ case 0xC92A50474C61746ELLU: // kjs_Latn_PG
+ case 0xCD2A544854686169LLU: // kjt_Thai_TH
+ case 0xD12A55534C61746ELLU: // kju_Latn_US
+ case 0xDD2A50474C61746ELLU: // kjx_Latn_PG
+ case 0xE12A50474C61746ELLU: // kjy_Latn_PG
+ case 0xE52A425454696274LLU: // kjz_Tibt_BT
+ case 0x6B6B434E41726162LLU: // kk_Arab_CN
+ case 0x6B6B4B5A4379726CLLU: // kk_Cyrl_KZ
+ case 0x814A4E474C61746ELLU: // kka_Latn_NG
+ case 0x854A49444C61746ELLU: // kkb_Latn_ID
+ case 0x894A50474C61746ELLU: // kkc_Latn_PG
+ case 0x8D4A4E474C61746ELLU: // kkd_Latn_NG
+ case 0x914A474E4C61746ELLU: // kke_Latn_GN
+ case 0x954A494E54696274LLU: // kkf_Tibt_IN
+ case 0x994A50484C61746ELLU: // kkg_Latn_PH
+ case 0x9D4A4D4D4C616E61LLU: // kkh_Lana_MM
+ case 0xA14A545A4C61746ELLU: // kki_Latn_TZ
+ case 0xA54A434D4C61746ELLU: // kkj_Latn_CM
+ case 0xA94A53424C61746ELLU: // kkk_Latn_SB
+ case 0xAD4A49444C61746ELLU: // kkl_Latn_ID
+ case 0xB14A4E474C61746ELLU: // kkm_Latn_NG
+ case 0xB94A53444C61746ELLU: // kko_Latn_SD
+ case 0xBD4A41554C61746ELLU: // kkp_Latn_AU
+ case 0xC14A43444C61746ELLU: // kkq_Latn_CD
+ case 0xC54A4E474C61746ELLU: // kkr_Latn_NG
+ case 0xC94A4E474C61746ELLU: // kks_Latn_NG
+ case 0xCD4A4E5044657661LLU: // kkt_Deva_NP
+ case 0xD14A4E474C61746ELLU: // kku_Latn_NG
+ case 0xD54A49444C61746ELLU: // kkv_Latn_ID
+ case 0xD94A43474C61746ELLU: // kkw_Latn_CG
+ case 0xDD4A49444C61746ELLU: // kkx_Latn_ID
+ case 0xE14A41554C61746ELLU: // kky_Latn_AU
+ case 0xE54A43414C61746ELLU: // kkz_Latn_CA
+ case 0x6B6C474C4C61746ELLU: // kl_Latn_GL
+ case 0x816A55534C61746ELLU: // kla_Latn_US
+ case 0x856A4D584C61746ELLU: // klb_Latn_MX
+ case 0x896A434D4C61746ELLU: // klc_Latn_CM
+ case 0x8D6A41554C61746ELLU: // kld_Latn_AU
+ case 0x916A4E5044657661LLU: // kle_Deva_NP
+ case 0x956A54444C61746ELLU: // klf_Latn_TD
+ case 0x996A50484C61746ELLU: // klg_Latn_PH
+ case 0x9D6A50474C61746ELLU: // klh_Latn_PG
+ case 0xA16A49444C61746ELLU: // kli_Latn_ID
+ case 0xA56A495241726162LLU: // klj_Arab_IR
+ case 0xA96A4E474C61746ELLU: // klk_Latn_NG
+ case 0xAD6A50484C61746ELLU: // kll_Latn_PH
+ case 0xB16A50474C61746ELLU: // klm_Latn_PG
+ case 0xB56A4B454C61746ELLU: // kln_Latn_KE
+ case 0xB96A4E474C61746ELLU: // klo_Latn_NG
+ case 0xBD6A50474C61746ELLU: // klp_Latn_PG
+ case 0xC16A50474C61746ELLU: // klq_Latn_PG
+ case 0xC56A4E5044657661LLU: // klr_Deva_NP
+ case 0xC96A504B4C61746ELLU: // kls_Latn_PK
+ case 0xCD6A50474C61746ELLU: // klt_Latn_PG
+ case 0xD16A4C524C61746ELLU: // klu_Latn_LR
+ case 0xD56A56554C61746ELLU: // klv_Latn_VU
+ case 0xD96A49444C61746ELLU: // klw_Latn_ID
+ case 0xDD6A50474C61746ELLU: // klx_Latn_PG
+ case 0xE16A49444C61746ELLU: // kly_Latn_ID
+ case 0xE56A49444C61746ELLU: // klz_Latn_ID
+ case 0x6B6D4B484B686D72LLU: // km_Khmr_KH
+ case 0x818A47484C61746ELLU: // kma_Latn_GH
+ case 0x858A414F4C61746ELLU: // kmb_Latn_AO
+ case 0x898A434E4C61746ELLU: // kmc_Latn_CN
+ case 0x8D8A50484C61746ELLU: // kmd_Latn_PH
+ case 0x918A434D4C61746ELLU: // kme_Latn_CM
+ case 0x958A50474C61746ELLU: // kmf_Latn_PG
+ case 0x998A50474C61746ELLU: // kmg_Latn_PG
+ case 0x9D8A50474C61746ELLU: // kmh_Latn_PG
+ case 0xA18A4E474C61746ELLU: // kmi_Latn_NG
+ case 0xA58A494E44657661LLU: // kmj_Deva_IN
+ case 0xA98A50484C61746ELLU: // kmk_Latn_PH
+ case 0xAD8A50484C61746ELLU: // kml_Latn_PH
+ case 0xB18A494E4C61746ELLU: // kmm_Latn_IN
+ case 0xB58A50474C61746ELLU: // kmn_Latn_PG
+ case 0xB98A50474C61746ELLU: // kmo_Latn_PG
+ case 0xBD8A434D4C61746ELLU: // kmp_Latn_CM
+ case 0xC18A45544C61746ELLU: // kmq_Latn_ET
+ case 0xC98A50474C61746ELLU: // kms_Latn_PG
+ case 0xCD8A49444C61746ELLU: // kmt_Latn_ID
+ case 0xD18A50474C61746ELLU: // kmu_Latn_PG
+ case 0xD58A42524C61746ELLU: // kmv_Latn_BR
+ case 0xD98A43444C61746ELLU: // kmw_Latn_CD
+ case 0xDD8A50474C61746ELLU: // kmx_Latn_PG
+ case 0xE18A4E474C61746ELLU: // kmy_Latn_NG
+ case 0xE58A495241726162LLU: // kmz_Arab_IR
+ case 0x6B6E494E4B6E6461LLU: // kn_Knda_IN
+ case 0x81AA4E474C61746ELLU: // kna_Latn_NG
+ case 0x85AA50484C61746ELLU: // knb_Latn_PH
+ case 0x8DAA49444C61746ELLU: // knd_Latn_ID
+ case 0x91AA50484C61746ELLU: // kne_Latn_PH
+ case 0x95AA47574C61746ELLU: // knf_Latn_GW
+ case 0xA1AA4E474C61746ELLU: // kni_Latn_NG
+ case 0xA5AA47544C61746ELLU: // knj_Latn_GT
+ case 0xA9AA534C4C61746ELLU: // knk_Latn_SL
+ case 0xADAA49444C61746ELLU: // knl_Latn_ID
+ case 0xB1AA42524C61746ELLU: // knm_Latn_BR
+ case 0xB5AA494E44657661LLU: // knn_Deva_IN
+ case 0xB9AA534C4C61746ELLU: // kno_Latn_SL
+ case 0xBDAA434D4C61746ELLU: // knp_Latn_CM
+ case 0xC1AA4D594C61746ELLU: // knq_Latn_MY
+ case 0xC5AA50474C61746ELLU: // knr_Latn_PG
+ case 0xC9AA4D594C61746ELLU: // kns_Latn_MY
+ case 0xCDAA42524C61746ELLU: // knt_Latn_BR
+ case 0xD1AA474E4C61746ELLU: // knu_Latn_GN
+ case 0xD5AA50474C61746ELLU: // knv_Latn_PG
+ case 0xD9AA4E414C61746ELLU: // knw_Latn_NA
+ case 0xDDAA49444C61746ELLU: // knx_Latn_ID
+ case 0xE1AA43444C61746ELLU: // kny_Latn_CD
+ case 0xE5AA42464C61746ELLU: // knz_Latn_BF
+ case 0x6B6F4B524B6F7265LLU: // ko_Kore_KR
+ case 0x81CA50474C61746ELLU: // koa_Latn_PG
+ case 0x89CA4E474C61746ELLU: // koc_Latn_NG
+ case 0x8DCA49444C61746ELLU: // kod_Latn_ID
+ case 0x91CA53534C61746ELLU: // koe_Latn_SS
+ case 0x95CA4E474C61746ELLU: // kof_Latn_NG
+ case 0x99CA434F4C61746ELLU: // kog_Latn_CO
+ case 0x9DCA43474C61746ELLU: // koh_Latn_CG
+ case 0xA1CA52554379726CLLU: // koi_Cyrl_RU
+ case 0xA9CA494E44657661LLU: // kok_Deva_IN
+ case 0xADCA50474C61746ELLU: // kol_Latn_PG
+ case 0xB9CA55474C61746ELLU: // koo_Latn_UG
+ case 0xBDCA50474C61746ELLU: // kop_Latn_PG
+ case 0xC1CA47414C61746ELLU: // koq_Latn_GA
+ case 0xC9CA464D4C61746ELLU: // kos_Latn_FM
+ case 0xCDCA434D4C61746ELLU: // kot_Latn_CM
+ case 0xD1CA54444C61746ELLU: // kou_Latn_TD
+ case 0xD5CA4E474C61746ELLU: // kov_Latn_NG
+ case 0xD9CA4E474C61746ELLU: // kow_Latn_NG
+ case 0xE1CA55534C61746ELLU: // koy_Latn_US
+ case 0xE5CA50474C61746ELLU: // koz_Latn_PG
+ case 0x81EA4E474C61746ELLU: // kpa_Latn_NG
+ case 0x89EA434F4C61746ELLU: // kpc_Latn_CO
+ case 0x8DEA49444C61746ELLU: // kpd_Latn_ID
+ case 0x91EA4C524C61746ELLU: // kpe_Latn_LR
+ case 0x95EA50474C61746ELLU: // kpf_Latn_PG
+ case 0x99EA464D4C61746ELLU: // kpg_Latn_FM
+ case 0x9DEA47484C61746ELLU: // kph_Latn_GH
+ case 0xA1EA49444C61746ELLU: // kpi_Latn_ID
+ case 0xA5EA42524C61746ELLU: // kpj_Latn_BR
+ case 0xA9EA4E474C61746ELLU: // kpk_Latn_NG
+ case 0xADEA43444C61746ELLU: // kpl_Latn_CD
+ case 0xB1EA564E4C61746ELLU: // kpm_Latn_VN
+ case 0xB5EA42524C61746ELLU: // kpn_Latn_BR
+ case 0xB9EA54474C61746ELLU: // kpo_Latn_TG
+ case 0xC1EA49444C61746ELLU: // kpq_Latn_ID
+ case 0xC5EA50474C61746ELLU: // kpr_Latn_PG
+ case 0xC9EA49444C61746ELLU: // kps_Latn_ID
+ case 0xCDEA52554379726CLLU: // kpt_Cyrl_RU
+ case 0xD1EA49444C61746ELLU: // kpu_Latn_ID
+ case 0xD9EA50474C61746ELLU: // kpw_Latn_PG
+ case 0xDDEA50474C61746ELLU: // kpx_Latn_PG
+ case 0xE1EA52554379726CLLU: // kpy_Cyrl_RU
+ case 0xE5EA55474C61746ELLU: // kpz_Latn_UG
+ case 0x820A50474C61746ELLU: // kqa_Latn_PG
+ case 0x860A50474C61746ELLU: // kqb_Latn_PG
+ case 0x8A0A50474C61746ELLU: // kqc_Latn_PG
+ case 0x8E0A495153797263LLU: // kqd_Syrc_IQ
+ case 0x920A50484C61746ELLU: // kqe_Latn_PH
+ case 0x960A50474C61746ELLU: // kqf_Latn_PG
+ case 0x9A0A42464C61746ELLU: // kqg_Latn_BF
+ case 0x9E0A545A4C61746ELLU: // kqh_Latn_TZ
+ case 0xA20A50474C61746ELLU: // kqi_Latn_PG
+ case 0xA60A50474C61746ELLU: // kqj_Latn_PG
+ case 0xAA0A424A4C61746ELLU: // kqk_Latn_BJ
+ case 0xAE0A50474C61746ELLU: // kql_Latn_PG
+ case 0xB20A43494C61746ELLU: // kqm_Latn_CI
+ case 0xB60A5A4D4C61746ELLU: // kqn_Latn_ZM
+ case 0xBA0A4C524C61746ELLU: // kqo_Latn_LR
+ case 0xBE0A54444C61746ELLU: // kqp_Latn_TD
+ case 0xC20A42524C61746ELLU: // kqq_Latn_BR
+ case 0xC60A4D594C61746ELLU: // kqr_Latn_MY
+ case 0xCA0A474E4C61746ELLU: // kqs_Latn_GN
+ case 0xCE0A4D594C61746ELLU: // kqt_Latn_MY
+ case 0xD20A5A414C61746ELLU: // kqu_Latn_ZA
+ case 0xD60A49444C61746ELLU: // kqv_Latn_ID
+ case 0xDA0A50474C61746ELLU: // kqw_Latn_PG
+ case 0xDE0A434D4C61746ELLU: // kqx_Latn_CM
+ case 0xE20A455445746869LLU: // kqy_Ethi_ET
+ case 0xE60A5A414C61746ELLU: // kqz_Latn_ZA
+ case 0x6B724E474C61746ELLU: // kr_Latn_NG
+ case 0x822A4E5044657661LLU: // kra_Deva_NP
+ case 0x862A55534C61746ELLU: // krb_Latn_US
+ case 0x8A2A52554379726CLLU: // krc_Cyrl_RU
+ case 0x8E2A544C4C61746ELLU: // krd_Latn_TL
+ case 0x922A42524C61746ELLU: // kre_Latn_BR
+ case 0x962A56554C61746ELLU: // krf_Latn_VU
+ case 0x9E2A4E474C61746ELLU: // krh_Latn_NG
+ case 0xA22A534C4C61746ELLU: // kri_Latn_SL
+ case 0xA62A50484C61746ELLU: // krj_Latn_PH
+ case 0xAA2A52554379726CLLU: // krk_Cyrl_RU
+ case 0xAE2A52554C61746ELLU: // krl_Latn_RU
+ case 0xB62A4C524C61746ELLU: // krn_Latn_LR
+ case 0xBE2A4E474C61746ELLU: // krp_Latn_NG
+ case 0xC62A4B484B686D72LLU: // krr_Khmr_KH
+ case 0xCA2A53534C61746ELLU: // krs_Latn_SS
+ case 0xCE2A4E454C61746ELLU: // krt_Latn_NE
+ case 0xD22A494E44657661LLU: // kru_Deva_IN
+ case 0xD62A4B484B686D72LLU: // krv_Khmr_KH
+ case 0xDA2A4C524C61746ELLU: // krw_Latn_LR
+ case 0xDE2A534E4C61746ELLU: // krx_Latn_SN
+ case 0xE22A415A4C61746ELLU: // kry_Latn_AZ
+ case 0xE62A49444C61746ELLU: // krz_Latn_ID
+ case 0x6B73494E41726162LLU: // ks_Arab_IN
+ case 0x864A545A4C61746ELLU: // ksb_Latn_TZ
+ case 0x8A4A50484C61746ELLU: // ksc_Latn_PH
+ case 0x8E4A50474C61746ELLU: // ksd_Latn_PG
+ case 0x924A50474C61746ELLU: // kse_Latn_PG
+ case 0x964A434D4C61746ELLU: // ksf_Latn_CM
+ case 0x9A4A53424C61746ELLU: // ksg_Latn_SB
+ case 0x9E4A44454C61746ELLU: // ksh_Latn_DE
+ case 0xA24A50474C61746ELLU: // ksi_Latn_PG
+ case 0xA64A50474C61746ELLU: // ksj_Latn_PG
+ case 0xAA4A55534C61746ELLU: // ksk_Latn_US
+ case 0xAE4A50474C61746ELLU: // ksl_Latn_PG
+ case 0xB24A4E474C61746ELLU: // ksm_Latn_NG
+ case 0xB64A50484C61746ELLU: // ksn_Latn_PH
+ case 0xBA4A4E474C61746ELLU: // kso_Latn_NG
+ case 0xBE4A43464C61746ELLU: // ksp_Latn_CF
+ case 0xC24A4E474C61746ELLU: // ksq_Latn_NG
+ case 0xC64A50474C61746ELLU: // ksr_Latn_PG
+ case 0xCA4A4C524C61746ELLU: // kss_Latn_LR
+ case 0xCE4A42464C61746ELLU: // kst_Latn_BF
+ case 0xD24A494E4D796D72LLU: // ksu_Mymr_IN
+ case 0xD64A43444C61746ELLU: // ksv_Latn_CD
+ case 0xDA4A4D4D4D796D72LLU: // ksw_Mymr_MM
+ case 0xDE4A49444C61746ELLU: // ksx_Latn_ID
+ case 0xE64A494E44657661LLU: // ksz_Deva_IN
+ case 0x826A564E4C61746ELLU: // kta_Latn_VN
+ case 0x866A455445746869LLU: // ktb_Ethi_ET
+ case 0x8A6A4E474C61746ELLU: // ktc_Latn_NG
+ case 0x8E6A41554C61746ELLU: // ktd_Latn_AU
+ case 0x926A4E5044657661LLU: // kte_Deva_NP
+ case 0x966A43444C61746ELLU: // ktf_Latn_CD
+ case 0x9A6A41554C61746ELLU: // ktg_Latn_AU
+ case 0x9E6A54444C61746ELLU: // kth_Latn_TD
+ case 0xA26A49444C61746ELLU: // kti_Latn_ID
+ case 0xA66A43494C61746ELLU: // ktj_Latn_CI
+ case 0xAA6A50474C61746ELLU: // ktk_Latn_PG
+ case 0xAE6A495241726162LLU: // ktl_Arab_IR
+ case 0xB26A50474C61746ELLU: // ktm_Latn_PG
+ case 0xB66A42524C61746ELLU: // ktn_Latn_BR
+ case 0xBA6A50474C61746ELLU: // kto_Latn_PG
+ case 0xBE6A434E506C7264LLU: // ktp_Plrd_CN
+ case 0xC26A50484C61746ELLU: // ktq_Latn_PH
+ case 0xCA6A49444C61746ELLU: // kts_Latn_ID
+ case 0xCE6A49444C61746ELLU: // ktt_Latn_ID
+ case 0xD26A43444C61746ELLU: // ktu_Latn_CD
+ case 0xD66A564E4C61746ELLU: // ktv_Latn_VN
+ case 0xDA6A55534C61746ELLU: // ktw_Latn_US
+ case 0xDE6A42524C61746ELLU: // ktx_Latn_BR
+ case 0xE26A43444C61746ELLU: // kty_Latn_CD
+ case 0xE66A4E414C61746ELLU: // ktz_Latn_NA
+ case 0x6B75495141726162LLU: // ku_Arab_IQ
+ case 0x6B7554524C61746ELLU: // ku_Latn_TR
+ case 0x6B75474559657A69LLU: // ku_Yezi_GE
+ case 0x868A4E474C61746ELLU: // kub_Latn_NG
+ case 0x8A8A49444C61746ELLU: // kuc_Latn_ID
+ case 0x8E8A50474C61746ELLU: // kud_Latn_PG
+ case 0x928A50474C61746ELLU: // kue_Latn_PG
+ case 0x968A4C414C616F6FLLU: // kuf_Laoo_LA
+ case 0x9A8A4E474C61746ELLU: // kug_Latn_NG
+ case 0x9E8A4E474C61746ELLU: // kuh_Latn_NG
+ case 0xA28A42524C61746ELLU: // kui_Latn_BR
+ case 0xA68A545A4C61746ELLU: // kuj_Latn_TZ
+ case 0xAA8A49444C61746ELLU: // kuk_Latn_ID
+ case 0xAE8A4E474C61746ELLU: // kul_Latn_NG
+ case 0xB28A52554379726CLLU: // kum_Cyrl_RU
+ case 0xB68A45524C61746ELLU: // kun_Latn_ER
+ case 0xBA8A50474C61746ELLU: // kuo_Latn_PG
+ case 0xBE8A50474C61746ELLU: // kup_Latn_PG
+ case 0xC28A42524C61746ELLU: // kuq_Latn_BR
+ case 0xCA8A47484C61746ELLU: // kus_Latn_GH
+ case 0xCE8A43414C61746ELLU: // kut_Latn_CA
+ case 0xD28A55534C61746ELLU: // kuu_Latn_US
+ case 0xD68A49444C61746ELLU: // kuv_Latn_ID
+ case 0xDA8A43464C61746ELLU: // kuw_Latn_CF
+ case 0xDE8A41554C61746ELLU: // kux_Latn_AU
+ case 0xE28A41554C61746ELLU: // kuy_Latn_AU
+ case 0xE68A434C4C61746ELLU: // kuz_Latn_CL
+ case 0x6B7652554379726CLLU: // kv_Cyrl_RU
+ case 0x82AA52554379726CLLU: // kva_Cyrl_RU
+ case 0x86AA49444C61746ELLU: // kvb_Latn_ID
+ case 0x8AAA50474C61746ELLU: // kvc_Latn_PG
+ case 0x8EAA49444C61746ELLU: // kvd_Latn_ID
+ case 0x92AA4D594C61746ELLU: // kve_Latn_MY
+ case 0x96AA54444C61746ELLU: // kvf_Latn_TD
+ case 0x9AAA50474C61746ELLU: // kvg_Latn_PG
+ case 0x9EAA49444C61746ELLU: // kvh_Latn_ID
+ case 0xA2AA54444C61746ELLU: // kvi_Latn_TD
+ case 0xA6AA434D4C61746ELLU: // kvj_Latn_CM
+ case 0xAEAA4D4D4C61746ELLU: // kvl_Latn_MM
+ case 0xB2AA434D4C61746ELLU: // kvm_Latn_CM
+ case 0xB6AA434F4C61746ELLU: // kvn_Latn_CO
+ case 0xBAAA49444C61746ELLU: // kvo_Latn_ID
+ case 0xBEAA49444C61746ELLU: // kvp_Latn_ID
+ case 0xC2AA4D4D4D796D72LLU: // kvq_Mymr_MM
+ case 0xC6AA49444C61746ELLU: // kvr_Latn_ID
+ case 0xCEAA4D4D4D796D72LLU: // kvt_Mymr_MM
+ case 0xD6AA49444C61746ELLU: // kvv_Latn_ID
+ case 0xDAAA49444C61746ELLU: // kvw_Latn_ID
+ case 0xDEAA504B41726162LLU: // kvx_Arab_PK
+ case 0xE2AA4D4D4B616C69LLU: // kvy_Kali_MM
+ case 0xE6AA49444C61746ELLU: // kvz_Latn_ID
+ case 0x6B7747424C61746ELLU: // kw_Latn_GB
+ case 0x82CA42524C61746ELLU: // kwa_Latn_BR
+ case 0x86CA4E474C61746ELLU: // kwb_Latn_NG
+ case 0x8ACA43474C61746ELLU: // kwc_Latn_CG
+ case 0x8ECA53424C61746ELLU: // kwd_Latn_SB
+ case 0x92CA49444C61746ELLU: // kwe_Latn_ID
+ case 0x96CA53424C61746ELLU: // kwf_Latn_SB
+ case 0x9ACA54444C61746ELLU: // kwg_Latn_TD
+ case 0x9ECA49444C61746ELLU: // kwh_Latn_ID
+ case 0xA2CA434F4C61746ELLU: // kwi_Latn_CO
+ case 0xA6CA50474C61746ELLU: // kwj_Latn_PG
+ case 0xAACA43414C61746ELLU: // kwk_Latn_CA
+ case 0xAECA4E474C61746ELLU: // kwl_Latn_NG
+ case 0xB2CA4E414C61746ELLU: // kwm_Latn_NA
+ case 0xB6CA4E414C61746ELLU: // kwn_Latn_NA
+ case 0xBACA50474C61746ELLU: // kwo_Latn_PG
+ case 0xBECA43494C61746ELLU: // kwp_Latn_CI
+ case 0xC6CA49444C61746ELLU: // kwr_Latn_ID
+ case 0xCACA43444C61746ELLU: // kws_Latn_CD
+ case 0xCECA49444C61746ELLU: // kwt_Latn_ID
+ case 0xD2CA434D4C61746ELLU: // kwu_Latn_CM
+ case 0xD6CA54444C61746ELLU: // kwv_Latn_TD
+ case 0xDACA53524C61746ELLU: // kww_Latn_SR
+ case 0xE2CA414F4C61746ELLU: // kwy_Latn_AO
+ case 0xE6CA414F4C61746ELLU: // kwz_Latn_AO
+ case 0x82EA50474C61746ELLU: // kxa_Latn_PG
+ case 0x86EA43494C61746ELLU: // kxb_Latn_CI
+ case 0x8AEA45544C61746ELLU: // kxc_Latn_ET
+ case 0x8EEA424E4C61746ELLU: // kxd_Latn_BN
+ case 0x96EA4D4D4D796D72LLU: // kxf_Mymr_MM
+ case 0xA2EA4D594C61746ELLU: // kxi_Latn_MY
+ case 0xA6EA54444C61746ELLU: // kxj_Latn_TD
+ case 0xAAEA4D4D4D796D72LLU: // kxk_Mymr_MM
+ case 0xB2EA544854686169LLU: // kxm_Thai_TH
+ case 0xB6EA4D594C61746ELLU: // kxn_Latn_MY
+ case 0xBAEA42524C61746ELLU: // kxo_Latn_BR
+ case 0xBEEA504B41726162LLU: // kxp_Arab_PK
+ case 0xC2EA49444C61746ELLU: // kxq_Latn_ID
+ case 0xC6EA50474C61746ELLU: // kxr_Latn_PG
+ case 0xCEEA50474C61746ELLU: // kxt_Latn_PG
+ case 0xD6EA494E4C61746ELLU: // kxv_Latn_IN
+ case 0xDAEA50474C61746ELLU: // kxw_Latn_PG
+ case 0xDEEA43474C61746ELLU: // kxx_Latn_CG
+ case 0xE2EA564E4C61746ELLU: // kxy_Latn_VN
+ case 0xE6EA50474C61746ELLU: // kxz_Latn_PG
+ case 0x6B79434E41726162LLU: // ky_Arab_CN
+ case 0x6B794B474379726CLLU: // ky_Cyrl_KG
+ case 0x6B7954524C61746ELLU: // ky_Latn_TR
+ case 0x830A545A4C61746ELLU: // kya_Latn_TZ
+ case 0x870A50484C61746ELLU: // kyb_Latn_PH
+ case 0x8B0A50474C61746ELLU: // kyc_Latn_PG
+ case 0x8F0A49444C61746ELLU: // kyd_Latn_ID
+ case 0x930A47484C61746ELLU: // kye_Latn_GH
+ case 0x970A43494C61746ELLU: // kyf_Latn_CI
+ case 0x9B0A50474C61746ELLU: // kyg_Latn_PG
+ case 0x9F0A55534C61746ELLU: // kyh_Latn_US
+ case 0xA30A4D594C61746ELLU: // kyi_Latn_MY
+ case 0xA70A50484C61746ELLU: // kyj_Latn_PH
+ case 0xAB0A50484C61746ELLU: // kyk_Latn_PH
+ case 0xAF0A55534C61746ELLU: // kyl_Latn_US
+ case 0xB30A43464C61746ELLU: // kym_Latn_CF
+ case 0xB70A50484C61746ELLU: // kyn_Latn_PH
+ case 0xBB0A49444C61746ELLU: // kyo_Latn_ID
+ case 0xC30A54444C61746ELLU: // kyq_Latn_TD
+ case 0xC70A42524C61746ELLU: // kyr_Latn_BR
+ case 0xCB0A4D594C61746ELLU: // kys_Latn_MY
+ case 0xCF0A49444C61746ELLU: // kyt_Latn_ID
+ case 0xD30A4D4D4B616C69LLU: // kyu_Kali_MM
+ case 0xD70A4E5044657661LLU: // kyv_Deva_NP
+ case 0xDB0A494E44657661LLU: // kyw_Deva_IN
+ case 0xDF0A50474C61746ELLU: // kyx_Latn_PG
+ case 0xE30A50474C61746ELLU: // kyy_Latn_PG
+ case 0xE70A42524C61746ELLU: // kyz_Latn_BR
+ case 0x832A42464C61746ELLU: // kza_Latn_BF
+ case 0x872A49444C61746ELLU: // kzb_Latn_ID
+ case 0x8B2A43494C61746ELLU: // kzc_Latn_CI
+ case 0x8F2A49444C61746ELLU: // kzd_Latn_ID
+ case 0x932A50474C61746ELLU: // kze_Latn_PG
+ case 0x972A49444C61746ELLU: // kzf_Latn_ID
+ case 0xA32A4D594C61746ELLU: // kzi_Latn_MY
+ case 0xAB2A53424C61746ELLU: // kzk_Latn_SB
+ case 0xAF2A49444C61746ELLU: // kzl_Latn_ID
+ case 0xB32A49444C61746ELLU: // kzm_Latn_ID
+ case 0xB72A4D574C61746ELLU: // kzn_Latn_MW
+ case 0xBB2A47414C61746ELLU: // kzo_Latn_GA
+ case 0xBF2A49444C61746ELLU: // kzp_Latn_ID
+ case 0xC72A434D4C61746ELLU: // kzr_Latn_CM
+ case 0xCB2A4D594C61746ELLU: // kzs_Latn_MY
+ case 0xD32A49444C61746ELLU: // kzu_Latn_ID
+ case 0xD72A49444C61746ELLU: // kzv_Latn_ID
+ case 0xDB2A42524C61746ELLU: // kzw_Latn_BR
+ case 0xDF2A49444C61746ELLU: // kzx_Latn_ID
+ case 0xE32A43444C61746ELLU: // kzy_Latn_CD
+ case 0xE72A49444C61746ELLU: // kzz_Latn_ID
+ case 0x6C6156414C61746ELLU: // la_Latn_VA
+ case 0x800B50484C61746ELLU: // laa_Latn_PH
+ case 0x840B47524C696E61LLU: // lab_Lina_GR
+ case 0x880B4D584C61746ELLU: // lac_Latn_MX
+ case 0x8C0B494C48656272LLU: // lad_Hebr_IL
+ case 0x900B494E44657661LLU: // lae_Deva_IN
+ case 0x980B545A4C61746ELLU: // lag_Latn_TZ
+ case 0x9C0B504B41726162LLU: // lah_Arab_PK
+ case 0xA00B4D574C61746ELLU: // lai_Latn_MW
+ case 0xA40B55474C61746ELLU: // laj_Latn_UG
+ case 0xAC0B43444C61746ELLU: // lal_Latn_CD
+ case 0xB00B5A4D4C61746ELLU: // lam_Latn_ZM
+ case 0xB40B4E474C61746ELLU: // lan_Latn_NG
+ case 0xBC0B54444C61746ELLU: // lap_Latn_TD
+ case 0xC00B564E4C61746ELLU: // laq_Latn_VN
+ case 0xC40B47484C61746ELLU: // lar_Latn_GH
+ case 0xC80B54474C61746ELLU: // las_Latn_TG
+ case 0xD00B49444C61746ELLU: // lau_Latn_ID
+ case 0xD80B49444C61746ELLU: // law_Latn_ID
+ case 0xDC0B494E4C61746ELLU: // lax_Latn_IN
+ case 0xE40B50474C61746ELLU: // laz_Latn_PG
+ case 0x6C624C554C61746ELLU: // lb_Latn_LU
+ case 0x842B50474C61746ELLU: // lbb_Latn_PG
+ case 0x902B52554379726CLLU: // lbe_Cyrl_RU
+ case 0x942B494E44657661LLU: // lbf_Deva_IN
+ case 0xA02B434D4C61746ELLU: // lbi_Latn_CM
+ case 0xA42B494E54696274LLU: // lbj_Tibt_IN
+ case 0xAC2B50484C61746ELLU: // lbl_Latn_PH
+ case 0xB02B494E44657661LLU: // lbm_Deva_IN
+ case 0xB42B4C414C61746ELLU: // lbn_Latn_LA
+ case 0xB82B4C414C616F6FLLU: // lbo_Laoo_LA
+ case 0xC02B50474C61746ELLU: // lbq_Latn_PG
+ case 0xC42B4E5044657661LLU: // lbr_Deva_NP
+ case 0xCC2B564E4C61746ELLU: // lbt_Latn_VN
+ case 0xD02B50474C61746ELLU: // lbu_Latn_PG
+ case 0xD42B50474C61746ELLU: // lbv_Latn_PG
+ case 0xD82B49444C61746ELLU: // lbw_Latn_ID
+ case 0xDC2B49444C61746ELLU: // lbx_Latn_ID
+ case 0xE02B41554C61746ELLU: // lby_Latn_AU
+ case 0xE42B41554C61746ELLU: // lbz_Latn_AU
+ case 0x884B49444C61746ELLU: // lcc_Latn_ID
+ case 0x8C4B49444C61746ELLU: // lcd_Latn_ID
+ case 0x904B49444C61746ELLU: // lce_Latn_ID
+ case 0x944B49444C61746ELLU: // lcf_Latn_ID
+ case 0x9C4B414F4C61746ELLU: // lch_Latn_AO
+ case 0xAC4B49444C61746ELLU: // lcl_Latn_ID
+ case 0xB04B50474C61746ELLU: // lcm_Latn_PG
+ case 0xBC4B434E54686169LLU: // lcp_Thai_CN
+ case 0xC04B49444C61746ELLU: // lcq_Latn_ID
+ case 0xC84B49444C61746ELLU: // lcs_Latn_ID
+ case 0x806B43494C61746ELLU: // lda_Latn_CI
+ case 0x846B4E474C61746ELLU: // ldb_Latn_NG
+ case 0x8C6B4E474C61746ELLU: // ldd_Latn_NG
+ case 0x986B4E474C61746ELLU: // ldg_Latn_NG
+ case 0x9C6B4E474C61746ELLU: // ldh_Latn_NG
+ case 0xA06B43474C61746ELLU: // ldi_Latn_CG
+ case 0xA46B4E474C61746ELLU: // ldj_Latn_NG
+ case 0xA86B4E474C61746ELLU: // ldk_Latn_NG
+ case 0xAC6B4E474C61746ELLU: // ldl_Latn_NG
+ case 0xB06B474E4C61746ELLU: // ldm_Latn_GN
+ case 0xB86B4E474C61746ELLU: // ldo_Latn_NG
+ case 0xBC6B4E474C61746ELLU: // ldp_Latn_NG
+ case 0xC06B4E474C61746ELLU: // ldq_Latn_NG
+ case 0x808B43444C61746ELLU: // lea_Latn_CD
+ case 0x848B5A4D4C61746ELLU: // leb_Latn_ZM
+ case 0x888B424F4C61746ELLU: // lec_Latn_BO
+ case 0x8C8B43444C61746ELLU: // led_Latn_CD
+ case 0x908B42464C61746ELLU: // lee_Latn_BF
+ case 0x948B47484C61746ELLU: // lef_Latn_GH
+ case 0x9C8B5A4D4C61746ELLU: // leh_Latn_ZM
+ case 0xA08B50474C61746ELLU: // lei_Latn_PG
+ case 0xA48B43444C61746ELLU: // lej_Latn_CD
+ case 0xA88B50474C61746ELLU: // lek_Latn_PG
+ case 0xAC8B43444C61746ELLU: // lel_Latn_CD
+ case 0xB08B434D4C61746ELLU: // lem_Latn_CM
+ case 0xB48B484E4C61746ELLU: // len_Latn_HN
+ case 0xB88B434D4C61746ELLU: // leo_Latn_CM
+ case 0xBC8B494E4C657063LLU: // lep_Lepc_IN
+ case 0xC08B50474C61746ELLU: // leq_Latn_PG
+ case 0xC48B50474C61746ELLU: // ler_Latn_PG
+ case 0xC88B43444C61746ELLU: // les_Latn_CD
+ case 0xCC8B50474C61746ELLU: // let_Latn_PG
+ case 0xD08B50474C61746ELLU: // leu_Latn_PG
+ case 0xD48B49444C61746ELLU: // lev_Latn_ID
+ case 0xD88B49444C61746ELLU: // lew_Latn_ID
+ case 0xDC8B49444C61746ELLU: // lex_Latn_ID
+ case 0xE08B49444C61746ELLU: // ley_Latn_ID
+ case 0xE48B52554379726CLLU: // lez_Cyrl_RU
+ case 0x80AB434D4C61746ELLU: // lfa_Latn_CM
+ case 0x6C6755474C61746ELLU: // lg_Latn_UG
+ case 0x80CB53424C61746ELLU: // lga_Latn_SB
+ case 0x84CB53424C61746ELLU: // lgb_Latn_SB
+ case 0x98CB55474C61746ELLU: // lgg_Latn_UG
+ case 0x9CCB564E4C61746ELLU: // lgh_Latn_VN
+ case 0xA0CB49444C61746ELLU: // lgi_Latn_ID
+ case 0xA8CB56554C61746ELLU: // lgk_Latn_VU
+ case 0xACCB53424C61746ELLU: // lgl_Latn_SB
+ case 0xB0CB43444C61746ELLU: // lgm_Latn_CD
+ case 0xB4CB45544C61746ELLU: // lgn_Latn_ET
+ case 0xB8CB53534C61746ELLU: // lgo_Latn_SS
+ case 0xC0CB47484C61746ELLU: // lgq_Latn_GH
+ case 0xC4CB53424C61746ELLU: // lgr_Latn_SB
+ case 0xCCCB50474C61746ELLU: // lgt_Latn_PG
+ case 0xD0CB53424C61746ELLU: // lgu_Latn_SB
+ case 0xE4CB43444C61746ELLU: // lgz_Latn_CD
+ case 0x80EB564E4C61746ELLU: // lha_Latn_VN
+ case 0x9CEB49444C61746ELLU: // lhh_Latn_ID
+ case 0xA0EB434E4C61746ELLU: // lhi_Latn_CN
+ case 0xB0EB4E5044657661LLU: // lhm_Deva_NP
+ case 0xB4EB4D594C61746ELLU: // lhn_Latn_MY
+ case 0xC8EB535953797263LLU: // lhs_Syrc_SY
+ case 0xCCEB56554C61746ELLU: // lht_Latn_VU
+ case 0xD0EB434E4C61746ELLU: // lhu_Latn_CN
+ case 0x6C694E4C4C61746ELLU: // li_Latn_NL
+ case 0x810B534C4C61746ELLU: // lia_Latn_SL
+ case 0x850B50474C61746ELLU: // lib_Latn_PG
+ case 0x890B434E4C61746ELLU: // lic_Latn_CN
+ case 0x8D0B50474C61746ELLU: // lid_Latn_PG
+ case 0x910B43444C61746ELLU: // lie_Latn_CD
+ case 0x950B4E5044657661LLU: // lif_Deva_NP
+ case 0x950B494E4C696D62LLU: // lif_Limb_IN
+ case 0x990B47484C61746ELLU: // lig_Latn_GH
+ case 0x9D0B50474C61746ELLU: // lih_Latn_PG
+ case 0xA50B49544C61746ELLU: // lij_Latn_IT
+ case 0xA90B43444C61746ELLU: // lik_Latn_CD
+ case 0xAD0B43414C61746ELLU: // lil_Latn_CA
+ case 0xB90B49444C61746ELLU: // lio_Latn_ID
+ case 0xBD0B47484C61746ELLU: // lip_Latn_GH
+ case 0xC10B45544C61746ELLU: // liq_Latn_ET
+ case 0xC50B4C524C61746ELLU: // lir_Latn_LR
+ case 0xC90B434E4C697375LLU: // lis_Lisu_CN
+ case 0xD10B53444C61746ELLU: // liu_Latn_SD
+ case 0xD50B4C564C61746ELLU: // liv_Latn_LV
+ case 0xD90B49444C61746ELLU: // liw_Latn_ID
+ case 0xDD0B49444C61746ELLU: // lix_Latn_ID
+ case 0xE10B43464C61746ELLU: // liy_Latn_CF
+ case 0xE50B43444C61746ELLU: // liz_Latn_CD
+ case 0x812B41554C61746ELLU: // lja_Latn_AU
+ case 0x912B49444C61746ELLU: // lje_Latn_ID
+ case 0xA12B49444C61746ELLU: // lji_Latn_ID
+ case 0xAD2B49444C61746ELLU: // ljl_Latn_ID
+ case 0xBD2B49444C61746ELLU: // ljp_Latn_ID
+ case 0xD92B41554C61746ELLU: // ljw_Latn_AU
+ case 0xDD2B41554C61746ELLU: // ljx_Latn_AU
+ case 0x814B544C4C61746ELLU: // lka_Latn_TL
+ case 0x854B4B454C61746ELLU: // lkb_Latn_KE
+ case 0x894B564E4C61746ELLU: // lkc_Latn_VN
+ case 0x8D4B42524C61746ELLU: // lkd_Latn_BR
+ case 0x914B55474C61746ELLU: // lke_Latn_UG
+ case 0x9D4B425454696274LLU: // lkh_Tibt_BT
+ case 0xA14B495241726162LLU: // lki_Arab_IR
+ case 0xA54B4D594C61746ELLU: // lkj_Latn_MY
+ case 0xAD4B50474C61746ELLU: // lkl_Latn_PG
+ case 0xB14B41554C61746ELLU: // lkm_Latn_AU
+ case 0xB54B56554C61746ELLU: // lkn_Latn_VU
+ case 0xB94B4B454C61746ELLU: // lko_Latn_KE
+ case 0xC54B53534C61746ELLU: // lkr_Latn_SS
+ case 0xC94B4B454C61746ELLU: // lks_Latn_KE
+ case 0xCD4B55534C61746ELLU: // lkt_Latn_US
+ case 0xD14B41554C61746ELLU: // lku_Latn_AU
+ case 0xE14B53534C61746ELLU: // lky_Latn_SS
+ case 0x816B4E474C61746ELLU: // lla_Latn_NG
+ case 0x856B4D5A4C61746ELLU: // llb_Latn_MZ
+ case 0x896B474E4C61746ELLU: // llc_Latn_GN
+ case 0x8D6B49544C61746ELLU: // lld_Latn_IT
+ case 0x916B50474C61746ELLU: // lle_Latn_PG
+ case 0x956B50474C61746ELLU: // llf_Latn_PG
+ case 0x996B49444C61746ELLU: // llg_Latn_ID
+ case 0xA16B43474C61746ELLU: // lli_Latn_CG
+ case 0xA56B41554C61746ELLU: // llj_Latn_AU
+ case 0xA96B4D594C61746ELLU: // llk_Latn_MY
+ case 0xAD6B50474C61746ELLU: // lll_Latn_PG
+ case 0xB16B49444C61746ELLU: // llm_Latn_ID
+ case 0xB56B54444C61746ELLU: // lln_Latn_TD
+ case 0xBD6B56554C61746ELLU: // llp_Latn_VU
+ case 0xC16B49444C61746ELLU: // llq_Latn_ID
+ case 0xD16B53424C61746ELLU: // llu_Latn_SB
+ case 0xDD6B464A4C61746ELLU: // llx_Latn_FJ
+ case 0x818B474E4C61746ELLU: // lma_Latn_GN
+ case 0x858B56554C61746ELLU: // lmb_Latn_VU
+ case 0x898B41554C61746ELLU: // lmc_Latn_AU
+ case 0x8D8B53444C61746ELLU: // lmd_Latn_SD
+ case 0x918B54444C61746ELLU: // lme_Latn_TD
+ case 0x958B49444C61746ELLU: // lmf_Latn_ID
+ case 0x998B50474C61746ELLU: // lmg_Latn_PG
+ case 0x9D8B4E5044657661LLU: // lmh_Deva_NP
+ case 0xA18B43444C61746ELLU: // lmi_Latn_CD
+ case 0xA58B49444C61746ELLU: // lmj_Latn_ID
+ case 0xA98B494E4C61746ELLU: // lmk_Latn_IN
+ case 0xAD8B56554C61746ELLU: // lml_Latn_VU
+ case 0xB58B494E54656C75LLU: // lmn_Telu_IN
+ case 0xB98B49544C61746ELLU: // lmo_Latn_IT
+ case 0xBD8B434D4C61746ELLU: // lmp_Latn_CM
+ case 0xC18B49444C61746ELLU: // lmq_Latn_ID
+ case 0xC58B49444C61746ELLU: // lmr_Latn_ID
+ case 0xD18B56554C61746ELLU: // lmu_Latn_VU
+ case 0xD58B464A4C61746ELLU: // lmv_Latn_FJ
+ case 0xD98B55534C61746ELLU: // lmw_Latn_US
+ case 0xDD8B434D4C61746ELLU: // lmx_Latn_CM
+ case 0xE18B49444C61746ELLU: // lmy_Latn_ID
+ case 0x6C6E43444C61746ELLU: // ln_Latn_CD
+ case 0x81AB43464C61746ELLU: // lna_Latn_CF
+ case 0x85AB4E414C61746ELLU: // lnb_Latn_NA
+ case 0x8DAB49444C61746ELLU: // lnd_Latn_ID
+ case 0x99AB48554C61746ELLU: // lng_Latn_HU
+ case 0x9DAB4D594C61746ELLU: // lnh_Latn_MY
+ case 0xA1AB50474C61746ELLU: // lni_Latn_PG
+ case 0xA5AB41554C61746ELLU: // lnj_Latn_AU
+ case 0xADAB43464C61746ELLU: // lnl_Latn_CF
+ case 0xB1AB50474C61746ELLU: // lnm_Latn_PG
+ case 0xB5AB56554C61746ELLU: // lnn_Latn_VU
+ case 0xC9AB434D4C61746ELLU: // lns_Latn_CM
+ case 0xD1AB4E474C61746ELLU: // lnu_Latn_NG
+ case 0xD9AB41554C61746ELLU: // lnw_Latn_AU
+ case 0xE5AB43444C61746ELLU: // lnz_Latn_CD
+ case 0x6C6F4C414C616F6FLLU: // lo_Laoo_LA
+ case 0x81CB49444C61746ELLU: // loa_Latn_ID
+ case 0x85CB42464C61746ELLU: // lob_Latn_BF
+ case 0x89CB50484C61746ELLU: // loc_Latn_PH
+ case 0x91CB49444C61746ELLU: // loe_Latn_ID
+ case 0x99CB43444C61746ELLU: // log_Latn_CD
+ case 0x9DCB53534C61746ELLU: // loh_Latn_SS
+ case 0xA1CB43494C61746ELLU: // loi_Latn_CI
+ case 0xA5CB50474C61746ELLU: // loj_Latn_PG
+ case 0xA9CB534C4C61746ELLU: // lok_Latn_SL
+ case 0xADCB43444C61746ELLU: // lol_Latn_CD
+ case 0xB1CB4C524C61746ELLU: // lom_Latn_LR
+ case 0xB5CB4D574C61746ELLU: // lon_Latn_MW
+ case 0xB9CB43444C61746ELLU: // loo_Latn_CD
+ case 0xBDCB4E474C61746ELLU: // lop_Latn_NG
+ case 0xC1CB43444C61746ELLU: // loq_Latn_CD
+ case 0xC5CB43494C61746ELLU: // lor_Latn_CI
+ case 0xC9CB50474C61746ELLU: // los_Latn_PG
+ case 0xCDCB53534C61746ELLU: // lot_Latn_SS
+ case 0xD1CB55534C61746ELLU: // lou_Latn_US
+ case 0xD9CB4D594C61746ELLU: // low_Latn_MY
+ case 0xDDCB49444C61746ELLU: // lox_Latn_ID
+ case 0xE1CB4E5044657661LLU: // loy_Deva_NP
+ case 0xE5CB5A4D4C61746ELLU: // loz_Latn_ZM
+ case 0x81EB56554C61746ELLU: // lpa_Latn_VU
+ case 0x91EB49444C61746ELLU: // lpe_Latn_ID
+ case 0xB5EB4D4D4C61746ELLU: // lpn_Latn_MM
+ case 0xB9EB434E506C7264LLU: // lpo_Plrd_CN
+ case 0xDDEB53534C61746ELLU: // lpx_Latn_SS
+ case 0xC60B53534C61746ELLU: // lqr_Latn_SS
+ case 0x822B4D594C61746ELLU: // lra_Latn_MY
+ case 0x8A2B495241726162LLU: // lrc_Arab_IR
+ case 0x9A2B41554C61746ELLU: // lrg_Latn_AU
+ case 0xA22B4B454C61746ELLU: // lri_Latn_KE
+ case 0xAA2B504B41726162LLU: // lrk_Arab_PK
+ case 0xAE2B495241726162LLU: // lrl_Arab_IR
+ case 0xB22B4B454C61746ELLU: // lrm_Latn_KE
+ case 0xB62B49444C61746ELLU: // lrn_Latn_ID
+ case 0xBA2B53444C61746ELLU: // lro_Latn_SD
+ case 0xCE2B49444C61746ELLU: // lrt_Latn_ID
+ case 0xD62B56554C61746ELLU: // lrv_Latn_VU
+ case 0xE62B56554C61746ELLU: // lrz_Latn_VU
+ case 0x824B495241726162LLU: // lsa_Arab_IR
+ case 0x8E4B494C48656272LLU: // lsd_Hebr_IL
+ case 0x924B43444C61746ELLU: // lse_Latn_CD
+ case 0xA24B4D4D4C61746ELLU: // lsi_Latn_MM
+ case 0xB24B55474C61746ELLU: // lsm_Latn_UG
+ case 0xC64B50474C61746ELLU: // lsr_Latn_PG
+ case 0xCA4B504B41726162LLU: // lss_Arab_PK
+ case 0x6C744C544C61746ELLU: // lt_Latn_LT
+ case 0x8A6B434E48616E74LLU: // ltc_Hant_CN
+ case 0x9A6B4C564C61746ELLU: // ltg_Latn_LV
+ case 0x9E6B55474C61746ELLU: // lth_Latn_UG
+ case 0xA26B49444C61746ELLU: // lti_Latn_ID
+ case 0xB66B42524C61746ELLU: // ltn_Latn_BR
+ case 0xBA6B4B454C61746ELLU: // lto_Latn_KE
+ case 0xCA6B4B454C61746ELLU: // lts_Latn_KE
+ case 0xD26B49444C61746ELLU: // ltu_Latn_ID
+ case 0x6C7543444C61746ELLU: // lu_Latn_CD
+ case 0x828B43444C61746ELLU: // lua_Latn_CD
+ case 0x8A8B55474C61746ELLU: // luc_Latn_UG
+ case 0x8E8B52554C61746ELLU: // lud_Latn_RU
+ case 0x928B5A4D4C61746ELLU: // lue_Latn_ZM
+ case 0x968B50474C61746ELLU: // luf_Latn_PG
+ case 0xA28B55534C61746ELLU: // lui_Latn_US
+ case 0xA68B43444C61746ELLU: // luj_Latn_CD
+ case 0xAA8B425454696274LLU: // luk_Tibt_BT
+ case 0xAE8B53534C61746ELLU: // lul_Latn_SS
+ case 0xB28B414F4C61746ELLU: // lum_Latn_AO
+ case 0xB68B5A4D4C61746ELLU: // lun_Latn_ZM
+ case 0xBA8B4B454C61746ELLU: // luo_Latn_KE
+ case 0xBE8B47414C61746ELLU: // lup_Latn_GA
+ case 0xC28B43554C61746ELLU: // luq_Latn_CU
+ case 0xC68B49444C61746ELLU: // lur_Latn_ID
+ case 0xCA8B494E4C61746ELLU: // lus_Latn_IN
+ case 0xCE8B55534C61746ELLU: // lut_Latn_US
+ case 0xD28B4E5044657661LLU: // luu_Deva_NP
+ case 0xD68B4F4D41726162LLU: // luv_Arab_OM
+ case 0xDA8B434D4C61746ELLU: // luw_Latn_CM
+ case 0xE28B4B454C61746ELLU: // luy_Latn_KE
+ case 0xE68B495241726162LLU: // luz_Arab_IR
+ case 0x6C764C564C61746ELLU: // lv_Latn_LV
+ case 0x82AB544C4C61746ELLU: // lva_Latn_TL
+ case 0xA2AB4C414C61746ELLU: // lvi_Latn_LA
+ case 0xAAAB53424C61746ELLU: // lvk_Latn_SB
+ case 0xAEAB43444C61746ELLU: // lvl_Latn_CD
+ case 0xD2AB49444C61746ELLU: // lvu_Latn_ID
+ case 0x82CB43444C61746ELLU: // lwa_Latn_CD
+ case 0x92CB49444C61746ELLU: // lwe_Latn_ID
+ case 0x9ACB4B454C61746ELLU: // lwg_Latn_KE
+ case 0x9ECB564E4C61746ELLU: // lwh_Latn_VN
+ case 0xAECB544854686169LLU: // lwl_Thai_TH
+ case 0xB2CB434E54686169LLU: // lwm_Thai_CN
+ case 0xBACB53534C61746ELLU: // lwo_Latn_SS
+ case 0xCECB49444C61746ELLU: // lwt_Latn_ID
+ case 0xDACB56554C61746ELLU: // lww_Latn_VU
+ case 0xB2EB50474C61746ELLU: // lxm_Latn_PG
+ case 0x830B425454696274LLU: // lya_Tibt_BT
+ case 0xB70B5A4D4C61746ELLU: // lyn_Latn_ZM
+ case 0x9F2B434E48616E73LLU: // lzh_Hans_CN
+ case 0xAF2B56554C61746ELLU: // lzl_Latn_VU
+ case 0xB72B4D4D4C61746ELLU: // lzn_Latn_MM
+ case 0xE72B54524C61746ELLU: // lzz_Latn_TR
+ case 0x800C4D584C61746ELLU: // maa_Latn_MX
+ case 0x840C4D584C61746ELLU: // mab_Latn_MX
+ case 0x8C0C49444C61746ELLU: // mad_Latn_ID
+ case 0x900C4E474C61746ELLU: // mae_Latn_NG
+ case 0x940C434D4C61746ELLU: // maf_Latn_CM
+ case 0x980C494E44657661LLU: // mag_Deva_IN
+ case 0xA00C494E44657661LLU: // mai_Deva_IN
+ case 0xA40C4D584C61746ELLU: // maj_Latn_MX
+ case 0xA80C49444C61746ELLU: // mak_Latn_ID
+ case 0xB00C47544C61746ELLU: // mam_Latn_GT
+ case 0xB40C474D4C61746ELLU: // man_Latn_GM
+ case 0xB40C474E4E6B6F6FLLU: // man_Nkoo_GN
+ case 0xC00C4D584C61746ELLU: // maq_Latn_MX
+ case 0xC80C4B454C61746ELLU: // mas_Latn_KE
+ case 0xCC0C4D584C61746ELLU: // mat_Latn_MX
+ case 0xD00C4D584C61746ELLU: // mau_Latn_MX
+ case 0xD40C42524C61746ELLU: // mav_Latn_BR
+ case 0xD80C47484C61746ELLU: // maw_Latn_GH
+ case 0xDC0C49444C61746ELLU: // max_Latn_ID
+ case 0xE40C4D584C61746ELLU: // maz_Latn_MX
+ case 0x802C50484C61746ELLU: // mba_Latn_PH
+ case 0x842C50484C61746ELLU: // mbb_Latn_PH
+ case 0x882C42524C61746ELLU: // mbc_Latn_BR
+ case 0x8C2C50484C61746ELLU: // mbd_Latn_PH
+ case 0x942C53474C61746ELLU: // mbf_Latn_SG
+ case 0x9C2C50474C61746ELLU: // mbh_Latn_PG
+ case 0xA02C50484C61746ELLU: // mbi_Latn_PH
+ case 0xA42C42524C61746ELLU: // mbj_Latn_BR
+ case 0xA82C50474C61746ELLU: // mbk_Latn_PG
+ case 0xAC2C42524C61746ELLU: // mbl_Latn_BR
+ case 0xB02C43474C61746ELLU: // mbm_Latn_CG
+ case 0xB42C434F4C61746ELLU: // mbn_Latn_CO
+ case 0xB82C434D4C61746ELLU: // mbo_Latn_CM
+ case 0xBC2C434F4C61746ELLU: // mbp_Latn_CO
+ case 0xC02C50474C61746ELLU: // mbq_Latn_PG
+ case 0xC42C434F4C61746ELLU: // mbr_Latn_CO
+ case 0xC82C50484C61746ELLU: // mbs_Latn_PH
+ case 0xCC2C50484C61746ELLU: // mbt_Latn_PH
+ case 0xD02C4E474C61746ELLU: // mbu_Latn_NG
+ case 0xD42C474E4C61746ELLU: // mbv_Latn_GN
+ case 0xD82C50474C61746ELLU: // mbw_Latn_PG
+ case 0xDC2C50474C61746ELLU: // mbx_Latn_PG
+ case 0xE02C504B41726162LLU: // mby_Arab_PK
+ case 0xE42C4D584C61746ELLU: // mbz_Latn_MX
+ case 0x804C50594C61746ELLU: // mca_Latn_PY
+ case 0x844C50454C61746ELLU: // mcb_Latn_PE
+ case 0x884C50474C61746ELLU: // mcc_Latn_PG
+ case 0x8C4C50454C61746ELLU: // mcd_Latn_PE
+ case 0x904C4D584C61746ELLU: // mce_Latn_MX
+ case 0x944C50454C61746ELLU: // mcf_Latn_PE
+ case 0x984C56454C61746ELLU: // mcg_Latn_VE
+ case 0x9C4C56454C61746ELLU: // mch_Latn_VE
+ case 0xA04C50474C61746ELLU: // mci_Latn_PG
+ case 0xA44C4E474C61746ELLU: // mcj_Latn_NG
+ case 0xA84C414F4C61746ELLU: // mck_Latn_AO
+ case 0xAC4C434F4C61746ELLU: // mcl_Latn_CO
+ case 0xB04C4D594C61746ELLU: // mcm_Latn_MY
+ case 0xB44C54444C61746ELLU: // mcn_Latn_TD
+ case 0xB84C4D584C61746ELLU: // mco_Latn_MX
+ case 0xBC4C434D4C61746ELLU: // mcp_Latn_CM
+ case 0xC04C50474C61746ELLU: // mcq_Latn_PG
+ case 0xC44C50474C61746ELLU: // mcr_Latn_PG
+ case 0xC84C434D4C61746ELLU: // mcs_Latn_CM
+ case 0xCC4C434D4C61746ELLU: // mct_Latn_CM
+ case 0xD04C434D4C61746ELLU: // mcu_Latn_CM
+ case 0xD44C50474C61746ELLU: // mcv_Latn_PG
+ case 0xD84C54444C61746ELLU: // mcw_Latn_TD
+ case 0xDC4C43464C61746ELLU: // mcx_Latn_CF
+ case 0xE04C50474C61746ELLU: // mcy_Latn_PG
+ case 0xE44C50474C61746ELLU: // mcz_Latn_PG
+ case 0x806C4E474C61746ELLU: // mda_Latn_NG
+ case 0x846C50474C61746ELLU: // mdb_Latn_PG
+ case 0x886C50474C61746ELLU: // mdc_Latn_PG
+ case 0x8C6C434D4C61746ELLU: // mdd_Latn_CM
+ case 0x906C544441726162LLU: // mde_Arab_TD
+ case 0x946C52554379726CLLU: // mdf_Cyrl_RU
+ case 0x986C54444C61746ELLU: // mdg_Latn_TD
+ case 0x9C6C50484C61746ELLU: // mdh_Latn_PH
+ case 0xA06C43444C61746ELLU: // mdi_Latn_CD
+ case 0xA46C43444C61746ELLU: // mdj_Latn_CD
+ case 0xA86C43444C61746ELLU: // mdk_Latn_CD
+ case 0xB06C43444C61746ELLU: // mdm_Latn_CD
+ case 0xB46C43464C61746ELLU: // mdn_Latn_CF
+ case 0xBC6C43444C61746ELLU: // mdp_Latn_CD
+ case 0xC06C43444C61746ELLU: // mdq_Latn_CD
+ case 0xC46C49444C61746ELLU: // mdr_Latn_ID
+ case 0xC86C50474C61746ELLU: // mds_Latn_PG
+ case 0xCC6C43474C61746ELLU: // mdt_Latn_CG
+ case 0xD06C43474C61746ELLU: // mdu_Latn_CG
+ case 0xD46C4D584C61746ELLU: // mdv_Latn_MX
+ case 0xD86C43474C61746ELLU: // mdw_Latn_CG
+ case 0xDC6C455445746869LLU: // mdx_Ethi_ET
+ case 0xE06C455445746869LLU: // mdy_Ethi_ET
+ case 0xE46C42524C61746ELLU: // mdz_Latn_BR
+ case 0x808C434D4C61746ELLU: // mea_Latn_CM
+ case 0x848C50474C61746ELLU: // meb_Latn_PG
+ case 0x888C41554C61746ELLU: // mec_Latn_AU
+ case 0x8C8C50474C61746ELLU: // med_Latn_PG
+ case 0x908C50474C61746ELLU: // mee_Latn_PG
+ case 0x9C8C4D584C61746ELLU: // meh_Latn_MX
+ case 0xA48C49444C61746ELLU: // mej_Latn_ID
+ case 0xA88C50474C61746ELLU: // mek_Latn_PG
+ case 0xAC8C4D594C61746ELLU: // mel_Latn_MY
+ case 0xB08C41554C61746ELLU: // mem_Latn_AU
+ case 0xB48C534C4C61746ELLU: // men_Latn_SL
+ case 0xB88C4D594C61746ELLU: // meo_Latn_MY
+ case 0xBC8C41554C61746ELLU: // mep_Latn_AU
+ case 0xC08C434D4C61746ELLU: // meq_Latn_CM
+ case 0xC48C4B454C61746ELLU: // mer_Latn_KE
+ case 0xC88C54444C61746ELLU: // mes_Latn_TD
+ case 0xCC8C50474C61746ELLU: // met_Latn_PG
+ case 0xD08C50474C61746ELLU: // meu_Latn_PG
+ case 0xD48C4C524C61746ELLU: // mev_Latn_LR
+ case 0xD88C4E474C61746ELLU: // mew_Latn_NG
+ case 0xE08C534E4C61746ELLU: // mey_Latn_SN
+ case 0xE48C55534C61746ELLU: // mez_Latn_US
+ case 0x80AC544841726162LLU: // mfa_Arab_TH
+ case 0x84AC49444C61746ELLU: // mfb_Latn_ID
+ case 0x88AC43444C61746ELLU: // mfc_Latn_CD
+ case 0x8CAC434D4C61746ELLU: // mfd_Latn_CM
+ case 0x90AC4D554C61746ELLU: // mfe_Latn_MU
+ case 0x94AC434D4C61746ELLU: // mff_Latn_CM
+ case 0x98AC474E4C61746ELLU: // mfg_Latn_GN
+ case 0x9CAC434D4C61746ELLU: // mfh_Latn_CM
+ case 0xA0AC434D41726162LLU: // mfi_Arab_CM
+ case 0xA4AC434D4C61746ELLU: // mfj_Latn_CM
+ case 0xA8AC434D4C61746ELLU: // mfk_Latn_CM
+ case 0xACAC4E474C61746ELLU: // mfl_Latn_NG
+ case 0xB0AC4E474C61746ELLU: // mfm_Latn_NG
+ case 0xB4AC4E474C61746ELLU: // mfn_Latn_NG
+ case 0xB8AC4E474C61746ELLU: // mfo_Latn_NG
+ case 0xBCAC49444C61746ELLU: // mfp_Latn_ID
+ case 0xC0AC54474C61746ELLU: // mfq_Latn_TG
+ case 0xC4AC41554C61746ELLU: // mfr_Latn_AU
+ case 0xCCAC50474C61746ELLU: // mft_Latn_PG
+ case 0xD0AC414F4C61746ELLU: // mfu_Latn_AO
+ case 0xD4AC534E4C61746ELLU: // mfv_Latn_SN
+ case 0xD8AC50474C61746ELLU: // mfw_Latn_PG
+ case 0xDCAC45544C61746ELLU: // mfx_Latn_ET
+ case 0xE0AC4D584C61746ELLU: // mfy_Latn_MX
+ case 0xE4AC53534C61746ELLU: // mfz_Latn_SS
+ case 0x6D674D474C61746ELLU: // mg_Latn_MG
+ case 0x80CC49454C617467LLU: // mga_Latg_IE
+ case 0x84CC54444C61746ELLU: // mgb_Latn_TD
+ case 0x88CC53534C61746ELLU: // mgc_Latn_SS
+ case 0x8CCC53534C61746ELLU: // mgd_Latn_SS
+ case 0x90CC54444C61746ELLU: // mge_Latn_TD
+ case 0x94CC49444C61746ELLU: // mgf_Latn_ID
+ case 0x98CC434D4C61746ELLU: // mgg_Latn_CM
+ case 0x9CCC4D5A4C61746ELLU: // mgh_Latn_MZ
+ case 0xA0CC4E474C61746ELLU: // mgi_Latn_NG
+ case 0xA4CC4E474C61746ELLU: // mgj_Latn_NG
+ case 0xA8CC49444C61746ELLU: // mgk_Latn_ID
+ case 0xACCC50474C61746ELLU: // mgl_Latn_PG
+ case 0xB0CC544C4C61746ELLU: // mgm_Latn_TL
+ case 0xB4CC43464C61746ELLU: // mgn_Latn_CF
+ case 0xB8CC434D4C61746ELLU: // mgo_Latn_CM
+ case 0xBCCC4E5044657661LLU: // mgp_Deva_NP
+ case 0xC0CC545A4C61746ELLU: // mgq_Latn_TZ
+ case 0xC4CC5A4D4C61746ELLU: // mgr_Latn_ZM
+ case 0xC8CC545A4C61746ELLU: // mgs_Latn_TZ
+ case 0xCCCC50474C61746ELLU: // mgt_Latn_PG
+ case 0xD0CC50474C61746ELLU: // mgu_Latn_PG
+ case 0xD4CC545A4C61746ELLU: // mgv_Latn_TZ
+ case 0xD8CC545A4C61746ELLU: // mgw_Latn_TZ
+ case 0xE0CC545A4C61746ELLU: // mgy_Latn_TZ
+ case 0xE4CC545A4C61746ELLU: // mgz_Latn_TZ
+ case 0x6D684D484C61746ELLU: // mh_Latn_MH
+ case 0x84EC47414C61746ELLU: // mhb_Latn_GA
+ case 0x88EC4D584C61746ELLU: // mhc_Latn_MX
+ case 0x8CEC545A4C61746ELLU: // mhd_Latn_TZ
+ case 0x90EC4D594C61746ELLU: // mhe_Latn_MY
+ case 0x94EC50474C61746ELLU: // mhf_Latn_PG
+ case 0x98EC41554C61746ELLU: // mhg_Latn_AU
+ case 0xA0EC55474C61746ELLU: // mhi_Latn_UG
+ case 0xA4EC414641726162LLU: // mhj_Arab_AF
+ case 0xA8EC434D4C61746ELLU: // mhk_Latn_CM
+ case 0xACEC50474C61746ELLU: // mhl_Latn_PG
+ case 0xB0EC4D5A4C61746ELLU: // mhm_Latn_MZ
+ case 0xB4EC49544C61746ELLU: // mhn_Latn_IT
+ case 0xB8EC5A4D4C61746ELLU: // mho_Latn_ZM
+ case 0xBCEC49444C61746ELLU: // mhp_Latn_ID
+ case 0xC0EC55534C61746ELLU: // mhq_Latn_US
+ case 0xC8EC49444C61746ELLU: // mhs_Latn_ID
+ case 0xCCEC56454C61746ELLU: // mht_Latn_VE
+ case 0xD0EC494E4C61746ELLU: // mhu_Latn_IN
+ case 0xD8EC42574C61746ELLU: // mhw_Latn_BW
+ case 0xDCEC4D4D4C61746ELLU: // mhx_Latn_MM
+ case 0xE0EC49444C61746ELLU: // mhy_Latn_ID
+ case 0xE4EC49444C61746ELLU: // mhz_Latn_ID
+ case 0x6D694E5A4C61746ELLU: // mi_Latn_NZ
+ case 0x810C55534C61746ELLU: // mia_Latn_US
+ case 0x850C4D584C61746ELLU: // mib_Latn_MX
+ case 0x890C43414C61746ELLU: // mic_Latn_CA
+ case 0x8D0C49514D616E64LLU: // mid_Mand_IQ
+ case 0x910C4D584C61746ELLU: // mie_Latn_MX
+ case 0x950C434D4C61746ELLU: // mif_Latn_CM
+ case 0x990C4D584C61746ELLU: // mig_Latn_MX
+ case 0x9D0C4D584C61746ELLU: // mih_Latn_MX
+ case 0xA10C4D584C61746ELLU: // mii_Latn_MX
+ case 0xA50C434D4C61746ELLU: // mij_Latn_CM
+ case 0xA90C55534C61746ELLU: // mik_Latn_US
+ case 0xAD0C4D584C61746ELLU: // mil_Latn_MX
+ case 0xB10C4D584C61746ELLU: // mim_Latn_MX
+ case 0xB50C49444C61746ELLU: // min_Latn_ID
+ case 0xB90C4D584C61746ELLU: // mio_Latn_MX
+ case 0xBD0C4D584C61746ELLU: // mip_Latn_MX
+ case 0xC10C4E494C61746ELLU: // miq_Latn_NI
+ case 0xC50C4D584C61746ELLU: // mir_Latn_MX
+ case 0xCD0C4D584C61746ELLU: // mit_Latn_MX
+ case 0xD10C4D584C61746ELLU: // miu_Latn_MX
+ case 0xD90C50474C61746ELLU: // miw_Latn_PG
+ case 0xDD0C4D584C61746ELLU: // mix_Latn_MX
+ case 0xE10C4D584C61746ELLU: // miy_Latn_MX
+ case 0xE50C4D584C61746ELLU: // miz_Latn_MX
+ case 0x852C544C4C61746ELLU: // mjb_Latn_TL
+ case 0x892C4D584C61746ELLU: // mjc_Latn_MX
+ case 0x8D2C55534C61746ELLU: // mjd_Latn_US
+ case 0x912C54444C61746ELLU: // mje_Latn_TD
+ case 0x992C434E4C61746ELLU: // mjg_Latn_CN
+ case 0x9D2C545A4C61746ELLU: // mjh_Latn_TZ
+ case 0xA12C434E4C61746ELLU: // mji_Latn_CN
+ case 0xA52C50474C61746ELLU: // mjj_Latn_PG
+ case 0xA92C50474C61746ELLU: // mjk_Latn_PG
+ case 0xAD2C494E44657661LLU: // mjl_Deva_IN
+ case 0xB12C50474C61746ELLU: // mjm_Latn_PG
+ case 0xB52C50474C61746ELLU: // mjn_Latn_PG
+ case 0xC12C494E4D6C796DLLU: // mjq_Mlym_IN
+ case 0xC52C494E4D6C796DLLU: // mjr_Mlym_IN
+ case 0xC92C4E474C61746ELLU: // mjs_Latn_NG
+ case 0xCD2C494E44657661LLU: // mjt_Deva_IN
+ case 0xD12C494E54656C75LLU: // mju_Telu_IN
+ case 0xD52C494E4D6C796DLLU: // mjv_Mlym_IN
+ case 0xD92C494E4C61746ELLU: // mjw_Latn_IN
+ case 0xDD2C42444C61746ELLU: // mjx_Latn_BD
+ case 0xE12C55534C61746ELLU: // mjy_Latn_US
+ case 0xE52C4E5044657661LLU: // mjz_Deva_NP
+ case 0x6D6B4D4B4379726CLLU: // mk_Cyrl_MK
+ case 0x814C43494C61746ELLU: // mka_Latn_CI
+ case 0x854C494E44657661LLU: // mkb_Deva_IN
+ case 0x894C50474C61746ELLU: // mkc_Latn_PG
+ case 0x914C494E44657661LLU: // mke_Deva_IN
+ case 0x954C4E474C61746ELLU: // mkf_Latn_NG
+ case 0xA14C504B41726162LLU: // mki_Arab_PK
+ case 0xA54C464D4C61746ELLU: // mkj_Latn_FM
+ case 0xA94C434D4C61746ELLU: // mkk_Latn_CM
+ case 0xAD4C424A4C61746ELLU: // mkl_Latn_BJ
+ case 0xB14C544854686169LLU: // mkm_Thai_TH
+ case 0xB54C49444C61746ELLU: // mkn_Latn_ID
+ case 0xB94C4E474C61746ELLU: // mko_Latn_NG
+ case 0xBD4C50474C61746ELLU: // mkp_Latn_PG
+ case 0xC54C50474C61746ELLU: // mkr_Latn_PG
+ case 0xC94C4D584C61746ELLU: // mks_Latn_MX
+ case 0xCD4C4E434C61746ELLU: // mkt_Latn_NC
+ case 0xD14C474E4C61746ELLU: // mku_Latn_GN
+ case 0xD54C56554C61746ELLU: // mkv_Latn_VU
+ case 0xD94C43474C61746ELLU: // mkw_Latn_CG
+ case 0xDD4C50484C61746ELLU: // mkx_Latn_PH
+ case 0xE14C49444C61746ELLU: // mky_Latn_ID
+ case 0xE54C544C4C61746ELLU: // mkz_Latn_TL
+ case 0x6D6C494E4D6C796DLLU: // ml_Mlym_IN
+ case 0x816C56554C61746ELLU: // mla_Latn_VU
+ case 0x856C434D4C61746ELLU: // mlb_Latn_CM
+ case 0x896C564E4C61746ELLU: // mlc_Latn_VN
+ case 0x916C50474C61746ELLU: // mle_Latn_PG
+ case 0x956C4C4154686169LLU: // mlf_Thai_LA
+ case 0x9D6C50474C61746ELLU: // mlh_Latn_PG
+ case 0xA16C49444C61746ELLU: // mli_Latn_ID
+ case 0xA56C54444C61746ELLU: // mlj_Latn_TD
+ case 0xA96C4B454C61746ELLU: // mlk_Latn_KE
+ case 0xAD6C56554C61746ELLU: // mll_Latn_VU
+ case 0xB56C53424C61746ELLU: // mln_Latn_SB
+ case 0xB96C534E4C61746ELLU: // mlo_Latn_SN
+ case 0xBD6C50474C61746ELLU: // mlp_Latn_PG
+ case 0xC16C534E4C61746ELLU: // mlq_Latn_SN
+ case 0xC56C434D4C61746ELLU: // mlr_Latn_CM
+ case 0xC96C53444C61746ELLU: // mls_Latn_SD
+ case 0xD16C53424C61746ELLU: // mlu_Latn_SB
+ case 0xD56C56554C61746ELLU: // mlv_Latn_VU
+ case 0xD96C434D4C61746ELLU: // mlw_Latn_CM
+ case 0xDD6C56554C61746ELLU: // mlx_Latn_VU
+ case 0xE56C50484C61746ELLU: // mlz_Latn_PH
+ case 0x818C4E474C61746ELLU: // mma_Latn_NG
+ case 0x858C49444C61746ELLU: // mmb_Latn_ID
+ case 0x898C4D584C61746ELLU: // mmc_Latn_MX
+ case 0x8D8C434E4C61746ELLU: // mmd_Latn_CN
+ case 0x918C56554C61746ELLU: // mme_Latn_VU
+ case 0x958C4E474C61746ELLU: // mmf_Latn_NG
+ case 0x998C56554C61746ELLU: // mmg_Latn_VU
+ case 0x9D8C42524C61746ELLU: // mmh_Latn_BR
+ case 0xA18C50474C61746ELLU: // mmi_Latn_PG
+ case 0xB18C56554C61746ELLU: // mmm_Latn_VU
+ case 0xB58C50484C61746ELLU: // mmn_Latn_PH
+ case 0xB98C50474C61746ELLU: // mmo_Latn_PG
+ case 0xBD8C50474C61746ELLU: // mmp_Latn_PG
+ case 0xC18C50474C61746ELLU: // mmq_Latn_PG
+ case 0xC58C434E4C61746ELLU: // mmr_Latn_CN
+ case 0xCD8C50474C61746ELLU: // mmt_Latn_PG
+ case 0xD18C434D4C61746ELLU: // mmu_Latn_CM
+ case 0xD58C42524C61746ELLU: // mmv_Latn_BR
+ case 0xD98C56554C61746ELLU: // mmw_Latn_VU
+ case 0xDD8C50474C61746ELLU: // mmx_Latn_PG
+ case 0xE18C54444C61746ELLU: // mmy_Latn_TD
+ case 0xE58C43444C61746ELLU: // mmz_Latn_CD
+ case 0x6D6E4D4E4379726CLLU: // mn_Cyrl_MN
+ case 0x6D6E434E4D6F6E67LLU: // mn_Mong_CN
+ case 0x81AC50474C61746ELLU: // mna_Latn_PG
+ case 0x85AC49444C61746ELLU: // mnb_Latn_ID
+ case 0x89AC434E4D6F6E67LLU: // mnc_Mong_CN
+ case 0x8DAC42524C61746ELLU: // mnd_Latn_BR
+ case 0x91AC54444C61746ELLU: // mne_Latn_TD
+ case 0x95AC434D4C61746ELLU: // mnf_Latn_CM
+ case 0x99AC564E4C61746ELLU: // mng_Latn_VN
+ case 0x9DAC43444C61746ELLU: // mnh_Latn_CD
+ case 0xA1AC494E42656E67LLU: // mni_Beng_IN
+ case 0xA5AC414641726162LLU: // mnj_Arab_AF
+ case 0xADAC56554C61746ELLU: // mnl_Latn_VU
+ case 0xB1AC50474C61746ELLU: // mnm_Latn_PG
+ case 0xB5AC564E4C61746ELLU: // mnn_Latn_VN
+ case 0xBDAC434E4C61746ELLU: // mnp_Latn_CN
+ case 0xC1AC4D594C61746ELLU: // mnq_Latn_MY
+ case 0xC5AC55534C61746ELLU: // mnr_Latn_US
+ case 0xC9AC52554379726CLLU: // mns_Cyrl_RU
+ case 0xD1AC49444C61746ELLU: // mnu_Latn_ID
+ case 0xD5AC53424C61746ELLU: // mnv_Latn_SB
+ case 0xD9AC4D4D4D796D72LLU: // mnw_Mymr_MM
+ case 0xDDAC49444C61746ELLU: // mnx_Latn_ID
+ case 0xE1AC4D5A4C61746ELLU: // mny_Latn_MZ
+ case 0xE5AC49444C61746ELLU: // mnz_Latn_ID
+ case 0x6D6F524F4C61746ELLU: // mo_Latn_RO
+ case 0x81CC43494C61746ELLU: // moa_Latn_CI
+ case 0x89CC41524C61746ELLU: // moc_Latn_AR
+ case 0x8DCC55534C61746ELLU: // mod_Latn_US
+ case 0x91CC43414C61746ELLU: // moe_Latn_CA
+ case 0x99CC49444C61746ELLU: // mog_Latn_ID
+ case 0x9DCC43414C61746ELLU: // moh_Latn_CA
+ case 0xA1CC4E474C61746ELLU: // moi_Latn_NG
+ case 0xA5CC43474C61746ELLU: // moj_Latn_CG
+ case 0xA9CC49444C61746ELLU: // mok_Latn_ID
+ case 0xB1CC4E494C61746ELLU: // mom_Latn_NI
+ case 0xB9CC564E4C61746ELLU: // moo_Latn_VN
+ case 0xBDCC425A4C61746ELLU: // mop_Latn_BZ
+ case 0xC1CC49444C61746ELLU: // moq_Latn_ID
+ case 0xC5CC53444C61746ELLU: // mor_Latn_SD
+ case 0xC9CC42464C61746ELLU: // mos_Latn_BF
+ case 0xCDCC434F4C61746ELLU: // mot_Latn_CO
+ case 0xD1CC54444C61746ELLU: // mou_Latn_TD
+ case 0xD5CC55534C61746ELLU: // mov_Latn_US
+ case 0xD9CC43474C61746ELLU: // mow_Latn_CG
+ case 0xDDCC50474C61746ELLU: // mox_Latn_PG
+ case 0xE1CC45544C61746ELLU: // moy_Latn_ET
+ case 0xE5CC54444C61746ELLU: // moz_Latn_TD
+ case 0x81EC545A4C61746ELLU: // mpa_Latn_TZ
+ case 0x85EC41554C61746ELLU: // mpb_Latn_AU
+ case 0x89EC41554C61746ELLU: // mpc_Latn_AU
+ case 0x8DEC42524C61746ELLU: // mpd_Latn_BR
+ case 0x91EC45544C61746ELLU: // mpe_Latn_ET
+ case 0x99EC54444C61746ELLU: // mpg_Latn_TD
+ case 0x9DEC41554C61746ELLU: // mph_Latn_AU
+ case 0xA1EC434D4C61746ELLU: // mpi_Latn_CM
+ case 0xA5EC41554C61746ELLU: // mpj_Latn_AU
+ case 0xA9EC54444C61746ELLU: // mpk_Latn_TD
+ case 0xADEC50474C61746ELLU: // mpl_Latn_PG
+ case 0xB1EC4D584C61746ELLU: // mpm_Latn_MX
+ case 0xB5EC50474C61746ELLU: // mpn_Latn_PG
+ case 0xB9EC50474C61746ELLU: // mpo_Latn_PG
+ case 0xBDEC50474C61746ELLU: // mpp_Latn_PG
+ case 0xC1EC42524C61746ELLU: // mpq_Latn_BR
+ case 0xC5EC53424C61746ELLU: // mpr_Latn_SB
+ case 0xC9EC50474C61746ELLU: // mps_Latn_PG
+ case 0xCDEC50474C61746ELLU: // mpt_Latn_PG
+ case 0xD1EC42524C61746ELLU: // mpu_Latn_BR
+ case 0xD5EC50474C61746ELLU: // mpv_Latn_PG
+ case 0xD9EC42524C61746ELLU: // mpw_Latn_BR
+ case 0xDDEC50474C61746ELLU: // mpx_Latn_PG
+ case 0xE1EC49444C61746ELLU: // mpy_Latn_ID
+ case 0xE5EC544854686169LLU: // mpz_Thai_TH
+ case 0x820C49444C61746ELLU: // mqa_Latn_ID
+ case 0x860C434D4C61746ELLU: // mqb_Latn_CM
+ case 0x8A0C49444C61746ELLU: // mqc_Latn_ID
+ case 0x920C50474C61746ELLU: // mqe_Latn_PG
+ case 0x960C49444C61746ELLU: // mqf_Latn_ID
+ case 0x9A0C49444C61746ELLU: // mqg_Latn_ID
+ case 0x9E0C4D584C61746ELLU: // mqh_Latn_MX
+ case 0xA20C49444C61746ELLU: // mqi_Latn_ID
+ case 0xA60C49444C61746ELLU: // mqj_Latn_ID
+ case 0xAA0C50484C61746ELLU: // mqk_Latn_PH
+ case 0xAE0C424A4C61746ELLU: // mql_Latn_BJ
+ case 0xB20C50464C61746ELLU: // mqm_Latn_PF
+ case 0xB60C49444C61746ELLU: // mqn_Latn_ID
+ case 0xBA0C49444C61746ELLU: // mqo_Latn_ID
+ case 0xBE0C49444C61746ELLU: // mqp_Latn_ID
+ case 0xC20C4D594C61746ELLU: // mqq_Latn_MY
+ case 0xC60C49444C61746ELLU: // mqr_Latn_ID
+ case 0xCA0C49444C61746ELLU: // mqs_Latn_ID
+ case 0xD20C53534C61746ELLU: // mqu_Latn_SS
+ case 0xD60C50474C61746ELLU: // mqv_Latn_PG
+ case 0xDA0C50474C61746ELLU: // mqw_Latn_PG
+ case 0xDE0C49444C61746ELLU: // mqx_Latn_ID
+ case 0xE20C49444C61746ELLU: // mqy_Latn_ID
+ case 0xE60C50474C61746ELLU: // mqz_Latn_PG
+ case 0x6D72494E44657661LLU: // mr_Deva_IN
+ case 0x822C544854686169LLU: // mra_Thai_TH
+ case 0x862C56554C61746ELLU: // mrb_Latn_VU
+ case 0x8A2C55534C61746ELLU: // mrc_Latn_US
+ case 0x8E2C4E5044657661LLU: // mrd_Deva_NP
+ case 0x962C49444C61746ELLU: // mrf_Latn_ID
+ case 0x9A2C494E4C61746ELLU: // mrg_Latn_IN
+ case 0x9E2C494E4C61746ELLU: // mrh_Latn_IN
+ case 0xA62C52554379726CLLU: // mrj_Cyrl_RU
+ case 0xAA2C4E434C61746ELLU: // mrk_Latn_NC
+ case 0xAE2C464D4C61746ELLU: // mrl_Latn_FM
+ case 0xB22C56554C61746ELLU: // mrm_Latn_VU
+ case 0xB62C53424C61746ELLU: // mrn_Latn_SB
+ case 0xBA2C42444D726F6FLLU: // mro_Mroo_BD
+ case 0xBE2C56554C61746ELLU: // mrp_Latn_VU
+ case 0xC22C50464C61746ELLU: // mrq_Latn_PF
+ case 0xC62C494E44657661LLU: // mrr_Deva_IN
+ case 0xCA2C56554C61746ELLU: // mrs_Latn_VU
+ case 0xCE2C4E474C61746ELLU: // mrt_Latn_NG
+ case 0xD22C434D4C61746ELLU: // mru_Latn_CM
+ case 0xD62C50464C61746ELLU: // mrv_Latn_PF
+ case 0xDA2C50484C61746ELLU: // mrw_Latn_PH
+ case 0xDE2C49444C61746ELLU: // mrx_Latn_ID
+ case 0xE22C50484C61746ELLU: // mry_Latn_PH
+ case 0xE62C49444C61746ELLU: // mrz_Latn_ID
+ case 0x6D734D594C61746ELLU: // ms_Latn_MY
+ case 0x864C50484C61746ELLU: // msb_Latn_PH
+ case 0x8A4C474E4C61746ELLU: // msc_Latn_GN
+ case 0x924C54444C61746ELLU: // mse_Latn_TD
+ case 0x964C49444C61746ELLU: // msf_Latn_ID
+ case 0x9A4C49444C61746ELLU: // msg_Latn_ID
+ case 0x9E4C4D474C61746ELLU: // msh_Latn_MG
+ case 0xA24C4D594C61746ELLU: // msi_Latn_MY
+ case 0xA64C43444C61746ELLU: // msj_Latn_CD
+ case 0xAA4C50484C61746ELLU: // msk_Latn_PH
+ case 0xAE4C49444C61746ELLU: // msl_Latn_ID
+ case 0xB24C50484C61746ELLU: // msm_Latn_PH
+ case 0xB64C56554C61746ELLU: // msn_Latn_VU
+ case 0xBA4C49444C61746ELLU: // mso_Latn_ID
+ case 0xBE4C42524C61746ELLU: // msp_Latn_BR
+ case 0xC24C4E434C61746ELLU: // msq_Latn_NC
+ case 0xCA4C49444C61746ELLU: // mss_Latn_ID
+ case 0xD24C50474C61746ELLU: // msu_Latn_PG
+ case 0xD64C434D4C61746ELLU: // msv_Latn_CM
+ case 0xDA4C47574C61746ELLU: // msw_Latn_GW
+ case 0xDE4C50474C61746ELLU: // msx_Latn_PG
+ case 0xE24C50474C61746ELLU: // msy_Latn_PG
+ case 0xE64C50474C61746ELLU: // msz_Latn_PG
+ case 0x6D744D544C61746ELLU: // mt_Latn_MT
+ case 0x826C50484C61746ELLU: // mta_Latn_PH
+ case 0x866C43494C61746ELLU: // mtb_Latn_CI
+ case 0x8A6C50474C61746ELLU: // mtc_Latn_PG
+ case 0x8E6C49444C61746ELLU: // mtd_Latn_ID
+ case 0x926C53424C61746ELLU: // mte_Latn_SB
+ case 0x966C50474C61746ELLU: // mtf_Latn_PG
+ case 0x9A6C49444C61746ELLU: // mtg_Latn_ID
+ case 0x9E6C49444C61746ELLU: // mth_Latn_ID
+ case 0xA26C50474C61746ELLU: // mti_Latn_PG
+ case 0xA66C49444C61746ELLU: // mtj_Latn_ID
+ case 0xAA6C434D4C61746ELLU: // mtk_Latn_CM
+ case 0xAE6C4E474C61746ELLU: // mtl_Latn_NG
+ case 0xB26C52554379726CLLU: // mtm_Cyrl_RU
+ case 0xB66C4E494C61746ELLU: // mtn_Latn_NI
+ case 0xBA6C4D584C61746ELLU: // mto_Latn_MX
+ case 0xBE6C424F4C61746ELLU: // mtp_Latn_BO
+ case 0xC26C564E4C61746ELLU: // mtq_Latn_VN
+ case 0xC66C494E44657661LLU: // mtr_Deva_IN
+ case 0xCA6C50454C61746ELLU: // mts_Latn_PE
+ case 0xCE6C56554C61746ELLU: // mtt_Latn_VU
+ case 0xD26C4D584C61746ELLU: // mtu_Latn_MX
+ case 0xD66C50474C61746ELLU: // mtv_Latn_PG
+ case 0xDA6C50484C61746ELLU: // mtw_Latn_PH
+ case 0xDE6C4D584C61746ELLU: // mtx_Latn_MX
+ case 0xE26C50474C61746ELLU: // mty_Latn_PG
+ case 0x828C434D4C61746ELLU: // mua_Latn_CM
+ case 0x868C54444C61746ELLU: // mub_Latn_TD
+ case 0x8A8C434D4C61746ELLU: // muc_Latn_CM
+ case 0x8E8C52554379726CLLU: // mud_Cyrl_RU
+ case 0x928C45434C61746ELLU: // mue_Latn_EC
+ case 0x9A8C434D4C61746ELLU: // mug_Latn_CM
+ case 0x9E8C53534C61746ELLU: // muh_Latn_SS
+ case 0xA28C49444C61746ELLU: // mui_Latn_ID
+ case 0xA68C54444C61746ELLU: // muj_Latn_TD
+ case 0xAA8C4E5054696274LLU: // muk_Tibt_NP
+ case 0xB28C50474C61746ELLU: // mum_Latn_PG
+ case 0xBA8C434D4C61746ELLU: // muo_Latn_CM
+ case 0xC28C434E4C61746ELLU: // muq_Latn_CN
+ case 0xC68C53534C61746ELLU: // mur_Latn_SS
+ case 0xCA8C55534C61746ELLU: // mus_Latn_US
+ case 0xCE8C494E44657661LLU: // mut_Deva_IN
+ case 0xD28C4B454C61746ELLU: // muu_Latn_KE
+ case 0xD68C494E54616D6CLLU: // muv_Taml_IN
+ case 0xDE8C50474C61746ELLU: // mux_Latn_PG
+ case 0xE28C434D4C61746ELLU: // muy_Latn_CM
+ case 0xE68C455445746869LLU: // muz_Ethi_ET
+ case 0x82AC50474C61746ELLU: // mva_Latn_PG
+ case 0x8EAC49444C61746ELLU: // mvd_Latn_ID
+ case 0x92AC504B41726162LLU: // mve_Arab_PK
+ case 0x96AC434E4D6F6E67LLU: // mvf_Mong_CN
+ case 0x9AAC4D584C61746ELLU: // mvg_Latn_MX
+ case 0x9EAC54444C61746ELLU: // mvh_Latn_TD
+ case 0xAAAC50474C61746ELLU: // mvk_Latn_PG
+ case 0xAEAC41554C61746ELLU: // mvl_Latn_AU
+ case 0xB6AC50474C61746ELLU: // mvn_Latn_PG
+ case 0xBAAC53424C61746ELLU: // mvo_Latn_SB
+ case 0xBEAC49444C61746ELLU: // mvp_Latn_ID
+ case 0xC2AC50474C61746ELLU: // mvq_Latn_PG
+ case 0xC6AC49444C61746ELLU: // mvr_Latn_ID
+ case 0xCAAC49444C61746ELLU: // mvs_Latn_ID
+ case 0xCEAC56554C61746ELLU: // mvt_Latn_VU
+ case 0xD2AC54444C61746ELLU: // mvu_Latn_TD
+ case 0xD6AC4D594C61746ELLU: // mvv_Latn_MY
+ case 0xDAAC545A4C61746ELLU: // mvw_Latn_TZ
+ case 0xDEAC49444C61746ELLU: // mvx_Latn_ID
+ case 0xE2AC504B41726162LLU: // mvy_Arab_PK
+ case 0xE6AC455445746869LLU: // mvz_Ethi_ET
+ case 0x82CC50474C61746ELLU: // mwa_Latn_PG
+ case 0x86CC50474C61746ELLU: // mwb_Latn_PG
+ case 0x8ACC50474C61746ELLU: // mwc_Latn_PG
+ case 0x92CC545A4C61746ELLU: // mwe_Latn_TZ
+ case 0x96CC41554C61746ELLU: // mwf_Latn_AU
+ case 0x9ACC50474C61746ELLU: // mwg_Latn_PG
+ case 0x9ECC50474C61746ELLU: // mwh_Latn_PG
+ case 0xA2CC56554C61746ELLU: // mwi_Latn_VU
+ case 0xAACC4D4C4C61746ELLU: // mwk_Latn_ML
+ case 0xAECC50544C61746ELLU: // mwl_Latn_PT
+ case 0xB2CC54444C61746ELLU: // mwm_Latn_TD
+ case 0xB6CC5A4D4C61746ELLU: // mwn_Latn_ZM
+ case 0xBACC56554C61746ELLU: // mwo_Latn_VU
+ case 0xBECC41554C61746ELLU: // mwp_Latn_AU
+ case 0xC2CC4D4D4C61746ELLU: // mwq_Latn_MM
+ case 0xC6CC494E44657661LLU: // mwr_Deva_IN
+ case 0xCACC4B454C61746ELLU: // mws_Latn_KE
+ case 0xCECC4D4D4D796D72LLU: // mwt_Mymr_MM
+ case 0xD2CC53534C61746ELLU: // mwu_Latn_SS
+ case 0xD6CC49444C61746ELLU: // mwv_Latn_ID
+ case 0xDACC5553486D6E70LLU: // mww_Hmnp_US
+ case 0xE6CC43444C61746ELLU: // mwz_Latn_CD
+ case 0x82EC4D584C61746ELLU: // mxa_Latn_MX
+ case 0x86EC4D584C61746ELLU: // mxb_Latn_MX
+ case 0x8AEC5A574C61746ELLU: // mxc_Latn_ZW
+ case 0x8EEC49444C61746ELLU: // mxd_Latn_ID
+ case 0x92EC56554C61746ELLU: // mxe_Latn_VU
+ case 0x96EC434D4C61746ELLU: // mxf_Latn_CM
+ case 0x9AEC414F4C61746ELLU: // mxg_Latn_AO
+ case 0x9EEC43444C61746ELLU: // mxh_Latn_CD
+ case 0xA2EC45534C61746ELLU: // mxi_Latn_ES
+ case 0xA6EC494E4C61746ELLU: // mxj_Latn_IN
+ case 0xAAEC50474C61746ELLU: // mxk_Latn_PG
+ case 0xAEEC424A4C61746ELLU: // mxl_Latn_BJ
+ case 0xB2EC50474C61746ELLU: // mxm_Latn_PG
+ case 0xB6EC49444C61746ELLU: // mxn_Latn_ID
+ case 0xBAEC5A4D4C61746ELLU: // mxo_Latn_ZM
+ case 0xBEEC4D584C61746ELLU: // mxp_Latn_MX
+ case 0xC2EC4D584C61746ELLU: // mxq_Latn_MX
+ case 0xC6EC4D594C61746ELLU: // mxr_Latn_MY
+ case 0xCAEC4D584C61746ELLU: // mxs_Latn_MX
+ case 0xCEEC4D584C61746ELLU: // mxt_Latn_MX
+ case 0xD2EC434D4C61746ELLU: // mxu_Latn_CM
+ case 0xD6EC4D584C61746ELLU: // mxv_Latn_MX
+ case 0xDAEC50474C61746ELLU: // mxw_Latn_PG
+ case 0xDEEC43494C61746ELLU: // mxx_Latn_CI
+ case 0xE2EC4D584C61746ELLU: // mxy_Latn_MX
+ case 0xE6EC49444C61746ELLU: // mxz_Latn_ID
+ case 0x6D794D4D4D796D72LLU: // my_Mymr_MM
+ case 0x870C54444C61746ELLU: // myb_Latn_TD
+ case 0x8B0C43444C61746ELLU: // myc_Latn_CD
+ case 0x930C47414C61746ELLU: // mye_Latn_GA
+ case 0x970C45544C61746ELLU: // myf_Latn_ET
+ case 0x9B0C434D4C61746ELLU: // myg_Latn_CM
+ case 0x9F0C55534C61746ELLU: // myh_Latn_US
+ case 0xA70C53534C61746ELLU: // myj_Latn_SS
+ case 0xAB0C4D4C4C61746ELLU: // myk_Latn_ML
+ case 0xAF0C49444C61746ELLU: // myl_Latn_ID
+ case 0xB30C455445746869LLU: // mym_Ethi_ET
+ case 0xBF0C42524C61746ELLU: // myp_Latn_BR
+ case 0xC70C50454C61746ELLU: // myr_Latn_PE
+ case 0xD30C42524C61746ELLU: // myu_Latn_BR
+ case 0xD70C52554379726CLLU: // myv_Cyrl_RU
+ case 0xDB0C50474C61746ELLU: // myw_Latn_PG
+ case 0xDF0C55474C61746ELLU: // myx_Latn_UG
+ case 0xE30C434F4C61746ELLU: // myy_Latn_CO
+ case 0xE70C49524D616E64LLU: // myz_Mand_IR
+ case 0x832C4D584C61746ELLU: // mza_Latn_MX
+ case 0x8F2C434D4C61746ELLU: // mzd_Latn_CM
+ case 0x932C50474C61746ELLU: // mze_Latn_PG
+ case 0x9F2C41524C61746ELLU: // mzh_Latn_AR
+ case 0xA32C4D584C61746ELLU: // mzi_Latn_MX
+ case 0xA72C4C524C61746ELLU: // mzj_Latn_LR
+ case 0xAB2C4E474C61746ELLU: // mzk_Latn_NG
+ case 0xAF2C4D584C61746ELLU: // mzl_Latn_MX
+ case 0xB32C4E474C61746ELLU: // mzm_Latn_NG
+ case 0xB72C495241726162LLU: // mzn_Arab_IR
+ case 0xBB2C42524C61746ELLU: // mzo_Latn_BR
+ case 0xBF2C424F4C61746ELLU: // mzp_Latn_BO
+ case 0xC32C49444C61746ELLU: // mzq_Latn_ID
+ case 0xC72C42524C61746ELLU: // mzr_Latn_BR
+ case 0xCF2C4D594C61746ELLU: // mzt_Latn_MY
+ case 0xD32C50474C61746ELLU: // mzu_Latn_PG
+ case 0xD72C43464C61746ELLU: // mzv_Latn_CF
+ case 0xDB2C47484C61746ELLU: // mzw_Latn_GH
+ case 0xDF2C47594C61746ELLU: // mzx_Latn_GY
+ case 0xE72C50474C61746ELLU: // mzz_Latn_PG
+ case 0x6E614E524C61746ELLU: // na_Latn_NR
+ case 0x800D49444C61746ELLU: // naa_Latn_ID
+ case 0x840D42524C61746ELLU: // nab_Latn_BR
+ case 0x880D50474C61746ELLU: // nac_Latn_PG
+ case 0x900D49444C61746ELLU: // nae_Latn_ID
+ case 0x940D50474C61746ELLU: // naf_Latn_PG
+ case 0x980D494E4C61746ELLU: // nag_Latn_IN
+ case 0xA40D474E4C61746ELLU: // naj_Latn_GN
+ case 0xA80D50474C61746ELLU: // nak_Latn_PG
+ case 0xAC0D50474C61746ELLU: // nal_Latn_PG
+ case 0xB00D41554C61746ELLU: // nam_Latn_AU
+ case 0xB40D434E48616E73LLU: // nan_Hans_CN
+ case 0xB80D4E5044657661LLU: // nao_Deva_NP
+ case 0xBC0D49544C61746ELLU: // nap_Latn_IT
+ case 0xC00D4E414C61746ELLU: // naq_Latn_NA
+ case 0xC40D4E474C61746ELLU: // nar_Latn_NG
+ case 0xC80D50474C61746ELLU: // nas_Latn_PG
+ case 0xCC0D4E474C61746ELLU: // nat_Latn_NG
+ case 0xD80D47484C61746ELLU: // naw_Latn_GH
+ case 0xDC0D50474C61746ELLU: // nax_Latn_PG
+ case 0xE00D41554C61746ELLU: // nay_Latn_AU
+ case 0xE40D4D584C61746ELLU: // naz_Latn_MX
+ case 0x6E624E4F4C61746ELLU: // nb_Latn_NO
+ case 0x802D414F4C61746ELLU: // nba_Latn_AO
+ case 0x842D4E474C61746ELLU: // nbb_Latn_NG
+ case 0x882D494E4C61746ELLU: // nbc_Latn_IN
+ case 0x8C2D43444C61746ELLU: // nbd_Latn_CD
+ case 0x902D494E4C61746ELLU: // nbe_Latn_IN
+ case 0x9C2D4E474C61746ELLU: // nbh_Latn_NG
+ case 0xA02D494E4C61746ELLU: // nbi_Latn_IN
+ case 0xA42D41554C61746ELLU: // nbj_Latn_AU
+ case 0xA82D50474C61746ELLU: // nbk_Latn_PG
+ case 0xB02D43464C61746ELLU: // nbm_Latn_CF
+ case 0xB42D49444C61746ELLU: // nbn_Latn_ID
+ case 0xB82D4E474C61746ELLU: // nbo_Latn_NG
+ case 0xBC2D4E474C61746ELLU: // nbp_Latn_NG
+ case 0xC02D49444C61746ELLU: // nbq_Latn_ID
+ case 0xC42D4E474C61746ELLU: // nbr_Latn_NG
+ case 0xCC2D494E4C61746ELLU: // nbt_Latn_IN
+ case 0xD02D494E4C61746ELLU: // nbu_Latn_IN
+ case 0xD42D434D4C61746ELLU: // nbv_Latn_CM
+ case 0xD82D43444C61746ELLU: // nbw_Latn_CD
+ case 0xE02D50474C61746ELLU: // nby_Latn_PG
+ case 0x804D50474C61746ELLU: // nca_Latn_PG
+ case 0x844D494E4C61746ELLU: // ncb_Latn_IN
+ case 0x884D50474C61746ELLU: // ncc_Latn_PG
+ case 0x8C4D4E5044657661LLU: // ncd_Deva_NP
+ case 0x904D50474C61746ELLU: // nce_Latn_PG
+ case 0x944D50474C61746ELLU: // ncf_Latn_PG
+ case 0x984D43414C61746ELLU: // ncg_Latn_CA
+ case 0x9C4D4D584C61746ELLU: // nch_Latn_MX
+ case 0xA04D4D584C61746ELLU: // nci_Latn_MX
+ case 0xA44D4D584C61746ELLU: // ncj_Latn_MX
+ case 0xA84D41554C61746ELLU: // nck_Latn_AU
+ case 0xAC4D4D584C61746ELLU: // ncl_Latn_MX
+ case 0xB04D50474C61746ELLU: // ncm_Latn_PG
+ case 0xB44D50474C61746ELLU: // ncn_Latn_PG
+ case 0xB84D50474C61746ELLU: // nco_Latn_PG
+ case 0xC04D4C414C616F6FLLU: // ncq_Laoo_LA
+ case 0xC44D434D4C61746ELLU: // ncr_Latn_CM
+ case 0xCC4D494E4C61746ELLU: // nct_Latn_IN
+ case 0xD04D47484C61746ELLU: // ncu_Latn_GH
+ case 0xDC4D4D584C61746ELLU: // ncx_Latn_MX
+ case 0xE44D55534C61746ELLU: // ncz_Latn_US
+ case 0x6E645A574C61746ELLU: // nd_Latn_ZW
+ case 0x806D43474C61746ELLU: // nda_Latn_CG
+ case 0x846D434D4C61746ELLU: // ndb_Latn_CM
+ case 0x886D4D5A4C61746ELLU: // ndc_Latn_MZ
+ case 0x8C6D4E474C61746ELLU: // ndd_Latn_NG
+ case 0x946D52554379726CLLU: // ndf_Cyrl_RU
+ case 0x986D545A4C61746ELLU: // ndg_Latn_TZ
+ case 0x9C6D545A4C61746ELLU: // ndh_Latn_TZ
+ case 0xA06D4E474C61746ELLU: // ndi_Latn_NG
+ case 0xA46D545A4C61746ELLU: // ndj_Latn_TZ
+ case 0xA86D43444C61746ELLU: // ndk_Latn_CD
+ case 0xAC6D43444C61746ELLU: // ndl_Latn_CD
+ case 0xB06D54444C61746ELLU: // ndm_Latn_TD
+ case 0xB46D43474C61746ELLU: // ndn_Latn_CG
+ case 0xBC6D55474C61746ELLU: // ndp_Latn_UG
+ case 0xC06D414F4C61746ELLU: // ndq_Latn_AO
+ case 0xC46D4E474C61746ELLU: // ndr_Latn_NG
+ case 0xC86D44454C61746ELLU: // nds_Latn_DE
+ case 0xCC6D43444C61746ELLU: // ndt_Latn_CD
+ case 0xD06D434D4C61746ELLU: // ndu_Latn_CM
+ case 0xD46D534E4C61746ELLU: // ndv_Latn_SN
+ case 0xD86D43444C61746ELLU: // ndw_Latn_CD
+ case 0xDC6D49444C61746ELLU: // ndx_Latn_ID
+ case 0xE06D43464C61746ELLU: // ndy_Latn_CF
+ case 0xE46D53534C61746ELLU: // ndz_Latn_SS
+ case 0x6E654E5044657661LLU: // ne_Deva_NP
+ case 0x808D49444C61746ELLU: // nea_Latn_ID
+ case 0x848D43494C61746ELLU: // neb_Latn_CI
+ case 0x888D49444C61746ELLU: // nec_Latn_ID
+ case 0x8C8D4E474C61746ELLU: // ned_Latn_NG
+ case 0x908D4E434C61746ELLU: // nee_Latn_NC
+ case 0x988D52554379726CLLU: // neg_Cyrl_RU
+ case 0x9C8D425454696274LLU: // neh_Tibt_BT
+ case 0xA08D545258737578LLU: // nei_Xsux_TR
+ case 0xA48D50474C61746ELLU: // nej_Latn_PG
+ case 0xA88D4E434C61746ELLU: // nek_Latn_NC
+ case 0xB08D4E434C61746ELLU: // nem_Latn_NC
+ case 0xB48D4E434C61746ELLU: // nen_Latn_NC
+ case 0xB88D564E4C61746ELLU: // neo_Latn_VN
+ case 0xC08D4D584C61746ELLU: // neq_Latn_MX
+ case 0xC48D49444C61746ELLU: // ner_Latn_ID
+ case 0xCC8D50474C61746ELLU: // net_Latn_PG
+ case 0xD88D4E5044657661LLU: // new_Deva_NP
+ case 0xDC8D50474C61746ELLU: // nex_Latn_PG
+ case 0xE08D43494C61746ELLU: // ney_Latn_CI
+ case 0xE48D55534C61746ELLU: // nez_Latn_US
+ case 0x80AD49444C61746ELLU: // nfa_Latn_ID
+ case 0x8CAD4E474C61746ELLU: // nfd_Latn_NG
+ case 0xACAD53424C61746ELLU: // nfl_Latn_SB
+ case 0xC4AD47484C61746ELLU: // nfr_Latn_GH
+ case 0xD0AD434D4C61746ELLU: // nfu_Latn_CM
+ case 0x6E674E414C61746ELLU: // ng_Latn_NA
+ case 0x80CD43444C61746ELLU: // nga_Latn_CD
+ case 0x84CD43444C61746ELLU: // ngb_Latn_CD
+ case 0x88CD43444C61746ELLU: // ngc_Latn_CD
+ case 0x8CCD43464C61746ELLU: // ngd_Latn_CF
+ case 0x90CD434D4C61746ELLU: // nge_Latn_CM
+ case 0x98CD43464C61746ELLU: // ngg_Latn_CF
+ case 0x9CCD5A414C61746ELLU: // ngh_Latn_ZA
+ case 0xA0CD4E474C61746ELLU: // ngi_Latn_NG
+ case 0xA4CD434D4C61746ELLU: // ngj_Latn_CM
+ case 0xA8CD41554C61746ELLU: // ngk_Latn_AU
+ case 0xACCD4D5A4C61746ELLU: // ngl_Latn_MZ
+ case 0xB0CD464D4C61746ELLU: // ngm_Latn_FM
+ case 0xB4CD434D4C61746ELLU: // ngn_Latn_CM
+ case 0xBCCD545A4C61746ELLU: // ngp_Latn_TZ
+ case 0xC0CD545A4C61746ELLU: // ngq_Latn_TZ
+ case 0xC4CD53424C61746ELLU: // ngr_Latn_SB
+ case 0xC8CD4E474C61746ELLU: // ngs_Latn_NG
+ case 0xCCCD4C414C616F6FLLU: // ngt_Laoo_LA
+ case 0xD0CD4D584C61746ELLU: // ngu_Latn_MX
+ case 0xD4CD434D4C61746ELLU: // ngv_Latn_CM
+ case 0xD8CD4E474C61746ELLU: // ngw_Latn_NG
+ case 0xDCCD4E474C61746ELLU: // ngx_Latn_NG
+ case 0xE0CD434D4C61746ELLU: // ngy_Latn_CM
+ case 0xE4CD43474C61746ELLU: // ngz_Latn_CG
+ case 0x80ED41554C61746ELLU: // nha_Latn_AU
+ case 0x84ED43494C61746ELLU: // nhb_Latn_CI
+ case 0x88ED4D584C61746ELLU: // nhc_Latn_MX
+ case 0x8CED50594C61746ELLU: // nhd_Latn_PY
+ case 0x90ED4D584C61746ELLU: // nhe_Latn_MX
+ case 0x94ED41554C61746ELLU: // nhf_Latn_AU
+ case 0x98ED4D584C61746ELLU: // nhg_Latn_MX
+ case 0xA0ED4D584C61746ELLU: // nhi_Latn_MX
+ case 0xA8ED4D584C61746ELLU: // nhk_Latn_MX
+ case 0xB0ED4D584C61746ELLU: // nhm_Latn_MX
+ case 0xB4ED4D584C61746ELLU: // nhn_Latn_MX
+ case 0xB8ED50474C61746ELLU: // nho_Latn_PG
+ case 0xBCED4D584C61746ELLU: // nhp_Latn_MX
+ case 0xC0ED4D584C61746ELLU: // nhq_Latn_MX
+ case 0xC4ED42574C61746ELLU: // nhr_Latn_BW
+ case 0xCCED4D584C61746ELLU: // nht_Latn_MX
+ case 0xD0ED434D4C61746ELLU: // nhu_Latn_CM
+ case 0xD4ED4D584C61746ELLU: // nhv_Latn_MX
+ case 0xD8ED4D584C61746ELLU: // nhw_Latn_MX
+ case 0xDCED4D584C61746ELLU: // nhx_Latn_MX
+ case 0xE0ED4D584C61746ELLU: // nhy_Latn_MX
+ case 0xE4ED4D584C61746ELLU: // nhz_Latn_MX
+ case 0x810D49444C61746ELLU: // nia_Latn_ID
+ case 0x850D50474C61746ELLU: // nib_Latn_PG
+ case 0x8D0D41554C61746ELLU: // nid_Latn_AU
+ case 0x910D54444C61746ELLU: // nie_Latn_TD
+ case 0x950D50474C61746ELLU: // nif_Latn_PG
+ case 0x990D41554C61746ELLU: // nig_Latn_AU
+ case 0x9D0D545A4C61746ELLU: // nih_Latn_TZ
+ case 0xA10D50474C61746ELLU: // nii_Latn_PG
+ case 0xA50D49444C61746ELLU: // nij_Latn_ID
+ case 0xAD0D49444C61746ELLU: // nil_Latn_ID
+ case 0xB10D545A4C61746ELLU: // nim_Latn_TZ
+ case 0xB50D4E474C61746ELLU: // nin_Latn_NG
+ case 0xB90D52554379726CLLU: // nio_Cyrl_RU
+ case 0xC10D4B454C61746ELLU: // niq_Latn_KE
+ case 0xC50D49444C61746ELLU: // nir_Latn_ID
+ case 0xC90D50474C61746ELLU: // nis_Latn_PG
+ case 0xCD0D494E54656C75LLU: // nit_Telu_IN
+ case 0xD10D4E554C61746ELLU: // niu_Latn_NU
+ case 0xD50D52554379726CLLU: // niv_Cyrl_RU
+ case 0xD90D50474C61746ELLU: // niw_Latn_PG
+ case 0xDD0D43444C61746ELLU: // nix_Latn_CD
+ case 0xE10D43444C61746ELLU: // niy_Latn_CD
+ case 0xE50D50474C61746ELLU: // niz_Latn_PG
+ case 0x812D4E474C61746ELLU: // nja_Latn_NG
+ case 0x852D494E4C61746ELLU: // njb_Latn_IN
+ case 0x8D2D545A4C61746ELLU: // njd_Latn_TZ
+ case 0x9D2D494E4C61746ELLU: // njh_Latn_IN
+ case 0xA12D41554C61746ELLU: // nji_Latn_AU
+ case 0xA52D434D4C61746ELLU: // njj_Latn_CM
+ case 0xAD2D53534C61746ELLU: // njl_Latn_SS
+ case 0xB12D494E4C61746ELLU: // njm_Latn_IN
+ case 0xB52D494E4C61746ELLU: // njn_Latn_IN
+ case 0xB92D494E4C61746ELLU: // njo_Latn_IN
+ case 0xC52D4E474C61746ELLU: // njr_Latn_NG
+ case 0xC92D49444C61746ELLU: // njs_Latn_ID
+ case 0xCD2D53524C61746ELLU: // njt_Latn_SR
+ case 0xD12D41554C61746ELLU: // nju_Latn_AU
+ case 0xDD2D43474C61746ELLU: // njx_Latn_CG
+ case 0xE12D434D4C61746ELLU: // njy_Latn_CM
+ case 0xE52D494E4C61746ELLU: // njz_Latn_IN
+ case 0x814D5A4D4C61746ELLU: // nka_Latn_ZM
+ case 0x854D494E4C61746ELLU: // nkb_Latn_IN
+ case 0x894D434D4C61746ELLU: // nkc_Latn_CM
+ case 0x8D4D494E4C61746ELLU: // nkd_Latn_IN
+ case 0x914D53424C61746ELLU: // nke_Latn_SB
+ case 0x954D494E4C61746ELLU: // nkf_Latn_IN
+ case 0x994D50474C61746ELLU: // nkg_Latn_PG
+ case 0x9D4D494E4C61746ELLU: // nkh_Latn_IN
+ case 0xA14D494E4C61746ELLU: // nki_Latn_IN
+ case 0xA54D49444C61746ELLU: // nkj_Latn_ID
+ case 0xA94D56554C61746ELLU: // nkk_Latn_VU
+ case 0xB14D50474C61746ELLU: // nkm_Latn_PG
+ case 0xB54D414F4C61746ELLU: // nkn_Latn_AO
+ case 0xB94D47484C61746ELLU: // nko_Latn_GH
+ case 0xC14D47484C61746ELLU: // nkq_Latn_GH
+ case 0xC54D464D4C61746ELLU: // nkr_Latn_FM
+ case 0xC94D49444C61746ELLU: // nks_Latn_ID
+ case 0xCD4D545A4C61746ELLU: // nkt_Latn_TZ
+ case 0xD14D43494C61746ELLU: // nku_Latn_CI
+ case 0xD54D4D574C61746ELLU: // nkv_Latn_MW
+ case 0xD94D43444C61746ELLU: // nkw_Latn_CD
+ case 0xDD4D4E474C61746ELLU: // nkx_Latn_NG
+ case 0xE54D4E474C61746ELLU: // nkz_Latn_NG
+ case 0x6E6C4E4C4C61746ELLU: // nl_Latn_NL
+ case 0x816D434D4C61746ELLU: // nla_Latn_CM
+ case 0x896D49444C61746ELLU: // nlc_Latn_ID
+ case 0x916D4B454C61746ELLU: // nle_Latn_KE
+ case 0x996D53424C61746ELLU: // nlg_Latn_SB
+ case 0xA16D414641726162LLU: // nli_Arab_AF
+ case 0xA56D43444C61746ELLU: // nlj_Latn_CD
+ case 0xA96D49444C61746ELLU: // nlk_Latn_ID
+ case 0xB16D504B41726162LLU: // nlm_Arab_PK
+ case 0xB96D43444C61746ELLU: // nlo_Latn_CD
+ case 0xC16D4D4D4C61746ELLU: // nlq_Latn_MM
+ case 0xD16D47484C61746ELLU: // nlu_Latn_GH
+ case 0xD56D4D584C61746ELLU: // nlv_Latn_MX
+ case 0xD96D41554C61746ELLU: // nlw_Latn_AU
+ case 0xDD6D494E44657661LLU: // nlx_Deva_IN
+ case 0xE16D41554C61746ELLU: // nly_Latn_AU
+ case 0xE56D53424C61746ELLU: // nlz_Latn_SB
+ case 0x818D494E4C61746ELLU: // nma_Latn_IN
+ case 0x858D56554C61746ELLU: // nmb_Latn_VU
+ case 0x898D54444C61746ELLU: // nmc_Latn_TD
+ case 0x8D8D47414C61746ELLU: // nmd_Latn_GA
+ case 0x918D494E4C61746ELLU: // nme_Latn_IN
+ case 0x958D494E4C61746ELLU: // nmf_Latn_IN
+ case 0x998D434D4C61746ELLU: // nmg_Latn_CM
+ case 0x9D8D494E4C61746ELLU: // nmh_Latn_IN
+ case 0xA18D4E474C61746ELLU: // nmi_Latn_NG
+ case 0xA58D43464C61746ELLU: // nmj_Latn_CF
+ case 0xA98D56554C61746ELLU: // nmk_Latn_VU
+ case 0xAD8D434D4C61746ELLU: // nml_Latn_CM
+ case 0xB18D4E5044657661LLU: // nmm_Deva_NP
+ case 0xB58D42574C61746ELLU: // nmn_Latn_BW
+ case 0xB98D494E4C61746ELLU: // nmo_Latn_IN
+ case 0xBD8D41554C61746ELLU: // nmp_Latn_AU
+ case 0xC18D5A574C61746ELLU: // nmq_Latn_ZW
+ case 0xC58D434D4C61746ELLU: // nmr_Latn_CM
+ case 0xC98D56554C61746ELLU: // nms_Latn_VU
+ case 0xCD8D464D4C61746ELLU: // nmt_Latn_FM
+ case 0xD18D55534C61746ELLU: // nmu_Latn_US
+ case 0xD58D41554C61746ELLU: // nmv_Latn_AU
+ case 0xD98D50474C61746ELLU: // nmw_Latn_PG
+ case 0xDD8D50474C61746ELLU: // nmx_Latn_PG
+ case 0xE58D54474C61746ELLU: // nmz_Latn_TG
+ case 0x6E6E4E4F4C61746ELLU: // nn_Latn_NO
+ case 0x81AD41554C61746ELLU: // nna_Latn_AU
+ case 0x85AD43444C61746ELLU: // nnb_Latn_CD
+ case 0x89AD54444C61746ELLU: // nnc_Latn_TD
+ case 0x8DAD56554C61746ELLU: // nnd_Latn_VU
+ case 0x91AD414F4C61746ELLU: // nne_Latn_AO
+ case 0x95AD50474C61746ELLU: // nnf_Latn_PG
+ case 0x99AD494E4C61746ELLU: // nng_Latn_IN
+ case 0x9DAD434D4C61746ELLU: // nnh_Latn_CM
+ case 0xA1AD49444C61746ELLU: // nni_Latn_ID
+ case 0xA5AD45544C61746ELLU: // nnj_Latn_ET
+ case 0xA9AD50474C61746ELLU: // nnk_Latn_PG
+ case 0xADAD494E4C61746ELLU: // nnl_Latn_IN
+ case 0xB1AD50474C61746ELLU: // nnm_Latn_PG
+ case 0xB5AD54444C61746ELLU: // nnn_Latn_TD
+ case 0xBDAD494E5763686FLLU: // nnp_Wcho_IN
+ case 0xC1AD545A4C61746ELLU: // nnq_Latn_TZ
+ case 0xC5AD41554C61746ELLU: // nnr_Latn_AU
+ case 0xCDAD55534C61746ELLU: // nnt_Latn_US
+ case 0xD1AD47484C61746ELLU: // nnu_Latn_GH
+ case 0xD5AD41554C61746ELLU: // nnv_Latn_AU
+ case 0xD9AD42464C61746ELLU: // nnw_Latn_BF
+ case 0xE1AD41554C61746ELLU: // nny_Latn_AU
+ case 0xE5AD434D4C61746ELLU: // nnz_Latn_CM
+ case 0x6E6F4E4F4C61746ELLU: // no_Latn_NO
+ case 0x81CD434F4C61746ELLU: // noa_Latn_CO
+ case 0x89CD50474C61746ELLU: // noc_Latn_PG
+ case 0x8DCD54484C616E61LLU: // nod_Lana_TH
+ case 0x91CD494E44657661LLU: // noe_Deva_IN
+ case 0x95CD50474C61746ELLU: // nof_Latn_PG
+ case 0x99CD52554379726CLLU: // nog_Cyrl_RU
+ case 0x9DCD50474C61746ELLU: // noh_Latn_PG
+ case 0xA1CD494E44657661LLU: // noi_Deva_IN
+ case 0xA5CD434F4C61746ELLU: // noj_Latn_CO
+ case 0xA9CD55534C61746ELLU: // nok_Latn_US
+ case 0xB5CD534552756E72LLU: // non_Runr_SE
+ case 0xBDCD50474C61746ELLU: // nop_Latn_PG
+ case 0xC1CD43444C61746ELLU: // noq_Latn_CD
+ case 0xC9CD434E59696969LLU: // nos_Yiii_CN
+ case 0xCDCD50454C61746ELLU: // not_Latn_PE
+ case 0xD1CD50474C61746ELLU: // nou_Latn_PG
+ case 0xD9CD545A4C61746ELLU: // now_Latn_TZ
+ case 0xE1CD54444C61746ELLU: // noy_Latn_TD
+ case 0x85ED425454696274LLU: // npb_Tibt_BT
+ case 0x99ED4D4D4C61746ELLU: // npg_Latn_MM
+ case 0x9DED494E4C61746ELLU: // nph_Latn_IN
+ case 0xADED4D584C61746ELLU: // npl_Latn_MX
+ case 0xB5ED50474C61746ELLU: // npn_Latn_PG
+ case 0xB9ED494E4C61746ELLU: // npo_Latn_IN
+ case 0xC9ED49444C61746ELLU: // nps_Latn_ID
+ case 0xD1ED494E4C61746ELLU: // npu_Latn_IN
+ case 0xDDED53424C61746ELLU: // npx_Latn_SB
+ case 0xE1ED49444C61746ELLU: // npy_Latn_ID
+ case 0x9A0D424A4C61746ELLU: // nqg_Latn_BJ
+ case 0xAA0D424A4C61746ELLU: // nqk_Latn_BJ
+ case 0xAE0D414F4C61746ELLU: // nql_Latn_AO
+ case 0xB20D49444C61746ELLU: // nqm_Latn_ID
+ case 0xB60D50474C61746ELLU: // nqn_Latn_PG
+ case 0xBA0D474E4E6B6F6FLLU: // nqo_Nkoo_GN
+ case 0xC20D4D4D4C61746ELLU: // nqq_Latn_MM
+ case 0xCE0D4E474C61746ELLU: // nqt_Latn_NG
+ case 0xE20D4D4D4C61746ELLU: // nqy_Latn_MM
+ case 0x6E725A414C61746ELLU: // nr_Latn_ZA
+ case 0x822D47414C61746ELLU: // nra_Latn_GA
+ case 0x862D45524C61746ELLU: // nrb_Latn_ER
+ case 0x922D494E4C61746ELLU: // nre_Latn_IN
+ case 0x962D4A454C61746ELLU: // nrf_Latn_JE
+ case 0x9A2D56554C61746ELLU: // nrg_Latn_VU
+ case 0xA22D494E4C61746ELLU: // nri_Latn_IN
+ case 0xAA2D41554C61746ELLU: // nrk_Latn_AU
+ case 0xAE2D41554C61746ELLU: // nrl_Latn_AU
+ case 0xB22D4D594C61746ELLU: // nrm_Latn_MY
+ case 0xB62D474252756E72LLU: // nrn_Runr_GB
+ case 0xBE2D49544C61746ELLU: // nrp_Latn_IT
+ case 0xD22D434E4C61746ELLU: // nru_Latn_CN
+ case 0xDE2D41554C61746ELLU: // nrx_Latn_AU
+ case 0xE62D50474C61746ELLU: // nrz_Latn_PG
+ case 0x824D494E4C61746ELLU: // nsa_Latn_IN
+ case 0x864D5A414C61746ELLU: // nsb_Latn_ZA
+ case 0x8A4D4E474C61746ELLU: // nsc_Latn_NG
+ case 0x8E4D434E59696969LLU: // nsd_Yiii_CN
+ case 0x924D5A4D4C61746ELLU: // nse_Latn_ZM
+ case 0x964D434E59696969LLU: // nsf_Yiii_CN
+ case 0x9A4D545A4C61746ELLU: // nsg_Latn_TZ
+ case 0x9E4D434D4C61746ELLU: // nsh_Latn_CM
+ case 0xAA4D434143616E73LLU: // nsk_Cans_CA
+ case 0xB24D494E4C61746ELLU: // nsm_Latn_IN
+ case 0xB64D50474C61746ELLU: // nsn_Latn_PG
+ case 0xBA4D5A414C61746ELLU: // nso_Latn_ZA
+ case 0xC24D55534C61746ELLU: // nsq_Latn_US
+ case 0xCA4D50474C61746ELLU: // nss_Latn_PG
+ case 0xCE4D494E546E7361LLU: // nst_Tnsa_IN
+ case 0xD24D4D584C61746ELLU: // nsu_Latn_MX
+ case 0xD64D434E59696969LLU: // nsv_Yiii_CN
+ case 0xDA4D56554C61746ELLU: // nsw_Latn_VU
+ case 0xDE4D414F4C61746ELLU: // nsx_Latn_AO
+ case 0xE24D49444C61746ELLU: // nsy_Latn_ID
+ case 0xE64D55534C61746ELLU: // nsz_Latn_US
+ case 0x8E6D4D594C61746ELLU: // ntd_Latn_MY
+ case 0x926D4D5A4C61746ELLU: // nte_Latn_MZ
+ case 0x9A6D41554C61746ELLU: // ntg_Latn_AU
+ case 0xA26D42464C61746ELLU: // nti_Latn_BF
+ case 0xA66D41554C61746ELLU: // ntj_Latn_AU
+ case 0xAA6D545A4C61746ELLU: // ntk_Latn_TZ
+ case 0xB26D424A4C61746ELLU: // ntm_Latn_BJ
+ case 0xBA6D43444C61746ELLU: // nto_Latn_CD
+ case 0xBE6D4D584C61746ELLU: // ntp_Latn_MX
+ case 0xC66D47484C61746ELLU: // ntr_Latn_GH
+ case 0xD26D53424C61746ELLU: // ntu_Latn_SB
+ case 0xDE6D4D4D4C61746ELLU: // ntx_Latn_MM
+ case 0xE26D564E59696969LLU: // nty_Yiii_VN
+ case 0xE66D495241726162LLU: // ntz_Arab_IR
+ case 0x828D4E434C61746ELLU: // nua_Latn_NC
+ case 0x8A8D42524C61746ELLU: // nuc_Latn_BR
+ case 0x8E8D50474C61746ELLU: // nud_Latn_PG
+ case 0x928D43444C61746ELLU: // nue_Latn_CD
+ case 0x968D434E4C61746ELLU: // nuf_Latn_CN
+ case 0x9A8D41554C61746ELLU: // nug_Latn_AU
+ case 0x9E8D4E474C61746ELLU: // nuh_Latn_NG
+ case 0xA28D47514C61746ELLU: // nui_Latn_GQ
+ case 0xA68D55474C61746ELLU: // nuj_Latn_UG
+ case 0xAA8D43414C61746ELLU: // nuk_Latn_CA
+ case 0xB28D544F4C61746ELLU: // num_Latn_TO
+ case 0xB68D4D4D4C61746ELLU: // nun_Latn_MM
+ case 0xBA8D564E4C61746ELLU: // nuo_Latn_VN
+ case 0xBE8D4E474C61746ELLU: // nup_Latn_NG
+ case 0xC28D50474C61746ELLU: // nuq_Latn_PG
+ case 0xC68D50474C61746ELLU: // nur_Latn_PG
+ case 0xCA8D53534C61746ELLU: // nus_Latn_SS
+ case 0xCE8D564E4C61746ELLU: // nut_Latn_VN
+ case 0xD28D43444C61746ELLU: // nuu_Latn_CD
+ case 0xD68D42464C61746ELLU: // nuv_Latn_BF
+ case 0xDA8D464D4C61746ELLU: // nuw_Latn_FM
+ case 0xDE8D50474C61746ELLU: // nux_Latn_PG
+ case 0xE28D41554C61746ELLU: // nuy_Latn_AU
+ case 0xE68D4D584C61746ELLU: // nuz_Latn_MX
+ case 0x6E7655534C61746ELLU: // nv_Latn_US
+ case 0x9EAD56554C61746ELLU: // nvh_Latn_VU
+ case 0xB2AD50474C61746ELLU: // nvm_Latn_PG
+ case 0xBAAD434D4C61746ELLU: // nvo_Latn_CM
+ case 0x86CD43494C61746ELLU: // nwb_Latn_CI
+ case 0x8ACD4E504E657761LLU: // nwc_Newa_NP
+ case 0x92CD434D4C61746ELLU: // nwe_Latn_CM
+ case 0x9ACD41554C61746ELLU: // nwg_Latn_AU
+ case 0xA2CD56554C61746ELLU: // nwi_Latn_VU
+ case 0xB2CD53534C61746ELLU: // nwm_Latn_SS
+ case 0xBACD41554C61746ELLU: // nwo_Latn_AU
+ case 0xC6CD50474C61746ELLU: // nwr_Latn_PG
+ case 0xDACD545A4C61746ELLU: // nww_Latn_TZ
+ case 0xDECD4E5044657661LLU: // nwx_Deva_NP
+ case 0x82ED544C4C61746ELLU: // nxa_Latn_TL
+ case 0x8EED43444C61746ELLU: // nxd_Latn_CD
+ case 0x92ED49444C61746ELLU: // nxe_Latn_ID
+ case 0x9AED49444C61746ELLU: // nxg_Latn_ID
+ case 0xA2ED545A4C61746ELLU: // nxi_Latn_TZ
+ case 0xAEED49444C61746ELLU: // nxl_Latn_ID
+ case 0xB6ED41554C61746ELLU: // nxn_Latn_AU
+ case 0xBAED47414C61746ELLU: // nxo_Latn_GA
+ case 0xC2ED434E4C61746ELLU: // nxq_Latn_CN
+ case 0xC6ED50474C61746ELLU: // nxr_Latn_PG
+ case 0xDEED49444C61746ELLU: // nxx_Latn_ID
+ case 0x6E794D574C61746ELLU: // ny_Latn_MW
+ case 0x870D47484C61746ELLU: // nyb_Latn_GH
+ case 0x8B0D43444C61746ELLU: // nyc_Latn_CD
+ case 0x8F0D4B454C61746ELLU: // nyd_Latn_KE
+ case 0x930D414F4C61746ELLU: // nye_Latn_AO
+ case 0x970D4B454C61746ELLU: // nyf_Latn_KE
+ case 0x9B0D43444C61746ELLU: // nyg_Latn_CD
+ case 0x9F0D41554C61746ELLU: // nyh_Latn_AU
+ case 0xA30D53444C61746ELLU: // nyi_Latn_SD
+ case 0xA70D43444C61746ELLU: // nyj_Latn_CD
+ case 0xAB0D414F4C61746ELLU: // nyk_Latn_AO
+ case 0xAF0D544854686169LLU: // nyl_Thai_TH
+ case 0xB30D545A4C61746ELLU: // nym_Latn_TZ
+ case 0xB70D55474C61746ELLU: // nyn_Latn_UG
+ case 0xBB0D55474C61746ELLU: // nyo_Latn_UG
+ case 0xBF0D55474C61746ELLU: // nyp_Latn_UG
+ case 0xC30D495241726162LLU: // nyq_Arab_IR
+ case 0xC70D4D574C61746ELLU: // nyr_Latn_MW
+ case 0xCB0D41554C61746ELLU: // nys_Latn_AU
+ case 0xCF0D41554C61746ELLU: // nyt_Latn_AU
+ case 0xD30D4D5A4C61746ELLU: // nyu_Latn_MZ
+ case 0xD70D41554C61746ELLU: // nyv_Latn_AU
+ case 0xDB0D544854686169LLU: // nyw_Thai_TH
+ case 0xDF0D41554C61746ELLU: // nyx_Latn_AU
+ case 0xE30D545A4C61746ELLU: // nyy_Latn_TZ
+ case 0x832D434D4C61746ELLU: // nza_Latn_CM
+ case 0x872D47414C61746ELLU: // nzb_Latn_GA
+ case 0x8F2D43444C61746ELLU: // nzd_Latn_CD
+ case 0xA32D47484C61746ELLU: // nzi_Latn_GH
+ case 0xAB2D43464C61746ELLU: // nzk_Latn_CF
+ case 0xB32D494E4C61746ELLU: // nzm_Latn_IN
+ case 0xC72D4E474C61746ELLU: // nzr_Latn_NG
+ case 0xD32D43474C61746ELLU: // nzu_Latn_CG
+ case 0xE32D54444C61746ELLU: // nzy_Latn_TD
+ case 0xE72D4D4C4C61746ELLU: // nzz_Latn_ML
+ case 0x800E52554379726CLLU: // oaa_Cyrl_RU
+ case 0x880E52554379726CLLU: // oac_Cyrl_RU
+ case 0xC40E535953797263LLU: // oar_Syrc_SY
+ case 0xD40E474547656F72LLU: // oav_Geor_GE
+ case 0xA02E55534C61746ELLU: // obi_Latn_US
+ case 0xA82E50484C61746ELLU: // obk_Latn_PH
+ case 0xAC2E434D4C61746ELLU: // obl_Latn_CM
+ case 0xB02E4A4F50686E78LLU: // obm_Phnx_JO
+ case 0xB82E50484C61746ELLU: // obo_Latn_PH
+ case 0xC42E4D4D4D796D72LLU: // obr_Mymr_MM
+ case 0xCC2E46524C61746ELLU: // obt_Latn_FR
+ case 0xD02E4E474C61746ELLU: // obu_Latn_NG
+ case 0x6F6346524C61746ELLU: // oc_Latn_FR
+ case 0x804E50454C61746ELLU: // oca_Latn_PE
+ case 0xB84E47424C61746ELLU: // oco_Latn_GB
+ case 0xD04E4D584C61746ELLU: // ocu_Latn_MX
+ case 0x806E4E474C61746ELLU: // oda_Latn_NG
+ case 0xA86E504B41726162LLU: // odk_Arab_PK
+ case 0xCC6E4E4C4C61746ELLU: // odt_Latn_NL
+ case 0xD06E4E474C61746ELLU: // odu_Latn_NG
+ case 0xC8AE4E4C4C61746ELLU: // ofs_Latn_NL
+ case 0xD0AE4E474C61746ELLU: // ofu_Latn_NG
+ case 0x84CE4E474C61746ELLU: // ogb_Latn_NG
+ case 0x88CE4E474C61746ELLU: // ogc_Latn_NG
+ case 0x98CE4E474C61746ELLU: // ogg_Latn_NG
+ case 0xB8CE4E474C61746ELLU: // ogo_Latn_NG
+ case 0xD0CE4E474C61746ELLU: // ogu_Latn_NG
+ case 0xCCEE545258737578LLU: // oht_Xsux_TR
+ case 0xD0EE48554C61746ELLU: // ohu_Latn_HU
+ case 0x810E49444C61746ELLU: // oia_Latn_ID
+ case 0x910E53534C61746ELLU: // oie_Latn_SS
+ case 0xB50E50474C61746ELLU: // oin_Latn_PG
+ case 0x6F6A434143616E73LLU: // oj_Cans_CA
+ case 0x852E43414C61746ELLU: // ojb_Latn_CA
+ case 0x892E43414C61746ELLU: // ojc_Latn_CA
+ case 0xC92E434143616E73LLU: // ojs_Cans_CA
+ case 0xD52E53424C61746ELLU: // ojv_Latn_SB
+ case 0xD92E43414C61746ELLU: // ojw_Latn_CA
+ case 0x814E43414C61746ELLU: // oka_Latn_CA
+ case 0x854E4E474C61746ELLU: // okb_Latn_NG
+ case 0x894E43444C61746ELLU: // okc_Latn_CD
+ case 0x8D4E4E474C61746ELLU: // okd_Latn_NG
+ case 0x914E4E474C61746ELLU: // oke_Latn_NG
+ case 0x994E41554C61746ELLU: // okg_Latn_AU
+ case 0xA14E4B454C61746ELLU: // oki_Latn_KE
+ case 0xA94E50474C61746ELLU: // okk_Latn_PG
+ case 0xB14E4B5248616E67LLU: // okm_Hang_KR
+ case 0xB94E4B5248616E69LLU: // oko_Hani_KR
+ case 0xC54E4E474C61746ELLU: // okr_Latn_NG
+ case 0xC94E4E474C61746ELLU: // oks_Latn_NG
+ case 0xD14E434D4C61746ELLU: // oku_Latn_CM
+ case 0xD54E50474C61746ELLU: // okv_Latn_PG
+ case 0xDD4E4E474C61746ELLU: // okx_Latn_NG
+ case 0xE54E4B484B686D72LLU: // okz_Khmr_KH
+ case 0x816E4E5044657661LLU: // ola_Deva_NP
+ case 0x8D6E545A4C61746ELLU: // old_Latn_TZ
+ case 0x916E425454696274LLU: // ole_Tibt_BT
+ case 0xA96E41554C61746ELLU: // olk_Latn_AU
+ case 0xB16E4E474C61746ELLU: // olm_Latn_NG
+ case 0xB96E52554C61746ELLU: // olo_Latn_RU
+ case 0xC56E56554C61746ELLU: // olr_Latn_VU
+ case 0xCD6E4C544C61746ELLU: // olt_Latn_LT
+ case 0xD16E414F4C61746ELLU: // olu_Latn_AO
+ case 0x6F6D45544C61746ELLU: // om_Latn_ET
+ case 0x818E55534C61746ELLU: // oma_Latn_US
+ case 0x858E56554C61746ELLU: // omb_Latn_VU
+ case 0x898E50454C61746ELLU: // omc_Latn_PE
+ case 0x998E50454C61746ELLU: // omg_Latn_PE
+ case 0xA18E43444C61746ELLU: // omi_Latn_CD
+ case 0xA98E52554379726CLLU: // omk_Cyrl_RU
+ case 0xAD8E43444C61746ELLU: // oml_Latn_CD
+ case 0xB98E50474C61746ELLU: // omo_Latn_PG
+ case 0xBD8E494E4D746569LLU: // omp_Mtei_IN
+ case 0xC58E494E4D6F6469LLU: // omr_Modi_IN
+ case 0xCD8E4B454C61746ELLU: // omt_Latn_KE
+ case 0xD18E50454C61746ELLU: // omu_Latn_PE
+ case 0xD98E50474C61746ELLU: // omw_Latn_PG
+ case 0xDD8E4D4D4D796D72LLU: // omx_Mymr_MM
+ case 0x81AE41524C61746ELLU: // ona_Latn_AR
+ case 0x91AE43414C61746ELLU: // one_Latn_CA
+ case 0x99AE50474C61746ELLU: // ong_Latn_PG
+ case 0xA1AE49444C61746ELLU: // oni_Latn_ID
+ case 0xA5AE50474C61746ELLU: // onj_Latn_PG
+ case 0xA9AE50474C61746ELLU: // onk_Latn_PG
+ case 0xB5AE50474C61746ELLU: // onn_Latn_PG
+ case 0xB9AE43414C61746ELLU: // ono_Latn_CA
+ case 0xBDAE494E4C61746ELLU: // onp_Latn_IN
+ case 0xC5AE50474C61746ELLU: // onr_Latn_PG
+ case 0xC9AE50474C61746ELLU: // ons_Latn_PG
+ case 0xCDAE50474C61746ELLU: // ont_Latn_PG
+ case 0xD1AE56554C61746ELLU: // onu_Latn_VU
+ case 0xDDAE49444C61746ELLU: // onx_Latn_ID
+ case 0x8DCE55534C61746ELLU: // ood_Latn_US
+ case 0xB5CE494E44657661LLU: // oon_Deva_IN
+ case 0xC5CE5A414C61746ELLU: // oor_Latn_ZA
+ case 0x81EE4E474C61746ELLU: // opa_Latn_NG
+ case 0xA9EE49444C61746ELLU: // opk_Latn_ID
+ case 0xB1EE50474C61746ELLU: // opm_Latn_PG
+ case 0xB9EE50474C61746ELLU: // opo_Latn_PG
+ case 0xCDEE4D584C61746ELLU: // opt_Latn_MX
+ case 0xE1EE42524C61746ELLU: // opy_Latn_BR
+ case 0x6F72494E4F727961LLU: // or_Orya_IN
+ case 0x822E53424C61746ELLU: // ora_Latn_SB
+ case 0x8A2E4B454C61746ELLU: // orc_Latn_KE
+ case 0x922E50454C61746ELLU: // ore_Latn_PE
+ case 0x9A2E4E474C61746ELLU: // org_Latn_NG
+ case 0xB62E4D594C61746ELLU: // orn_Latn_MY
+ case 0xBA2E50474C61746ELLU: // oro_Latn_PG
+ case 0xC62E4E474C61746ELLU: // orr_Latn_NG
+ case 0xCA2E4D594C61746ELLU: // ors_Latn_MY
+ case 0xCE2E494E54656C75LLU: // ort_Telu_IN
+ case 0xD22E504B41726162LLU: // oru_Arab_PK
+ case 0xD62E52554379726CLLU: // orv_Cyrl_RU
+ case 0xDA2E42524C61746ELLU: // orw_Latn_BR
+ case 0xDE2E4E474C61746ELLU: // orx_Latn_NG
+ case 0xE62E49444C61746ELLU: // orz_Latn_ID
+ case 0x6F7347454379726CLLU: // os_Cyrl_GE
+ case 0x824E55534F736765LLU: // osa_Osge_US
+ case 0x8A4E49544974616CLLU: // osc_Ital_IT
+ case 0xA24E49444A617661LLU: // osi_Java_ID
+ case 0xBA4E4E474C61746ELLU: // oso_Latn_NG
+ case 0xBE4E45534C61746ELLU: // osp_Latn_ES
+ case 0xCE4E434D4C61746ELLU: // ost_Latn_CM
+ case 0xD24E50474C61746ELLU: // osu_Latn_PG
+ case 0xDE4E44454C61746ELLU: // osx_Latn_DE
+ case 0x826E545241726162LLU: // ota_Arab_TR
+ case 0x866E434E54696274LLU: // otb_Tibt_CN
+ case 0x8E6E49444C61746ELLU: // otd_Latn_ID
+ case 0x926E4D584C61746ELLU: // ote_Latn_MX
+ case 0xA26E42524C61746ELLU: // oti_Latn_BR
+ case 0xAA6E4D4E4F726B68LLU: // otk_Orkh_MN
+ case 0xAE6E4D584C61746ELLU: // otl_Latn_MX
+ case 0xB26E4D584C61746ELLU: // otm_Latn_MX
+ case 0xB66E4D584C61746ELLU: // otn_Latn_MX
+ case 0xC26E4D584C61746ELLU: // otq_Latn_MX
+ case 0xC66E53444C61746ELLU: // otr_Latn_SD
+ case 0xCA6E4D584C61746ELLU: // ots_Latn_MX
+ case 0xCE6E4D584C61746ELLU: // ott_Latn_MX
+ case 0xD26E42524C61746ELLU: // otu_Latn_BR
+ case 0xDA6E43414C61746ELLU: // otw_Latn_CA
+ case 0xDE6E4D584C61746ELLU: // otx_Latn_MX
+ case 0xE26E494E4772616ELLU: // oty_Gran_IN
+ case 0xE66E4D584C61746ELLU: // otz_Latn_MX
+ case 0x868E4C524C61746ELLU: // oub_Latn_LR
+ case 0x928E50474C61746ELLU: // oue_Latn_PG
+ case 0xA28E434E4F756772LLU: // oui_Ougr_CN
+ case 0xB28E50474C61746ELLU: // oum_Latn_PG
+ case 0x8EAE53454C61746ELLU: // ovd_Latn_SE
+ case 0xA2CE50474C61746ELLU: // owi_Latn_PG
+ case 0xAECE47424C61746ELLU: // owl_Latn_GB
+ case 0x8F0E45544C61746ELLU: // oyd_Latn_ET
+ case 0xB30E42524C61746ELLU: // oym_Latn_BR
+ case 0xE30E50474C61746ELLU: // oyy_Latn_PG
+ case 0xB32E434D4C61746ELLU: // ozm_Latn_CM
+ case 0x7061504B41726162LLU: // pa_Arab_PK
+ case 0x7061494E47757275LLU: // pa_Guru_IN
+ case 0x840F42524C61746ELLU: // pab_Latn_BR
+ case 0x880F564E4C61746ELLU: // pac_Latn_VN
+ case 0x8C0F42524C61746ELLU: // pad_Latn_BR
+ case 0x900F43444C61746ELLU: // pae_Latn_CD
+ case 0x940F42524C61746ELLU: // paf_Latn_BR
+ case 0x980F50484C61746ELLU: // pag_Latn_PH
+ case 0x9C0F42524C61746ELLU: // pah_Latn_BR
+ case 0xA00F4E474C61746ELLU: // pai_Latn_NG
+ case 0xA80F42524C61746ELLU: // pak_Latn_BR
+ case 0xAC0F495250686C69LLU: // pal_Phli_IR
+ case 0xAC0F434E50686C70LLU: // pal_Phlp_CN
+ case 0xB00F50484C61746ELLU: // pam_Latn_PH
+ case 0xB80F55534C61746ELLU: // pao_Latn_US
+ case 0xBC0F43574C61746ELLU: // pap_Latn_CW
+ case 0xC00F544A4379726CLLU: // paq_Cyrl_TJ
+ case 0xC40F55534C61746ELLU: // par_Latn_US
+ case 0xC80F49444C61746ELLU: // pas_Latn_ID
+ case 0xD00F50574C61746ELLU: // pau_Latn_PW
+ case 0xD40F42524C61746ELLU: // pav_Latn_BR
+ case 0xD80F55534C61746ELLU: // paw_Latn_US
+ case 0xDC0F42524C61746ELLU: // pax_Latn_BR
+ case 0xE00F484E4C61746ELLU: // pay_Latn_HN
+ case 0xE40F42524C61746ELLU: // paz_Latn_BR
+ case 0x842F434F4C61746ELLU: // pbb_Latn_CO
+ case 0x882F47594C61746ELLU: // pbc_Latn_GY
+ case 0x902F4D584C61746ELLU: // pbe_Latn_MX
+ case 0x942F4D584C61746ELLU: // pbf_Latn_MX
+ case 0x982F56454C61746ELLU: // pbg_Latn_VE
+ case 0x9C2F56454C61746ELLU: // pbh_Latn_VE
+ case 0xA02F434D4C61746ELLU: // pbi_Latn_CM
+ case 0xAC2F4E474C61746ELLU: // pbl_Latn_NG
+ case 0xB02F4D584C61746ELLU: // pbm_Latn_MX
+ case 0xB42F4E474C61746ELLU: // pbn_Latn_NG
+ case 0xB82F47574C61746ELLU: // pbo_Latn_GW
+ case 0xBC2F474E4C61746ELLU: // pbp_Latn_GN
+ case 0xC42F545A4C61746ELLU: // pbr_Latn_TZ
+ case 0xC82F4D584C61746ELLU: // pbs_Latn_MX
+ case 0xCC2F414641726162LLU: // pbt_Arab_AF
+ case 0xD42F494E4C61746ELLU: // pbv_Latn_IN
+ case 0xE02F50474C61746ELLU: // pby_Latn_PG
+ case 0x804F4D584C61746ELLU: // pca_Latn_MX
+ case 0x844F4B484B686D72LLU: // pcb_Khmr_KH
+ case 0x884F434E4C61746ELLU: // pcc_Latn_CN
+ case 0x8C4F46524C61746ELLU: // pcd_Latn_FR
+ case 0x904F4D4D4D796D72LLU: // pce_Mymr_MM
+ case 0x944F494E4D6C796DLLU: // pcf_Mlym_IN
+ case 0x984F494E4D6C796DLLU: // pcg_Mlym_IN
+ case 0x9C4F494E44657661LLU: // pch_Deva_IN
+ case 0xA04F494E44657661LLU: // pci_Deva_IN
+ case 0xA44F494E54656C75LLU: // pcj_Telu_IN
+ case 0xA84F494E4C61746ELLU: // pck_Latn_IN
+ case 0xB04F4E474C61746ELLU: // pcm_Latn_NG
+ case 0xB44F4E474C61746ELLU: // pcn_Latn_NG
+ case 0xBC4F424F4C61746ELLU: // pcp_Latn_BO
+ case 0xD84F4E474C61746ELLU: // pcw_Latn_NG
+ case 0x806F50474C61746ELLU: // pda_Latn_PG
+ case 0x886F55534C61746ELLU: // pdc_Latn_US
+ case 0xB46F49444C61746ELLU: // pdn_Latn_ID
+ case 0xB86F49444C61746ELLU: // pdo_Latn_ID
+ case 0xCC6F43414C61746ELLU: // pdt_Latn_CA
+ case 0xD06F4D4D4C61746ELLU: // pdu_Latn_MM
+ case 0x808F49444C61746ELLU: // pea_Latn_ID
+ case 0x848F55534C61746ELLU: // peb_Latn_US
+ case 0x8C8F50474C61746ELLU: // ped_Latn_PG
+ case 0x908F49444C61746ELLU: // pee_Latn_ID
+ case 0x988F494E4F727961LLU: // peg_Orya_IN
+ case 0xA08F4D584C61746ELLU: // pei_Latn_MX
+ case 0xA88F50474C61746ELLU: // pek_Latn_PG
+ case 0xAC8F49444C61746ELLU: // pel_Latn_ID
+ case 0xB08F43444C61746ELLU: // pem_Latn_CD
+ case 0xB88F49525870656FLLU: // peo_Xpeo_IR
+ case 0xBC8F50474C61746ELLU: // pep_Latn_PG
+ case 0xC08F55534C61746ELLU: // peq_Latn_US
+ case 0xD48F56454C61746ELLU: // pev_Latn_VE
+ case 0xDC8F50474C61746ELLU: // pex_Latn_PG
+ case 0xE08F49444C61746ELLU: // pey_Latn_ID
+ case 0xE48F4D594C61746ELLU: // pez_Latn_MY
+ case 0x80AF464D4C61746ELLU: // pfa_Latn_FM
+ case 0x90AF434D4C61746ELLU: // pfe_Latn_CM
+ case 0xACAF44454C61746ELLU: // pfl_Latn_DE
+ case 0x80CF53534C61746ELLU: // pga_Latn_SS
+ case 0x8CCF504B4B686172LLU: // pgd_Khar_PK
+ case 0x98CF494E44657661LLU: // pgg_Deva_IN
+ case 0xA0CF50474C61746ELLU: // pgi_Latn_PG
+ case 0xA8CF56554C61746ELLU: // pgk_Latn_VU
+ case 0xACCF49454F67616DLLU: // pgl_Ogam_IE
+ case 0xB4CF49544974616CLLU: // pgn_Ital_IT
+ case 0xC8CF4E474C61746ELLU: // pgs_Latn_NG
+ case 0xD0CF49444C61746ELLU: // pgu_Latn_ID
+ case 0x8CEF494E44657661LLU: // phd_Deva_IN
+ case 0x98EF564E4C61746ELLU: // phg_Latn_VN
+ case 0x9CEF564E4C61746ELLU: // phh_Latn_VN
+ case 0xA8EF494E4D796D72LLU: // phk_Mymr_IN
+ case 0xACEF504B41726162LLU: // phl_Arab_PK
+ case 0xB0EF4D5A4C61746ELLU: // phm_Latn_MZ
+ case 0xB4EF4C4250686E78LLU: // phn_Phnx_LB
+ case 0xB8EF4C414C616F6FLLU: // pho_Laoo_LA
+ case 0xC4EF504B41726162LLU: // phr_Arab_PK
+ case 0xCCEF544854686169LLU: // pht_Thai_TH
+ case 0xD0EF544854686169LLU: // phu_Thai_TH
+ case 0xD4EF414641726162LLU: // phv_Arab_AF
+ case 0xD8EF4E5044657661LLU: // phw_Deva_NP
+ case 0x7069494E53696E68LLU: // pi_Sinh_IN
+ case 0x810F4D584C61746ELLU: // pia_Latn_MX
+ case 0x850F50454C61746ELLU: // pib_Latn_PE
+ case 0x890F47414C61746ELLU: // pic_Latn_GA
+ case 0x8D0F56454C61746ELLU: // pid_Latn_VE
+ case 0x950F464D4C61746ELLU: // pif_Latn_FM
+ case 0x990F50454C61746ELLU: // pig_Latn_PE
+ case 0x9D0F4E464C61746ELLU: // pih_Latn_NF
+ case 0xA50F434F4C61746ELLU: // pij_Latn_CO
+ case 0xAD0F424A4C61746ELLU: // pil_Latn_BJ
+ case 0xB10F55534C61746ELLU: // pim_Latn_US
+ case 0xB50F50474C61746ELLU: // pin_Latn_PG
+ case 0xB90F434F4C61746ELLU: // pio_Latn_CO
+ case 0xBD0F4E474C61746ELLU: // pip_Latn_NG
+ case 0xC50F42524C61746ELLU: // pir_Latn_BR
+ case 0xC90F53424C61746ELLU: // pis_Latn_SB
+ case 0xCD0F41554C61746ELLU: // pit_Latn_AU
+ case 0xD10F41554C61746ELLU: // piu_Latn_AU
+ case 0xD50F53424C61746ELLU: // piv_Latn_SB
+ case 0xD90F545A4C61746ELLU: // piw_Latn_TZ
+ case 0xDD0F50474C61746ELLU: // pix_Latn_PG
+ case 0xE10F4E474C61746ELLU: // piy_Latn_NG
+ case 0xE50F4E434C61746ELLU: // piz_Latn_NC
+ case 0xCD2F41554C61746ELLU: // pjt_Latn_AU
+ case 0x814F494E42726168LLU: // pka_Brah_IN
+ case 0x854F4B454C61746ELLU: // pkb_Latn_KE
+ case 0x994F50474C61746ELLU: // pkg_Latn_PG
+ case 0x9D4F42444C61746ELLU: // pkh_Latn_BD
+ case 0xB54F41554C61746ELLU: // pkn_Latn_AU
+ case 0xB94F4B454C61746ELLU: // pko_Latn_KE
+ case 0xBD4F434B4C61746ELLU: // pkp_Latn_CK
+ case 0xC54F494E4D6C796DLLU: // pkr_Mlym_IN
+ case 0xD14F49444C61746ELLU: // pku_Latn_ID
+ case 0x706C504C4C61746ELLU: // pl_Latn_PL
+ case 0x816F50474C61746ELLU: // pla_Latn_PG
+ case 0x856F56554C61746ELLU: // plb_Latn_VU
+ case 0x896F50484C61746ELLU: // plc_Latn_PH
+ case 0x8D6F47424C61746ELLU: // pld_Latn_GB
+ case 0x916F49444C61746ELLU: // ple_Latn_ID
+ case 0x996F41524C61746ELLU: // plg_Latn_AR
+ case 0x9D6F49444C61746ELLU: // plh_Latn_ID
+ case 0xA96F504B41726162LLU: // plk_Arab_PK
+ case 0xAD6F4D4D4D796D72LLU: // pll_Mymr_MM
+ case 0xB56F434F4C61746ELLU: // pln_Latn_CO
+ case 0xB96F4D584C61746ELLU: // plo_Latn_MX
+ case 0xC56F43494C61746ELLU: // plr_Latn_CI
+ case 0xC96F4D584C61746ELLU: // pls_Latn_MX
+ case 0xD16F42524C61746ELLU: // plu_Latn_BR
+ case 0xD56F50484C61746ELLU: // plv_Latn_PH
+ case 0xD96F50484C61746ELLU: // plw_Latn_PH
+ case 0xE56F4D594C61746ELLU: // plz_Latn_MY
+ case 0x818F56554C61746ELLU: // pma_Latn_VU
+ case 0x858F43444C61746ELLU: // pmb_Latn_CD
+ case 0x8D8F41554C61746ELLU: // pmd_Latn_AU
+ case 0x918F4E434C61746ELLU: // pme_Latn_NC
+ case 0x958F49444C61746ELLU: // pmf_Latn_ID
+ case 0x9D8F494E42726168LLU: // pmh_Brah_IN
+ case 0xA18F434E4C61746ELLU: // pmi_Latn_CN
+ case 0xA58F434E4C61746ELLU: // pmj_Latn_CN
+ case 0xAD8F544E4C61746ELLU: // pml_Latn_TN
+ case 0xB18F434D4C61746ELLU: // pmm_Latn_CM
+ case 0xB58F434D4C61746ELLU: // pmn_Latn_CM
+ case 0xB98F49444C61746ELLU: // pmo_Latn_ID
+ case 0xC18F4D584C61746ELLU: // pmq_Latn_MX
+ case 0xC58F50474C61746ELLU: // pmr_Latn_PG
+ case 0xC98F49544C61746ELLU: // pms_Latn_IT
+ case 0xCD8F50464C61746ELLU: // pmt_Latn_PF
+ case 0xD98F55534C61746ELLU: // pmw_Latn_US
+ case 0xDD8F494E4C61746ELLU: // pmx_Latn_IN
+ case 0xE18F49444C61746ELLU: // pmy_Latn_ID
+ case 0xE58F4D584C61746ELLU: // pmz_Latn_MX
+ case 0x81AF4D594C61746ELLU: // pna_Latn_MY
+ case 0x89AF49444C61746ELLU: // pnc_Latn_ID
+ case 0x8DAF414F4C61746ELLU: // pnd_Latn_AO
+ case 0x91AF4D594C61746ELLU: // pne_Latn_MY
+ case 0x99AF4E474C61746ELLU: // png_Latn_NG
+ case 0x9DAF434B4C61746ELLU: // pnh_Latn_CK
+ case 0xA1AF49444C61746ELLU: // pni_Latn_ID
+ case 0xA5AF41554C61746ELLU: // pnj_Latn_AU
+ case 0xA9AF424F4C61746ELLU: // pnk_Latn_BO
+ case 0xADAF42464C61746ELLU: // pnl_Latn_BF
+ case 0xB1AF4D594C61746ELLU: // pnm_Latn_MY
+ case 0xB5AF50474C61746ELLU: // pnn_Latn_PG
+ case 0xB9AF50454C61746ELLU: // pno_Latn_PE
+ case 0xBDAF49444C61746ELLU: // pnp_Latn_ID
+ case 0xC1AF42464C61746ELLU: // pnq_Latn_BF
+ case 0xC5AF50474C61746ELLU: // pnr_Latn_PG
+ case 0xC9AF49444C61746ELLU: // pns_Latn_ID
+ case 0xCDAF47524772656BLLU: // pnt_Grek_GR
+ case 0xD5AF41554C61746ELLU: // pnv_Latn_AU
+ case 0xD9AF41554C61746ELLU: // pnw_Latn_AU
+ case 0xE1AF434D4C61746ELLU: // pny_Latn_CM
+ case 0xE5AF43464C61746ELLU: // pnz_Latn_CF
+ case 0x89CF47544C61746ELLU: // poc_Latn_GT
+ case 0x91CF4D584C61746ELLU: // poe_Latn_MX
+ case 0x95CF43444C61746ELLU: // pof_Latn_CD
+ case 0x99CF42524C61746ELLU: // pog_Latn_BR
+ case 0x9DCF47544C61746ELLU: // poh_Latn_GT
+ case 0xA1CF4D584C61746ELLU: // poi_Latn_MX
+ case 0xA9CF42524C61746ELLU: // pok_Latn_BR
+ case 0xB1CF55534C61746ELLU: // pom_Latn_US
+ case 0xB5CF464D4C61746ELLU: // pon_Latn_FM
+ case 0xB9CF55534C61746ELLU: // poo_Latn_US
+ case 0xBDCF4E434C61746ELLU: // pop_Latn_NC
+ case 0xC1CF4D584C61746ELLU: // poq_Latn_MX
+ case 0xC9CF4D584C61746ELLU: // pos_Latn_MX
+ case 0xCDCF55534C61746ELLU: // pot_Latn_US
+ case 0xD5CF47574C61746ELLU: // pov_Latn_GW
+ case 0xD9CF4D584C61746ELLU: // pow_Latn_MX
+ case 0xE1CF545A4C61746ELLU: // poy_Latn_TZ
+ case 0x91EF50474C61746ELLU: // ppe_Latn_PG
+ case 0xA1EF4D584C61746ELLU: // ppi_Latn_MX
+ case 0xA9EF49444C61746ELLU: // ppk_Latn_ID
+ case 0xADEF53564C61746ELLU: // ppl_Latn_SV
+ case 0xB1EF49444C61746ELLU: // ppm_Latn_ID
+ case 0xB5EF50474C61746ELLU: // ppn_Latn_PG
+ case 0xB9EF50474C61746ELLU: // ppo_Latn_PG
+ case 0xBDEF43444C61746ELLU: // ppp_Latn_CD
+ case 0xC1EF50474C61746ELLU: // ppq_Latn_PG
+ case 0xC9EF4D584C61746ELLU: // pps_Latn_MX
+ case 0xCDEF50474C61746ELLU: // ppt_Latn_PG
+ case 0x820F4E474C61746ELLU: // pqa_Latn_NG
+ case 0xB20F43414C61746ELLU: // pqm_Latn_CA
+ case 0x822F504B4B686172LLU: // pra_Khar_PK
+ case 0x8A2F414641726162LLU: // prc_Arab_AF
+ case 0x8E2F495241726162LLU: // prd_Arab_IR
+ case 0x922F53544C61746ELLU: // pre_Latn_ST
+ case 0x962F50484C61746ELLU: // prf_Latn_PH
+ case 0x9A2F504C4C61746ELLU: // prg_Latn_PL
+ case 0x9E2F50484C61746ELLU: // prh_Latn_PH
+ case 0xA22F4E434C61746ELLU: // pri_Latn_NC
+ case 0xAA2F4D4D4C61746ELLU: // prk_Latn_MM
+ case 0xB22F50474C61746ELLU: // prm_Latn_PG
+ case 0xBA2F46524C61746ELLU: // pro_Latn_FR
+ case 0xC22F50454C61746ELLU: // prq_Latn_PE
+ case 0xC62F42524C61746ELLU: // prr_Latn_BR
+ case 0xCE2F544854686169LLU: // prt_Thai_TH
+ case 0xD22F49444C61746ELLU: // pru_Latn_ID
+ case 0xDA2F50474C61746ELLU: // prw_Latn_PG
+ case 0xDE2F494E41726162LLU: // prx_Arab_IN
+ case 0x7073414641726162LLU: // ps_Arab_AF
+ case 0x824F49444C61746ELLU: // psa_Latn_ID
+ case 0x924F49444C61746ELLU: // pse_Latn_ID
+ case 0x9E4F414641726162LLU: // psh_Arab_AF
+ case 0xA24F414641726162LLU: // psi_Arab_AF
+ case 0xB24F424F4C61746ELLU: // psm_Latn_BO
+ case 0xB64F49444C61746ELLU: // psn_Latn_ID
+ case 0xC24F50474C61746ELLU: // psq_Latn_PG
+ case 0xCA4F50474C61746ELLU: // pss_Latn_PG
+ case 0xCE4F504B41726162LLU: // pst_Arab_PK
+ case 0xD24F494E42726168LLU: // psu_Brah_IN
+ case 0xDA4F56554C61746ELLU: // psw_Latn_VU
+ case 0x707442524C61746ELLU: // pt_Latn_BR
+ case 0x826F50594C61746ELLU: // pta_Latn_PY
+ case 0x9E6F42524C61746ELLU: // pth_Latn_BR
+ case 0xA26F41554C61746ELLU: // pti_Latn_AU
+ case 0xB66F49444C61746ELLU: // ptn_Latn_ID
+ case 0xBA6F42524C61746ELLU: // pto_Latn_BR
+ case 0xBE6F50474C61746ELLU: // ptp_Latn_PG
+ case 0xC66F56554C61746ELLU: // ptr_Latn_VU
+ case 0xCE6F49444C61746ELLU: // ptt_Latn_ID
+ case 0xD26F49444C61746ELLU: // ptu_Latn_ID
+ case 0xD66F56554C61746ELLU: // ptv_Latn_VU
+ case 0x828F4D584C61746ELLU: // pua_Latn_MX
+ case 0x868F494E4C61746ELLU: // pub_Latn_IN
+ case 0x8A8F49444C61746ELLU: // puc_Latn_ID
+ case 0x8E8F49444C61746ELLU: // pud_Latn_ID
+ case 0x928F41524C61746ELLU: // pue_Latn_AR
+ case 0x968F49444C61746ELLU: // puf_Latn_ID
+ case 0x9A8F42464C61746ELLU: // pug_Latn_BF
+ case 0xA28F434F4C61746ELLU: // pui_Latn_CO
+ case 0xA68F49444C61746ELLU: // puj_Latn_ID
+ case 0xB28F4E5044657661LLU: // pum_Deva_NP
+ case 0xBA8F564E4C61746ELLU: // puo_Latn_VN
+ case 0xBE8F50474C61746ELLU: // pup_Latn_PG
+ case 0xC28F424F4C61746ELLU: // puq_Latn_BO
+ case 0xC68F42524C61746ELLU: // pur_Latn_BR
+ case 0xCE8F49444C61746ELLU: // put_Latn_ID
+ case 0xD28F47414C61746ELLU: // puu_Latn_GA
+ case 0xDA8F464D4C61746ELLU: // puw_Latn_FM
+ case 0xDE8F50474C61746ELLU: // pux_Latn_PG
+ case 0xE28F55534C61746ELLU: // puy_Latn_US
+ case 0x82CF50474C61746ELLU: // pwa_Latn_PG
+ case 0x86CF4E474C61746ELLU: // pwb_Latn_NG
+ case 0x9ACF50474C61746ELLU: // pwg_Latn_PG
+ case 0xB2CF50484C61746ELLU: // pwm_Latn_PH
+ case 0xB6CF54574C61746ELLU: // pwn_Latn_TW
+ case 0xBACF4D4D4D796D72LLU: // pwo_Mymr_MM
+ case 0xC6CF494E44657661LLU: // pwr_Deva_IN
+ case 0xDACF544854686169LLU: // pww_Thai_TH
+ case 0xB2EF4D584C61746ELLU: // pxm_Latn_MX
+ case 0x930F43494C61746ELLU: // pye_Latn_CI
+ case 0xB30F4E474C61746ELLU: // pym_Latn_NG
+ case 0xB70F42524C61746ELLU: // pyn_Latn_BR
+ case 0xD30F54574C61746ELLU: // pyu_Latn_TW
+ case 0xDF0F4D4D4D796D72LLU: // pyx_Mymr_MM
+ case 0xE30F4D4D4C61746ELLU: // pyy_Latn_MM
+ case 0x932F4E474C61746ELLU: // pze_Latn_NG
+ case 0x9F2F54574C61746ELLU: // pzh_Latn_TW
+ case 0xB72F4D4D4C61746ELLU: // pzn_Latn_MM
+ case 0x717550454C61746ELLU: // qu_Latn_PE
+ case 0x829055534C61746ELLU: // qua_Latn_US
+ case 0x869050454C61746ELLU: // qub_Latn_PE
+ case 0x8A9047544C61746ELLU: // quc_Latn_GT
+ case 0x8E9045434C61746ELLU: // qud_Latn_EC
+ case 0x969050454C61746ELLU: // quf_Latn_PE
+ case 0x9A9045434C61746ELLU: // qug_Latn_EC
+ case 0xA29055534C61746ELLU: // qui_Latn_US
+ case 0xAA9050454C61746ELLU: // quk_Latn_PE
+ case 0xAE90424F4C61746ELLU: // qul_Latn_BO
+ case 0xB29047544C61746ELLU: // qum_Latn_GT
+ case 0xB69055534C61746ELLU: // qun_Latn_US
+ case 0xBE9050454C61746ELLU: // qup_Latn_PE
+ case 0xC29045534C61746ELLU: // quq_Latn_ES
+ case 0xC69050454C61746ELLU: // qur_Latn_PE
+ case 0xCA9041524C61746ELLU: // qus_Latn_AR
+ case 0xD69047544C61746ELLU: // quv_Latn_GT
+ case 0xDA9045434C61746ELLU: // quw_Latn_EC
+ case 0xDE9050454C61746ELLU: // qux_Latn_PE
+ case 0xE29050454C61746ELLU: // quy_Latn_PE
+ case 0x82B050454C61746ELLU: // qva_Latn_PE
+ case 0x8AB050454C61746ELLU: // qvc_Latn_PE
+ case 0x92B050454C61746ELLU: // qve_Latn_PE
+ case 0x9EB050454C61746ELLU: // qvh_Latn_PE
+ case 0xA2B045434C61746ELLU: // qvi_Latn_EC
+ case 0xA6B045434C61746ELLU: // qvj_Latn_EC
+ case 0xAEB050454C61746ELLU: // qvl_Latn_PE
+ case 0xB2B050454C61746ELLU: // qvm_Latn_PE
+ case 0xB6B050454C61746ELLU: // qvn_Latn_PE
+ case 0xBAB050454C61746ELLU: // qvo_Latn_PE
+ case 0xBEB050454C61746ELLU: // qvp_Latn_PE
+ case 0xCAB050454C61746ELLU: // qvs_Latn_PE
+ case 0xDAB050454C61746ELLU: // qvw_Latn_PE
+ case 0xE6B045434C61746ELLU: // qvz_Latn_EC
+ case 0x82D050454C61746ELLU: // qwa_Latn_PE
+ case 0x8AD050454C61746ELLU: // qwc_Latn_PE
+ case 0x9ED050454C61746ELLU: // qwh_Latn_PE
+ case 0xB2D048554C61746ELLU: // qwm_Latn_HU
+ case 0xCAD050454C61746ELLU: // qws_Latn_PE
+ case 0xCED055534C61746ELLU: // qwt_Latn_US
+ case 0x82F050454C61746ELLU: // qxa_Latn_PE
+ case 0x8AF050454C61746ELLU: // qxc_Latn_PE
+ case 0x9EF050454C61746ELLU: // qxh_Latn_PE
+ case 0xAEF045434C61746ELLU: // qxl_Latn_EC
+ case 0xB6F050454C61746ELLU: // qxn_Latn_PE
+ case 0xBAF050454C61746ELLU: // qxo_Latn_PE
+ case 0xBEF050454C61746ELLU: // qxp_Latn_PE
+ case 0xC2F0495241726162LLU: // qxq_Arab_IR
+ case 0xC6F045434C61746ELLU: // qxr_Latn_EC
+ case 0xCEF050454C61746ELLU: // qxt_Latn_PE
+ case 0xD2F050454C61746ELLU: // qxu_Latn_PE
+ case 0xDAF050454C61746ELLU: // qxw_Latn_PE
+ case 0xBF1055534C61746ELLU: // qyp_Latn_US
+ case 0x80114E5044657661LLU: // raa_Deva_NP
+ case 0x84114E5044657661LLU: // rab_Deva_NP
+ case 0x881149444C61746ELLU: // rac_Latn_ID
+ case 0x8C11564E4C61746ELLU: // rad_Latn_VN
+ case 0x94114E5044657661LLU: // raf_Deva_NP
+ case 0x98114B454C61746ELLU: // rag_Latn_KE
+ case 0x9C11494E42656E67LLU: // rah_Beng_IN
+ case 0xA01150474C61746ELLU: // rai_Latn_PG
+ case 0xA411494E44657661LLU: // raj_Deva_IN
+ case 0xA81150474C61746ELLU: // rak_Latn_PG
+ case 0xB01142524C61746ELLU: // ram_Latn_BR
+ case 0xB41149444C61746ELLU: // ran_Latn_ID
+ case 0xB81150474C61746ELLU: // rao_Latn_PG
+ case 0xBC11434C4C61746ELLU: // rap_Latn_CL
+ case 0xC411434B4C61746ELLU: // rar_Latn_CK
+ case 0xD4114E5044657661LLU: // rav_Deva_NP
+ case 0xD8114D4D4C61746ELLU: // raw_Latn_MM
+ case 0xDC114E474C61746ELLU: // rax_Latn_NG
+ case 0xE01150464C61746ELLU: // ray_Latn_PF
+ case 0xE41149444C61746ELLU: // raz_Latn_ID
+ case 0x84314D4D4D796D72LLU: // rbb_Mymr_MM
+ case 0xA83150484C61746ELLU: // rbk_Latn_PH
+ case 0xAC3150484C61746ELLU: // rbl_Latn_PH
+ case 0xBC3141554C61746ELLU: // rbp_Latn_AU
+ case 0x945152454C61746ELLU: // rcf_Latn_RE
+ case 0x8471495241726162LLU: // rdb_Arab_IR
+ case 0x809150474C61746ELLU: // rea_Latn_PG
+ case 0x849149444C61746ELLU: // reb_Latn_ID
+ case 0x90914D594C61746ELLU: // ree_Latn_MY
+ case 0x9891545A4C61746ELLU: // reg_Latn_TZ
+ case 0xA091494E4F727961LLU: // rei_Orya_IN
+ case 0xA49149444C61746ELLU: // rej_Latn_ID
+ case 0xAC914B454C61746ELLU: // rel_Latn_KE
+ case 0xB09150454C61746ELLU: // rem_Latn_PE
+ case 0xB491564E4C61746ELLU: // ren_Latn_VN
+ case 0xC8914E474C61746ELLU: // res_Latn_NG
+ case 0xCC9149444C61746ELLU: // ret_Latn_ID
+ case 0xE091424F4C61746ELLU: // rey_Latn_BO
+ case 0x80D156554C61746ELLU: // rga_Latn_VU
+ case 0xB4D149544C61746ELLU: // rgn_Latn_IT
+ case 0xC4D150454C61746ELLU: // rgr_Latn_PE
+ case 0xC8D1564E4C61746ELLU: // rgs_Latn_VN
+ case 0xD0D149444C61746ELLU: // rgu_Latn_ID
+ case 0x98F14D4D526F6867LLU: // rhg_Rohg_MM
+ case 0xBCF150474C61746ELLU: // rhp_Latn_PG
+ case 0x8111494E4C61746ELLU: // ria_Latn_IN
+ case 0x95114D414C61746ELLU: // rif_Latn_MA
+ case 0xAD114D4D4C61746ELLU: // ril_Latn_MM
+ case 0xB111545A4C61746ELLU: // rim_Latn_TZ
+ case 0xB5114E474C61746ELLU: // rin_Latn_NG
+ case 0xC51149444C61746ELLU: // rir_Latn_ID
+ case 0xCD1141554C61746ELLU: // rit_Latn_AU
+ case 0xD11149444C61746ELLU: // riu_Latn_ID
+ case 0x993149444C61746ELLU: // rjg_Latn_ID
+ case 0xA1314E5044657661LLU: // rji_Deva_NP
+ case 0xC9314E5044657661LLU: // rjs_Deva_NP
+ case 0x81514B484B686D72LLU: // rka_Khmr_KH
+ case 0x855142524C61746ELLU: // rkb_Latn_BR
+ case 0x9D51434B4C61746ELLU: // rkh_Latn_CK
+ case 0xA1514D4D4D796D72LLU: // rki_Mymr_MM
+ case 0xB15142464C61746ELLU: // rkm_Latn_BF
+ case 0xCD51424442656E67LLU: // rkt_Beng_BD
+ case 0xD95141554C61746ELLU: // rkw_Latn_AU
+ case 0x726D43484C61746ELLU: // rm_Latn_CH
+ case 0x81914E494C61746ELLU: // rma_Latn_NI
+ case 0x859141554C61746ELLU: // rmb_Latn_AU
+ case 0x8991534B4C61746ELLU: // rmc_Latn_SK
+ case 0x8D91444B4C61746ELLU: // rmd_Latn_DK
+ case 0x919147424C61746ELLU: // rme_Latn_GB
+ case 0x959146494C61746ELLU: // rmf_Latn_FI
+ case 0x99914E4F4C61746ELLU: // rmg_Latn_NO
+ case 0x9D9149444C61746ELLU: // rmh_Latn_ID
+ case 0xA191414D41726D6ELLU: // rmi_Armn_AM
+ case 0xA99150474C61746ELLU: // rmk_Latn_PG
+ case 0xAD91504C4C61746ELLU: // rml_Latn_PL
+ case 0xB19149444C61746ELLU: // rmm_Latn_ID
+ case 0xB59152534C61746ELLU: // rmn_Latn_RS
+ case 0xB99143484C61746ELLU: // rmo_Latn_CH
+ case 0xBD9150474C61746ELLU: // rmp_Latn_PG
+ case 0xC19145534C61746ELLU: // rmq_Latn_ES
+ case 0xCD91495241726162LLU: // rmt_Arab_IR
+ case 0xD19153454C61746ELLU: // rmu_Latn_SE
+ case 0xD99147424C61746ELLU: // rmw_Latn_GB
+ case 0xDD91564E4C61746ELLU: // rmx_Latn_VN
+ case 0xE591494E4D796D72LLU: // rmz_Mymr_IN
+ case 0x726E42494C61746ELLU: // rn_Latn_BI
+ case 0x8DB143444C61746ELLU: // rnd_Latn_CD
+ case 0x99B14D5A4C61746ELLU: // rng_Latn_MZ
+ case 0xADB1494E4C61746ELLU: // rnl_Latn_IN
+ case 0xB5B149444C61746ELLU: // rnn_Latn_ID
+ case 0xC5B141554C61746ELLU: // rnr_Latn_AU
+ case 0xD9B1545A4C61746ELLU: // rnw_Latn_TZ
+ case 0x726F524F4C61746ELLU: // ro_Latn_RO
+ case 0x85D149444C61746ELLU: // rob_Latn_ID
+ case 0x89D1564E4C61746ELLU: // roc_Latn_VN
+ case 0x8DD14E474C61746ELLU: // rod_Latn_NG
+ case 0x91D150474C61746ELLU: // roe_Latn_PG
+ case 0x95D1545A4C61746ELLU: // rof_Latn_TZ
+ case 0x99D1564E4C61746ELLU: // rog_Latn_VN
+ case 0xADD150484C61746ELLU: // rol_Latn_PH
+ case 0xB1D1524F4C61746ELLU: // rom_Latn_RO
+ case 0xB9D150474C61746ELLU: // roo_Latn_PG
+ case 0xBDD141554C61746ELLU: // rop_Latn_AU
+ case 0xC5D149444C61746ELLU: // ror_Latn_ID
+ case 0xD1D154444C61746ELLU: // rou_Latn_TD
+ case 0xD9D149444C61746ELLU: // row_Latn_ID
+ case 0xB5F156554C61746ELLU: // rpn_Latn_VU
+ case 0xCDF150474C61746ELLU: // rpt_Latn_PG
+ case 0xA23153424C61746ELLU: // rri_Latn_SB
+ case 0xB2314E5A4C61746ELLU: // rrm_Latn_NZ
+ case 0xBA3150474C61746ELLU: // rro_Latn_PG
+ case 0xCE3141554C61746ELLU: // rrt_Latn_AU
+ case 0xAA5152534379726CLLU: // rsk_Cyrl_RS
+ case 0xDA514E474C61746ELLU: // rsw_Latn_NG
+ case 0x8A714D4D4C61746ELLU: // rtc_Latn_MM
+ case 0x9E7149444C61746ELLU: // rth_Latn_ID
+ case 0xB271464A4C61746ELLU: // rtm_Latn_FJ
+ case 0xDA71494E44657661LLU: // rtw_Deva_IN
+ case 0x727552554379726CLLU: // ru_Cyrl_RU
+ case 0x869155474C61746ELLU: // rub_Latn_UG
+ case 0x8A9155474C61746ELLU: // ruc_Latn_UG
+ case 0x929155414379726CLLU: // rue_Cyrl_UA
+ case 0x9691545A4C61746ELLU: // ruf_Latn_TZ
+ case 0x9A9153424C61746ELLU: // rug_Latn_SB
+ case 0xA291545A4C61746ELLU: // rui_Latn_TZ
+ case 0xAA914E474C61746ELLU: // ruk_Latn_NG
+ case 0xBA9148524C61746ELLU: // ruo_Latn_HR
+ case 0xBE91524F4C61746ELLU: // rup_Latn_RO
+ case 0xC29147524C61746ELLU: // ruq_Latn_GR
+ case 0xCE9152554379726CLLU: // rut_Cyrl_RU
+ case 0xD2914D594C61746ELLU: // ruu_Latn_MY
+ case 0xE2914E474C61746ELLU: // ruy_Latn_NG
+ case 0xE6914E474C61746ELLU: // ruz_Latn_NG
+ case 0x727752574C61746ELLU: // rw_Latn_RW
+ case 0x82D150474C61746ELLU: // rwa_Latn_PG
+ case 0xAAD1545A4C61746ELLU: // rwk_Latn_TZ
+ case 0xAED1545A4C61746ELLU: // rwl_Latn_TZ
+ case 0xB2D155474C61746ELLU: // rwm_Latn_UG
+ case 0xBAD150474C61746ELLU: // rwo_Latn_PG
+ case 0xC6D1494E44657661LLU: // rwr_Deva_IN
+ case 0x8EF141554C61746ELLU: // rxd_Latn_AU
+ case 0xDAF141554C61746ELLU: // rxw_Latn_AU
+ case 0xD3114A504B616E61LLU: // ryu_Kana_JP
+ case 0x7361494E44657661LLU: // sa_Deva_IN
+ case 0x801254444C61746ELLU: // saa_Latn_TD
+ case 0x841250414C61746ELLU: // sab_Latn_PA
+ case 0x881255534C61746ELLU: // sac_Latn_US
+ case 0x8C12545A4C61746ELLU: // sad_Latn_TZ
+ case 0x901242524C61746ELLU: // sae_Latn_BR
+ case 0x941247484C61746ELLU: // saf_Latn_GH
+ case 0x9C1252554379726CLLU: // sah_Cyrl_RU
+ case 0xA41249444C61746ELLU: // saj_Latn_ID
+ case 0xA81247414C61746ELLU: // sak_Latn_GA
+ case 0xB012505353616D72LLU: // sam_Samr_PS
+ case 0xB81249444C61746ELLU: // sao_Latn_ID
+ case 0xC0124B454C61746ELLU: // saq_Latn_KE
+ case 0xC412424F4C61746ELLU: // sar_Latn_BO
+ case 0xC81249444C61746ELLU: // sas_Latn_ID
+ case 0xCC12494E4F6C636BLLU: // sat_Olck_IN
+ case 0xD01249444C61746ELLU: // sau_Latn_ID
+ case 0xD412534E4C61746ELLU: // sav_Latn_SN
+ case 0xD81249444C61746ELLU: // saw_Latn_ID
+ case 0xDC1256554C61746ELLU: // sax_Latn_VU
+ case 0xE0124E474C61746ELLU: // say_Latn_NG
+ case 0xE412494E53617572LLU: // saz_Saur_IN
+ case 0x803254444C61746ELLU: // sba_Latn_TD
+ case 0x843253424C61746ELLU: // sbb_Latn_SB
+ case 0x883250474C61746ELLU: // sbc_Latn_PG
+ case 0x8C3242464C61746ELLU: // sbd_Latn_BF
+ case 0x903250474C61746ELLU: // sbe_Latn_PG
+ case 0x983249444C61746ELLU: // sbg_Latn_ID
+ case 0x9C3250474C61746ELLU: // sbh_Latn_PG
+ case 0xA03250474C61746ELLU: // sbi_Latn_PG
+ case 0xA43254444C61746ELLU: // sbj_Latn_TD
+ case 0xA832545A4C61746ELLU: // sbk_Latn_TZ
+ case 0xAC3250484C61746ELLU: // sbl_Latn_PH
+ case 0xB032545A4C61746ELLU: // sbm_Latn_TZ
+ case 0xB432504B41726162LLU: // sbn_Arab_PK
+ case 0xB8324D594C61746ELLU: // sbo_Latn_MY
+ case 0xBC32545A4C61746ELLU: // sbp_Latn_TZ
+ case 0xC03250474C61746ELLU: // sbq_Latn_PG
+ case 0xC43249444C61746ELLU: // sbr_Latn_ID
+ case 0xC8324E414C61746ELLU: // sbs_Latn_NA
+ case 0xCC3249444C61746ELLU: // sbt_Latn_ID
+ case 0xD032494E54696274LLU: // sbu_Tibt_IN
+ case 0xD43249544C61746ELLU: // sbv_Latn_IT
+ case 0xD83247414C61746ELLU: // sbw_Latn_GA
+ case 0xDC3249444C61746ELLU: // sbx_Latn_ID
+ case 0xE0325A4D4C61746ELLU: // sby_Latn_ZM
+ case 0xE43243464C61746ELLU: // sbz_Latn_CF
+ case 0x736349544C61746ELLU: // sc_Latn_IT
+ case 0x8452564E4C61746ELLU: // scb_Latn_VN
+ case 0x9052434E4C61746ELLU: // sce_Latn_CN
+ case 0x945250414C61746ELLU: // scf_Latn_PA
+ case 0x985249444C61746ELLU: // scg_Latn_ID
+ case 0x9C52494E4C61746ELLU: // sch_Latn_IN
+ case 0xA0524C4B4C61746ELLU: // sci_Latn_LK
+ case 0xA852494E44657661LLU: // sck_Deva_IN
+ case 0xAC52504B41726162LLU: // scl_Arab_PK
+ case 0xB45249544C61746ELLU: // scn_Latn_IT
+ case 0xB85247424C61746ELLU: // sco_Latn_GB
+ case 0xBC524E5044657661LLU: // scp_Deva_NP
+ case 0xC85243414C61746ELLU: // scs_Latn_CA
+ case 0xCC524C414C616F6FLLU: // sct_Laoo_LA
+ case 0xD052494E54616B72LLU: // scu_Takr_IN
+ case 0xD4524E474C61746ELLU: // scv_Latn_NG
+ case 0xD8524E474C61746ELLU: // scw_Latn_NG
+ case 0xDC5249544772656BLLU: // scx_Grek_IT
+ case 0x7364504B41726162LLU: // sd_Arab_PK
+ case 0x7364494E44657661LLU: // sd_Deva_IN
+ case 0x7364494E4B686F6ALLU: // sd_Khoj_IN
+ case 0x7364494E53696E64LLU: // sd_Sind_IN
+ case 0x807249444C61746ELLU: // sda_Latn_ID
+ case 0x8472495141726162LLU: // sdb_Arab_IQ
+ case 0x887249544C61746ELLU: // sdc_Latn_IT
+ case 0x90724E474C61746ELLU: // sde_Latn_NG
+ case 0x9472495141726162LLU: // sdf_Arab_IQ
+ case 0x9872414641726162LLU: // sdg_Arab_AF
+ case 0x9C72495241726162LLU: // sdh_Arab_IR
+ case 0xA47243474C61746ELLU: // sdj_Latn_CG
+ case 0xA87250474C61746ELLU: // sdk_Latn_PG
+ case 0xB47249544C61746ELLU: // sdn_Latn_IT
+ case 0xB8724D594C61746ELLU: // sdo_Latn_MY
+ case 0xC07249444C61746ELLU: // sdq_Latn_ID
+ case 0xC472424442656E67LLU: // sdr_Beng_BD
+ case 0xC872544E41726162LLU: // sds_Arab_TN
+ case 0xD07249444C61746ELLU: // sdu_Latn_ID
+ case 0xDC724D594C61746ELLU: // sdx_Latn_MY
+ case 0x73654E4F4C61746ELLU: // se_Latn_NO
+ case 0x80924D594C61746ELLU: // sea_Latn_MY
+ case 0x849243494C61746ELLU: // seb_Latn_CI
+ case 0x889243414C61746ELLU: // sec_Latn_CA
+ case 0x8C92564E4C61746ELLU: // sed_Latn_VN
+ case 0x909255534C61746ELLU: // see_Latn_US
+ case 0x949243494C61746ELLU: // sef_Latn_CI
+ case 0x9892545A4C61746ELLU: // seg_Latn_TZ
+ case 0x9C924D5A4C61746ELLU: // seh_Latn_MZ
+ case 0xA0924D584C61746ELLU: // sei_Latn_MX
+ case 0xA49250474C61746ELLU: // sej_Latn_PG
+ case 0xA89243414C61746ELLU: // sek_Latn_CA
+ case 0xAC9252554379726CLLU: // sel_Cyrl_RU
+ case 0xB49242464C61746ELLU: // sen_Latn_BF
+ case 0xB89250474C61746ELLU: // seo_Latn_PG
+ case 0xBC9242464C61746ELLU: // sep_Latn_BF
+ case 0xC09242464C61746ELLU: // seq_Latn_BF
+ case 0xC49255534C61746ELLU: // ser_Latn_US
+ case 0xC8924D4C4C61746ELLU: // ses_Latn_ML
+ case 0xCC9249444C61746ELLU: // set_Latn_ID
+ case 0xD09249444C61746ELLU: // seu_Latn_ID
+ case 0xD49243494C61746ELLU: // sev_Latn_CI
+ case 0xD89250474C61746ELLU: // sew_Latn_PG
+ case 0xE09245434C61746ELLU: // sey_Latn_EC
+ case 0xE4924D4D4C61746ELLU: // sez_Latn_MM
+ case 0x90B250484C61746ELLU: // sfe_Latn_PH
+ case 0xB0B2434E506C7264LLU: // sfm_Plrd_CN
+ case 0xD8B247484C61746ELLU: // sfw_Latn_GH
+ case 0x736743464C61746ELLU: // sg_Latn_CF
+ case 0x80D249454F67616DLLU: // sga_Ogam_IE
+ case 0x84D250484C61746ELLU: // sgb_Latn_PH
+ case 0x88D24B454C61746ELLU: // sgc_Latn_KE
+ case 0x8CD250484C61746ELLU: // sgd_Latn_PH
+ case 0x90D249444C61746ELLU: // sge_Latn_ID
+ case 0x9CD2544A4379726CLLU: // sgh_Cyrl_TJ
+ case 0xA0D2434D4C61746ELLU: // sgi_Latn_CM
+ case 0xA4D2494E44657661LLU: // sgj_Deva_IN
+ case 0xB0D24B454C61746ELLU: // sgm_Latn_KE
+ case 0xBCD2494E4C61746ELLU: // sgp_Latn_IN
+ case 0xC4D2495241726162LLU: // sgr_Arab_IR
+ case 0xC8D24C544C61746ELLU: // sgs_Latn_LT
+ case 0xCCD2425454696274LLU: // sgt_Tibt_BT
+ case 0xD0D249444C61746ELLU: // sgu_Latn_ID
+ case 0xD8D2455445746869LLU: // sgw_Ethi_ET
+ case 0xE0D2414641726162LLU: // sgy_Arab_AF
+ case 0xE4D250474C61746ELLU: // sgz_Latn_PG
+ case 0x80F24E474C61746ELLU: // sha_Latn_NG
+ case 0x84F242524C61746ELLU: // shb_Latn_BR
+ case 0x88F243444C61746ELLU: // shc_Latn_CD
+ case 0x8CF2504B41726162LLU: // shd_Arab_PK
+ case 0x90F245544C61746ELLU: // she_Latn_ET
+ case 0x98F242574C61746ELLU: // shg_Latn_BW
+ case 0x9CF255534C61746ELLU: // shh_Latn_US
+ case 0xA0F24D4154666E67LLU: // shi_Tfng_MA
+ case 0xA4F253444C61746ELLU: // shj_Latn_SD
+ case 0xA8F253534C61746ELLU: // shk_Latn_SS
+ case 0xB0F2495241726162LLU: // shm_Arab_IR
+ case 0xB4F24D4D4D796D72LLU: // shn_Mymr_MM
+ case 0xB8F24E474C61746ELLU: // sho_Latn_NG
+ case 0xBCF250454C61746ELLU: // shp_Latn_PE
+ case 0xC0F25A4D4C61746ELLU: // shq_Latn_ZM
+ case 0xC4F243444C61746ELLU: // shr_Latn_CD
+ case 0xC8F243414C61746ELLU: // shs_Latn_CA
+ case 0xCCF255534C61746ELLU: // sht_Latn_US
+ case 0xD0F2544441726162LLU: // shu_Arab_TD
+ case 0xD4F24F4D41726162LLU: // shv_Arab_OM
+ case 0xD8F253444C61746ELLU: // shw_Latn_SD
+ case 0xE0F2445A4C61746ELLU: // shy_Latn_DZ
+ case 0xE4F24D4C4C61746ELLU: // shz_Latn_ML
+ case 0x73694C4B53696E68LLU: // si_Sinh_LK
+ case 0x811252554379726CLLU: // sia_Cyrl_RU
+ case 0x85124D594C61746ELLU: // sib_Latn_MY
+ case 0x8D1245544C61746ELLU: // sid_Latn_ET
+ case 0x91125A4D4C61746ELLU: // sie_Latn_ZM
+ case 0x951242464C61746ELLU: // sif_Latn_BF
+ case 0x991247484C61746ELLU: // sig_Latn_GH
+ case 0x9D124E434C61746ELLU: // sih_Latn_NC
+ case 0xA112494E4C61746ELLU: // sii_Latn_IN
+ case 0xA51250474C61746ELLU: // sij_Latn_PG
+ case 0xA91242524C61746ELLU: // sik_Latn_BR
+ case 0xAD1247484C61746ELLU: // sil_Latn_GH
+ case 0xB11250474C61746ELLU: // sim_Latn_PG
+ case 0xBD12494E54696274LLU: // sip_Tibt_IN
+ case 0xC11250474C61746ELLU: // siq_Latn_PG
+ case 0xC5124E474C61746ELLU: // sir_Latn_NG
+ case 0xC91255534C61746ELLU: // sis_Latn_US
+ case 0xD11250474C61746ELLU: // siu_Latn_PG
+ case 0xD51250474C61746ELLU: // siv_Latn_PG
+ case 0xD91250474C61746ELLU: // siw_Latn_PG
+ case 0xDD1250474C61746ELLU: // six_Latn_PG
+ case 0xE112495241726162LLU: // siy_Arab_IR
+ case 0xE512454741726162LLU: // siz_Arab_EG
+ case 0x8132434F4C61746ELLU: // sja_Latn_CO
+ case 0x853249444C61746ELLU: // sjb_Latn_ID
+ case 0x8D3252554379726CLLU: // sjd_Cyrl_RU
+ case 0x913253454C61746ELLU: // sje_Latn_SE
+ case 0x993254444C61746ELLU: // sjg_Latn_TD
+ case 0xAD32494E4C61746ELLU: // sjl_Latn_IN
+ case 0xB13250484C61746ELLU: // sjm_Latn_PH
+ case 0xBD32494E44657661LLU: // sjp_Deva_IN
+ case 0xC53250474C61746ELLU: // sjr_Latn_PG
+ case 0xCD3252554379726CLLU: // sjt_Cyrl_RU
+ case 0xD13253454C61746ELLU: // sju_Latn_SE
+ case 0xD93255534C61746ELLU: // sjw_Latn_US
+ case 0x736B534B4C61746ELLU: // sk_Latn_SK
+ case 0x815255534C61746ELLU: // ska_Latn_US
+ case 0x8552544854686169LLU: // skb_Thai_TH
+ case 0x895250474C61746ELLU: // skc_Latn_PG
+ case 0x8D5255534C61746ELLU: // skd_Latn_US
+ case 0x915256554C61746ELLU: // ske_Latn_VU
+ case 0x955242524C61746ELLU: // skf_Latn_BR
+ case 0x99524D474C61746ELLU: // skg_Latn_MG
+ case 0x9D5249444C61746ELLU: // skh_Latn_ID
+ case 0xA15249444C61746ELLU: // ski_Latn_ID
+ case 0xA5524E5044657661LLU: // skj_Deva_NP
+ case 0xB15250474C61746ELLU: // skm_Latn_PG
+ case 0xB55250484C61746ELLU: // skn_Latn_PH
+ case 0xB95249444C61746ELLU: // sko_Latn_ID
+ case 0xBD524D594C61746ELLU: // skp_Latn_MY
+ case 0xC15242464C61746ELLU: // skq_Latn_BF
+ case 0xC552504B41726162LLU: // skr_Arab_PK
+ case 0xC95250474C61746ELLU: // sks_Latn_PG
+ case 0xCD5243444C61746ELLU: // skt_Latn_CD
+ case 0xD15256554C61746ELLU: // sku_Latn_VU
+ case 0xD55249444C61746ELLU: // skv_Latn_ID
+ case 0xD95247594C61746ELLU: // skw_Latn_GY
+ case 0xDD5249444C61746ELLU: // skx_Latn_ID
+ case 0xE15253424C61746ELLU: // sky_Latn_SB
+ case 0xE55249444C61746ELLU: // skz_Latn_ID
+ case 0x736C53494C61746ELLU: // sl_Latn_SI
+ case 0x8972434F4C61746ELLU: // slc_Latn_CO
+ case 0x8D7242464C61746ELLU: // sld_Latn_BF
+ case 0x997249444C61746ELLU: // slg_Latn_ID
+ case 0x9D7255534C61746ELLU: // slh_Latn_US
+ case 0xA172504C4C61746ELLU: // sli_Latn_PL
+ case 0xA57242524C61746ELLU: // slj_Latn_BR
+ case 0xAD7250474C61746ELLU: // sll_Latn_PG
+ case 0xB17250484C61746ELLU: // slm_Latn_PH
+ case 0xB57255534C61746ELLU: // sln_Latn_US
+ case 0xBD7249444C61746ELLU: // slp_Latn_ID
+ case 0xC572434E4C61746ELLU: // slr_Latn_CN
+ case 0xD17249444C61746ELLU: // slu_Latn_ID
+ case 0xD97250474C61746ELLU: // slw_Latn_PG
+ case 0xDD7243444C61746ELLU: // slx_Latn_CD
+ case 0xE17249444C61746ELLU: // sly_Latn_ID
+ case 0xE57249444C61746ELLU: // slz_Latn_ID
+ case 0x736D57534C61746ELLU: // sm_Latn_WS
+ case 0x819253454C61746ELLU: // sma_Latn_SE
+ case 0x859250474C61746ELLU: // smb_Latn_PG
+ case 0x899250474C61746ELLU: // smc_Latn_PG
+ case 0x959250474C61746ELLU: // smf_Latn_PG
+ case 0x999250474C61746ELLU: // smg_Latn_PG
+ case 0x9D92434E59696969LLU: // smh_Yiii_CN
+ case 0xA59253454C61746ELLU: // smj_Latn_SE
+ case 0xA99250484C61746ELLU: // smk_Latn_PH
+ case 0xAD9250484C61746ELLU: // sml_Latn_PH
+ case 0xB59246494C61746ELLU: // smn_Latn_FI
+ case 0xBD92494C53616D72LLU: // smp_Samr_IL
+ case 0xC19250474C61746ELLU: // smq_Latn_PG
+ case 0xC59249444C61746ELLU: // smr_Latn_ID
+ case 0xC99246494C61746ELLU: // sms_Latn_FI
+ case 0xCD92494E4C61746ELLU: // smt_Latn_IN
+ case 0xD1924B484B686D72LLU: // smu_Khmr_KH
+ case 0xD99249444C61746ELLU: // smw_Latn_ID
+ case 0xDD9243444C61746ELLU: // smx_Latn_CD
+ case 0xE192495241726162LLU: // smy_Arab_IR
+ case 0xE59250474C61746ELLU: // smz_Latn_PG
+ case 0x736E5A574C61746ELLU: // sn_Latn_ZW
+ case 0x89B250474C61746ELLU: // snc_Latn_PG
+ case 0x91B24D594C61746ELLU: // sne_Latn_MY
+ case 0x95B2534E4C61746ELLU: // snf_Latn_SN
+ case 0x99B243444C61746ELLU: // sng_Latn_CD
+ case 0xA1B250454C61746ELLU: // sni_Latn_PE
+ case 0xA5B243464C61746ELLU: // snj_Latn_CF
+ case 0xA9B24D4C4C61746ELLU: // snk_Latn_ML
+ case 0xADB250484C61746ELLU: // snl_Latn_PH
+ case 0xB1B255474C61746ELLU: // snm_Latn_UG
+ case 0xB5B2434F4C61746ELLU: // snn_Latn_CO
+ case 0xB9B255534C61746ELLU: // sno_Latn_US
+ case 0xBDB250474C61746ELLU: // snp_Latn_PG
+ case 0xC1B247414C61746ELLU: // snq_Latn_GA
+ case 0xC5B250474C61746ELLU: // snr_Latn_PG
+ case 0xC9B256554C61746ELLU: // sns_Latn_VU
+ case 0xD1B249444C61746ELLU: // snu_Latn_ID
+ case 0xD5B24D594C61746ELLU: // snv_Latn_MY
+ case 0xD9B247484C61746ELLU: // snw_Latn_GH
+ case 0xDDB250474C61746ELLU: // snx_Latn_PG
+ case 0xE1B250474C61746ELLU: // sny_Latn_PG
+ case 0xE5B250474C61746ELLU: // snz_Latn_PG
+ case 0x736F534F4C61746ELLU: // so_Latn_SO
+ case 0x81D2544854617674LLU: // soa_Tavt_TH
+ case 0x85D249444C61746ELLU: // sob_Latn_ID
+ case 0x89D243444C61746ELLU: // soc_Latn_CD
+ case 0x8DD243444C61746ELLU: // sod_Latn_CD
+ case 0x91D243444C61746ELLU: // soe_Latn_CD
+ case 0x99D2555A536F6764LLU: // sog_Sogd_UZ
+ case 0xA1D24E5044657661LLU: // soi_Deva_NP
+ case 0xA9D254444C61746ELLU: // sok_Latn_TD
+ case 0xADD250474C61746ELLU: // sol_Latn_PG
+ case 0xB9D243444C61746ELLU: // soo_Latn_CD
+ case 0xBDD243444C61746ELLU: // sop_Latn_CD
+ case 0xC1D250474C61746ELLU: // soq_Latn_PG
+ case 0xC5D254444C61746ELLU: // sor_Latn_TD
+ case 0xC9D242464C61746ELLU: // sos_Latn_BF
+ case 0xD1D2544854686169LLU: // sou_Thai_TH
+ case 0xD5D250574C61746ELLU: // sov_Latn_PW
+ case 0xD9D250474C61746ELLU: // sow_Latn_PG
+ case 0xDDD2434D4C61746ELLU: // sox_Latn_CM
+ case 0xE1D2424A4C61746ELLU: // soy_Latn_BJ
+ case 0xE5D2545A4C61746ELLU: // soz_Latn_TZ
+ case 0x85F249444C61746ELLU: // spb_Latn_ID
+ case 0x89F256454C61746ELLU: // spc_Latn_VE
+ case 0x8DF250474C61746ELLU: // spd_Latn_PG
+ case 0x91F250474C61746ELLU: // spe_Latn_PG
+ case 0x99F24D594C61746ELLU: // spg_Latn_MY
+ case 0xA1F249444C61746ELLU: // spi_Latn_ID
+ case 0xA9F250474C61746ELLU: // spk_Latn_PG
+ case 0xADF250474C61746ELLU: // spl_Latn_PG
+ case 0xB1F250474C61746ELLU: // spm_Latn_PG
+ case 0xB5F250594C61746ELLU: // spn_Latn_PY
+ case 0xB9F255534C61746ELLU: // spo_Latn_US
+ case 0xBDF24D4C4C61746ELLU: // spp_Latn_ML
+ case 0xC1F250454C61746ELLU: // spq_Latn_PE
+ case 0xC5F249444C61746ELLU: // spr_Latn_ID
+ case 0xC9F250474C61746ELLU: // sps_Latn_PG
+ case 0xCDF2494E54696274LLU: // spt_Tibt_IN
+ case 0xD5F2494E4F727961LLU: // spv_Orya_IN
+ case 0x7371414C4C61746ELLU: // sq_Latn_AL
+ case 0x82124E474C61746ELLU: // sqa_Latn_NG
+ case 0x9E124E474C61746ELLU: // sqh_Latn_NG
+ case 0xB21243464C61746ELLU: // sqm_Latn_CF
+ case 0xBA12495241726162LLU: // sqo_Arab_IR
+ case 0xC2124C414C616F6FLLU: // sqq_Laoo_LA
+ case 0xCE12594541726162LLU: // sqt_Arab_YE
+ case 0xD21243414C61746ELLU: // squ_Latn_CA
+ case 0x737252534379726CLLU: // sr_Cyrl_RS
+ case 0x823250474C61746ELLU: // sra_Latn_PG
+ case 0x8632494E536F7261LLU: // srb_Sora_IN
+ case 0x923249444C61746ELLU: // sre_Latn_ID
+ case 0x963250474C61746ELLU: // srf_Latn_PG
+ case 0x9A3250484C61746ELLU: // srg_Latn_PH
+ case 0x9E32434E41726162LLU: // srh_Arab_CN
+ case 0xA232434F4C61746ELLU: // sri_Latn_CO
+ case 0xAA324D594C61746ELLU: // srk_Latn_MY
+ case 0xAE3249444C61746ELLU: // srl_Latn_ID
+ case 0xB23253524C61746ELLU: // srm_Latn_SR
+ case 0xB63253524C61746ELLU: // srn_Latn_SR
+ case 0xBA3249544C61746ELLU: // sro_Latn_IT
+ case 0xC232424F4C61746ELLU: // srq_Latn_BO
+ case 0xC632534E4C61746ELLU: // srr_Latn_SN
+ case 0xCA3243414C61746ELLU: // srs_Latn_CA
+ case 0xCE3249444C61746ELLU: // srt_Latn_ID
+ case 0xD23242524C61746ELLU: // sru_Latn_BR
+ case 0xD63250484C61746ELLU: // srv_Latn_PH
+ case 0xDA3249444C61746ELLU: // srw_Latn_ID
+ case 0xDE32494E44657661LLU: // srx_Deva_IN
+ case 0xE23250474C61746ELLU: // sry_Latn_PG
+ case 0xE632495241726162LLU: // srz_Arab_IR
+ case 0x73735A414C61746ELLU: // ss_Latn_ZA
+ case 0x865250484C61746ELLU: // ssb_Latn_PH
+ case 0x8A52545A4C61746ELLU: // ssc_Latn_TZ
+ case 0x8E5250474C61746ELLU: // ssd_Latn_PG
+ case 0x925250484C61746ELLU: // sse_Latn_PH
+ case 0x965254574C61746ELLU: // ssf_Latn_TW
+ case 0x9A5250474C61746ELLU: // ssg_Latn_PG
+ case 0x9E52414541726162LLU: // ssh_Arab_AE
+ case 0xA65250474C61746ELLU: // ssj_Latn_PG
+ case 0xAE5247484C61746ELLU: // ssl_Latn_GH
+ case 0xB2524D594C61746ELLU: // ssm_Latn_MY
+ case 0xB6524B454C61746ELLU: // ssn_Latn_KE
+ case 0xBA5250474C61746ELLU: // sso_Latn_PG
+ case 0xC25249444C61746ELLU: // ssq_Latn_ID
+ case 0xCA524C414C616F6FLLU: // sss_Laoo_LA
+ case 0xCE5250474C61746ELLU: // sst_Latn_PG
+ case 0xD25250474C61746ELLU: // ssu_Latn_PG
+ case 0xD65256554C61746ELLU: // ssv_Latn_VU
+ case 0xDE5250474C61746ELLU: // ssx_Latn_PG
+ case 0xE25245524C61746ELLU: // ssy_Latn_ER
+ case 0xE65250474C61746ELLU: // ssz_Latn_PG
+ case 0x73745A414C61746ELLU: // st_Latn_ZA
+ case 0x82725A4D4C61746ELLU: // sta_Latn_ZM
+ case 0x867250484C61746ELLU: // stb_Latn_PH
+ case 0x927249444C61746ELLU: // ste_Latn_ID
+ case 0x967250474C61746ELLU: // stf_Latn_PG
+ case 0x9A72564E4C61746ELLU: // stg_Latn_VN
+ case 0x9E7249454C61746ELLU: // sth_Latn_IE
+ case 0xA272564E4C61746ELLU: // sti_Latn_VN
+ case 0xA67242464C61746ELLU: // stj_Latn_BF
+ case 0xAA7250474C61746ELLU: // stk_Latn_PG
+ case 0xAE724E4C4C61746ELLU: // stl_Latn_NL
+ case 0xB27250474C61746ELLU: // stm_Latn_PG
+ case 0xB67253424C61746ELLU: // stn_Latn_SB
+ case 0xBA7243414C61746ELLU: // sto_Latn_CA
+ case 0xBE724D584C61746ELLU: // stp_Latn_MX
+ case 0xC27244454C61746ELLU: // stq_Latn_DE
+ case 0xC67243414C61746ELLU: // str_Latn_CA
+ case 0xCA72414641726162LLU: // sts_Arab_AF
+ case 0xCE72564E4C61746ELLU: // stt_Latn_VN
+ case 0xD672455445746869LLU: // stv_Ethi_ET
+ case 0xDA72464D4C61746ELLU: // stw_Latn_FM
+ case 0xE27252554379726CLLU: // sty_Cyrl_RU
+ case 0x737549444C61746ELLU: // su_Latn_ID
+ case 0x829250474C61746ELLU: // sua_Latn_PG
+ case 0x869243444C61746ELLU: // sub_Latn_CD
+ case 0x8A9250484C61746ELLU: // suc_Latn_PH
+ case 0x929250474C61746ELLU: // sue_Latn_PG
+ case 0x9A9250474C61746ELLU: // sug_Latn_PG
+ case 0xA29250474C61746ELLU: // sui_Latn_PG
+ case 0xA692545A4C61746ELLU: // suj_Latn_TZ
+ case 0xAA92545A4C61746ELLU: // suk_Latn_TZ
+ case 0xBA9250474C61746ELLU: // suo_Latn_PG
+ case 0xC29245544C61746ELLU: // suq_Latn_ET
+ case 0xC6924E474C61746ELLU: // sur_Latn_NG
+ case 0xCA92474E4C61746ELLU: // sus_Latn_GN
+ case 0xCE924E494C61746ELLU: // sut_Latn_NI
+ case 0xD692494E4C61746ELLU: // suv_Latn_IN
+ case 0xDA92545A4C61746ELLU: // suw_Latn_TZ
+ case 0xE29242524C61746ELLU: // suy_Latn_BR
+ case 0xE6924E5053756E75LLU: // suz_Sunu_NP
+ case 0x737653454C61746ELLU: // sv_Latn_SE
+ case 0x82B2474547656F72LLU: // sva_Geor_GE
+ case 0x86B250474C61746ELLU: // svb_Latn_PG
+ case 0x8AB256434C61746ELLU: // svc_Latn_VC
+ case 0x92B249444C61746ELLU: // sve_Latn_ID
+ case 0xB2B249544C61746ELLU: // svm_Latn_IT
+ case 0xCAB253424C61746ELLU: // svs_Latn_SB
+ case 0x7377545A4C61746ELLU: // sw_Latn_TZ
+ case 0x86D2595441726162LLU: // swb_Arab_YT
+ case 0x96D243444C61746ELLU: // swf_Latn_CD
+ case 0x9AD244454C61746ELLU: // swg_Latn_DE
+ case 0xA2D2434E48616E69LLU: // swi_Hani_CN
+ case 0xA6D247414C61746ELLU: // swj_Latn_GA
+ case 0xAAD24D574C61746ELLU: // swk_Latn_MW
+ case 0xB2D250474C61746ELLU: // swm_Latn_PG
+ case 0xBAD242524C61746ELLU: // swo_Latn_BR
+ case 0xBED250474C61746ELLU: // swp_Latn_PG
+ case 0xC2D2434D4C61746ELLU: // swq_Latn_CM
+ case 0xC6D249444C61746ELLU: // swr_Latn_ID
+ case 0xCAD249444C61746ELLU: // sws_Latn_ID
+ case 0xCED249444C61746ELLU: // swt_Latn_ID
+ case 0xD2D249444C61746ELLU: // swu_Latn_ID
+ case 0xD6D2494E44657661LLU: // swv_Deva_IN
+ case 0xDAD256554C61746ELLU: // sww_Latn_VU
+ case 0xDED242524C61746ELLU: // swx_Latn_BR
+ case 0xE2D254444C61746ELLU: // swy_Latn_TD
+ case 0x86F24B454C61746ELLU: // sxb_Latn_KE
+ case 0x92F247414C61746ELLU: // sxe_Latn_GA
+ case 0xB6F249444C61746ELLU: // sxn_Latn_ID
+ case 0xC6F254574C61746ELLU: // sxr_Latn_TW
+ case 0xCAF24E474C61746ELLU: // sxs_Latn_NG
+ case 0xD2F2444552756E72LLU: // sxu_Runr_DE
+ case 0xDAF2424A4C61746ELLU: // sxw_Latn_BJ
+ case 0x831249444C61746ELLU: // sya_Latn_ID
+ case 0x871250484C61746ELLU: // syb_Latn_PH
+ case 0x8B12545253797263LLU: // syc_Syrc_TR
+ case 0xA31247414C61746ELLU: // syi_Latn_GA
+ case 0xAB124E474C61746ELLU: // syk_Latn_NG
+ case 0xAF12424442656E67LLU: // syl_Beng_BD
+ case 0xB31242464C61746ELLU: // sym_Latn_BF
+ case 0xB712495253797263LLU: // syn_Syrc_IR
+ case 0xBB124B484C61746ELLU: // syo_Latn_KH
+ case 0xC712495153797263LLU: // syr_Syrc_IQ
+ case 0xCB1254444C61746ELLU: // sys_Latn_TD
+ case 0xDB124E5044657661LLU: // syw_Deva_NP
+ case 0xDF1247414C61746ELLU: // syx_Latn_GA
+ case 0x83324D594C61746ELLU: // sza_Latn_MY
+ case 0x873249444C61746ELLU: // szb_Latn_ID
+ case 0x8B324D594C61746ELLU: // szc_Latn_MY
+ case 0x9B3243444C61746ELLU: // szg_Latn_CD
+ case 0xAF32504C4C61746ELLU: // szl_Latn_PL
+ case 0xB73249444C61746ELLU: // szn_Latn_ID
+ case 0xBF3249444C61746ELLU: // szp_Latn_ID
+ case 0xD732434D4C61746ELLU: // szv_Latn_CM
+ case 0xDB3249444C61746ELLU: // szw_Latn_ID
+ case 0xE33254574C61746ELLU: // szy_Latn_TW
+ case 0x7461494E54616D6CLLU: // ta_Taml_IN
+ case 0x801355534C61746ELLU: // taa_Latn_US
+ case 0x841352554379726CLLU: // tab_Cyrl_RU
+ case 0x88134D584C61746ELLU: // tac_Latn_MX
+ case 0x8C1349444C61746ELLU: // tad_Latn_ID
+ case 0x901342524C61746ELLU: // tae_Latn_BR
+ case 0x941342524C61746ELLU: // taf_Latn_BR
+ case 0x981353444C61746ELLU: // tag_Latn_SD
+ case 0xA4134E5044657661LLU: // taj_Deva_NP
+ case 0xA8134E474C61746ELLU: // tak_Latn_NG
+ case 0xAC134E474C61746ELLU: // tal_Latn_NG
+ case 0xB4134E474C61746ELLU: // tan_Latn_NG
+ case 0xB81354574C61746ELLU: // tao_Latn_TW
+ case 0xBC1343444C61746ELLU: // tap_Latn_CD
+ case 0xC0134D4C4C61746ELLU: // taq_Latn_ML
+ case 0xC4134D584C61746ELLU: // tar_Latn_MX
+ case 0xC813564E4C61746ELLU: // tas_Latn_VN
+ case 0xD01355534C61746ELLU: // tau_Latn_US
+ case 0xD413434F4C61746ELLU: // tav_Latn_CO
+ case 0xD81350474C61746ELLU: // taw_Latn_PG
+ case 0xDC1354444C61746ELLU: // tax_Latn_TD
+ case 0xE01354574C61746ELLU: // tay_Latn_TW
+ case 0xE41353444C61746ELLU: // taz_Latn_SD
+ case 0x803342524C61746ELLU: // tba_Latn_BR
+ case 0x883350474C61746ELLU: // tbc_Latn_PG
+ case 0x8C3350474C61746ELLU: // tbd_Latn_PG
+ case 0x903353424C61746ELLU: // tbe_Latn_SB
+ case 0x943350474C61746ELLU: // tbf_Latn_PG
+ case 0x983350474C61746ELLU: // tbg_Latn_PG
+ case 0x9C3341554C61746ELLU: // tbh_Latn_AU
+ case 0xA03353444C61746ELLU: // tbi_Latn_SD
+ case 0xA43350474C61746ELLU: // tbj_Latn_PG
+ case 0xA833504854616762LLU: // tbk_Tagb_PH
+ case 0xAC3350484C61746ELLU: // tbl_Latn_PH
+ case 0xB03343444C61746ELLU: // tbm_Latn_CD
+ case 0xB433434F4C61746ELLU: // tbn_Latn_CO
+ case 0xB83350474C61746ELLU: // tbo_Latn_PG
+ case 0xBC3349444C61746ELLU: // tbp_Latn_ID
+ case 0xC83350474C61746ELLU: // tbs_Latn_PG
+ case 0xCC3343444C61746ELLU: // tbt_Latn_CD
+ case 0xD0334D584C61746ELLU: // tbu_Latn_MX
+ case 0xD43350474C61746ELLU: // tbv_Latn_PG
+ case 0xD83350484C61746ELLU: // tbw_Latn_PH
+ case 0xDC3350474C61746ELLU: // tbx_Latn_PG
+ case 0xE03349444C61746ELLU: // tby_Latn_ID
+ case 0xE433424A4C61746ELLU: // tbz_Latn_BJ
+ case 0x805342524C61746ELLU: // tca_Latn_BR
+ case 0x845355534C61746ELLU: // tcb_Latn_US
+ case 0x8853545A4C61746ELLU: // tcc_Latn_TZ
+ case 0x8C5347484C61746ELLU: // tcd_Latn_GH
+ case 0x905343414C61746ELLU: // tce_Latn_CA
+ case 0x94534D584C61746ELLU: // tcf_Latn_MX
+ case 0x985349444C61746ELLU: // tcg_Latn_ID
+ case 0x9C5354434C61746ELLU: // tch_Latn_TC
+ case 0xA05350474C61746ELLU: // tci_Latn_PG
+ case 0xA85347414C61746ELLU: // tck_Latn_GA
+ case 0xB05349444C61746ELLU: // tcm_Latn_ID
+ case 0xB4534E5054696274LLU: // tcn_Tibt_NP
+ case 0xB8534D4D4D796D72LLU: // tco_Mymr_MM
+ case 0xBC534D4D4C61746ELLU: // tcp_Latn_MM
+ case 0xC05349444C61746ELLU: // tcq_Latn_ID
+ case 0xC85341554C61746ELLU: // tcs_Latn_AU
+ case 0xD0534D584C61746ELLU: // tcu_Latn_MX
+ case 0xD8534D584C61746ELLU: // tcw_Latn_MX
+ case 0xDC53494E54616D6CLLU: // tcx_Taml_IN
+ case 0xE053494E4B6E6461LLU: // tcy_Knda_IN
+ case 0xE453494E4C61746ELLU: // tcz_Latn_IN
+ case 0x80734E4554666E67LLU: // tda_Tfng_NE
+ case 0x8473494E44657661LLU: // tdb_Deva_IN
+ case 0x8873434F4C61746ELLU: // tdc_Latn_CO
+ case 0x8C73434E54616C65LLU: // tdd_Tale_CN
+ case 0x90734D4C4C61746ELLU: // tde_Latn_ML
+ case 0x98734E5044657661LLU: // tdg_Deva_NP
+ case 0x9C734E5044657661LLU: // tdh_Deva_NP
+ case 0xA07349444C61746ELLU: // tdi_Latn_ID
+ case 0xA47349444C61746ELLU: // tdj_Latn_ID
+ case 0xA8734E474C61746ELLU: // tdk_Latn_NG
+ case 0xAC734E474C61746ELLU: // tdl_Latn_NG
+ case 0xB07347594C61746ELLU: // tdm_Latn_GY
+ case 0xB47349444C61746ELLU: // tdn_Latn_ID
+ case 0xB8734E474C61746ELLU: // tdo_Latn_NG
+ case 0xC0734E474C61746ELLU: // tdq_Latn_NG
+ case 0xC473564E4C61746ELLU: // tdr_Latn_VN
+ case 0xC87349444C61746ELLU: // tds_Latn_ID
+ case 0xCC73544C4C61746ELLU: // tdt_Latn_TL
+ case 0xD4734E474C61746ELLU: // tdv_Latn_NG
+ case 0xDC734D474C61746ELLU: // tdx_Latn_MG
+ case 0xE07350484C61746ELLU: // tdy_Latn_PH
+ case 0x7465494E54656C75LLU: // te_Telu_IN
+ case 0x80934D594C61746ELLU: // tea_Latn_MY
+ case 0x849345434C61746ELLU: // teb_Latn_EC
+ case 0x88934B454C61746ELLU: // tec_Latn_KE
+ case 0x8C9343494C61746ELLU: // ted_Latn_CI
+ case 0x90934D584C61746ELLU: // tee_Latn_MX
+ case 0x989347414C61746ELLU: // teg_Latn_GA
+ case 0x9C9341524C61746ELLU: // teh_Latn_AR
+ case 0xA09350474C61746ELLU: // tei_Latn_PG
+ case 0xA89343444C61746ELLU: // tek_Latn_CD
+ case 0xB093534C4C61746ELLU: // tem_Latn_SL
+ case 0xB493434F4C61746ELLU: // ten_Latn_CO
+ case 0xB89355474C61746ELLU: // teo_Latn_UG
+ case 0xBC934D584C61746ELLU: // tep_Latn_MX
+ case 0xC09353444C61746ELLU: // teq_Latn_SD
+ case 0xC49342524C61746ELLU: // ter_Latn_BR
+ case 0xC89349444A617661LLU: // tes_Java_ID
+ case 0xCC93544C4C61746ELLU: // tet_Latn_TL
+ case 0xD09355474C61746ELLU: // teu_Latn_UG
+ case 0xD49349444C61746ELLU: // tev_Latn_ID
+ case 0xD89355534C61746ELLU: // tew_Latn_US
+ case 0xDC9353534C61746ELLU: // tex_Latn_SS
+ case 0xE09353444C61746ELLU: // tey_Latn_SD
+ case 0xE4934E454C61746ELLU: // tez_Latn_NE
+ case 0xA0B3424A4C61746ELLU: // tfi_Latn_BJ
+ case 0xB4B355534C61746ELLU: // tfn_Latn_US
+ case 0xB8B349444C61746ELLU: // tfo_Latn_ID
+ case 0xC4B350414C61746ELLU: // tfr_Latn_PA
+ case 0xCCB349444C61746ELLU: // tft_Latn_ID
+ case 0x7467504B41726162LLU: // tg_Arab_PK
+ case 0x7467544A4379726CLLU: // tg_Cyrl_TJ
+ case 0x80D34B454C61746ELLU: // tga_Latn_KE
+ case 0x84D34D594C61746ELLU: // tgb_Latn_MY
+ case 0x88D350474C61746ELLU: // tgc_Latn_PG
+ case 0x8CD34E474C61746ELLU: // tgd_Latn_NG
+ case 0x90D34E5044657661LLU: // tge_Deva_NP
+ case 0x94D3425454696274LLU: // tgf_Tibt_BT
+ case 0x9CD354544C61746ELLU: // tgh_Latn_TT
+ case 0xA0D350474C61746ELLU: // tgi_Latn_PG
+ case 0xA4D3494E4C61746ELLU: // tgj_Latn_IN
+ case 0xB4D350484C61746ELLU: // tgn_Latn_PH
+ case 0xB8D350474C61746ELLU: // tgo_Latn_PG
+ case 0xBCD356554C61746ELLU: // tgp_Latn_VU
+ case 0xC0D34D594C61746ELLU: // tgq_Latn_MY
+ case 0xC8D356554C61746ELLU: // tgs_Latn_VU
+ case 0xCCD350484C61746ELLU: // tgt_Latn_PH
+ case 0xD0D350474C61746ELLU: // tgu_Latn_PG
+ case 0xD4D342524C61746ELLU: // tgv_Latn_BR
+ case 0xD8D343494C61746ELLU: // tgw_Latn_CI
+ case 0xDCD343414C61746ELLU: // tgx_Latn_CA
+ case 0xE0D353534C61746ELLU: // tgy_Latn_SS
+ case 0xE4D341554C61746ELLU: // tgz_Latn_AU
+ case 0x7468544854686169LLU: // th_Thai_TH
+ case 0x8CF341554C61746ELLU: // thd_Latn_AU
+ case 0x90F34E5044657661LLU: // the_Deva_NP
+ case 0x94F34E5044657661LLU: // thf_Deva_NP
+ case 0x9CF34D584C61746ELLU: // thh_Latn_MX
+ case 0xA0F34C4154616C65LLU: // thi_Tale_LA
+ case 0xA8F34B454C61746ELLU: // thk_Latn_KE
+ case 0xACF34E5044657661LLU: // thl_Deva_NP
+ case 0xB0F3544854686169LLU: // thm_Thai_TH
+ case 0xBCF343414C61746ELLU: // thp_Latn_CA
+ case 0xC0F34E5044657661LLU: // thq_Deva_NP
+ case 0xC4F34E5044657661LLU: // thr_Deva_NP
+ case 0xC8F34E5044657661LLU: // ths_Deva_NP
+ case 0xCCF343414C61746ELLU: // tht_Latn_CA
+ case 0xD0F353534C61746ELLU: // thu_Latn_SS
+ case 0xD4F3445A4C61746ELLU: // thv_Latn_DZ
+ case 0xE0F34E474C61746ELLU: // thy_Latn_NG
+ case 0xE4F34E454C61746ELLU: // thz_Latn_NE
+ case 0x7469455445746869LLU: // ti_Ethi_ET
+ case 0x891353444C61746ELLU: // tic_Latn_SD
+ case 0x951350474C61746ELLU: // tif_Latn_PG
+ case 0x9913455245746869LLU: // tig_Ethi_ER
+ case 0x9D134D594C61746ELLU: // tih_Latn_MY
+ case 0xA11343444C61746ELLU: // tii_Latn_CD
+ case 0xA5134E5044657661LLU: // tij_Deva_NP
+ case 0xA913434D4C61746ELLU: // tik_Latn_CM
+ case 0xAD1355534C61746ELLU: // til_Latn_US
+ case 0xB11350474C61746ELLU: // tim_Latn_PG
+ case 0xB51352554379726CLLU: // tin_Cyrl_RU
+ case 0xB91350474C61746ELLU: // tio_Latn_PG
+ case 0xBD1349444C61746ELLU: // tip_Latn_ID
+ case 0xC11342464C61746ELLU: // tiq_Latn_BF
+ case 0xC91350484C61746ELLU: // tis_Latn_PH
+ case 0xCD13434F4C61746ELLU: // tit_Latn_CO
+ case 0xD11350484C61746ELLU: // tiu_Latn_PH
+ case 0xD5134E474C61746ELLU: // tiv_Latn_NG
+ case 0xD91341554C61746ELLU: // tiw_Latn_AU
+ case 0xDD1355534C61746ELLU: // tix_Latn_US
+ case 0xE11350484C61746ELLU: // tiy_Latn_PH
+ case 0x81334C524C61746ELLU: // tja_Latn_LR
+ case 0x993349444C61746ELLU: // tjg_Latn_ID
+ case 0xA133434E4C61746ELLU: // tji_Latn_CN
+ case 0xA53341554C61746ELLU: // tjj_Latn_AU
+ case 0xAD334D4D4D796D72LLU: // tjl_Mymr_MM
+ case 0xB53343494C61746ELLU: // tjn_Latn_CI
+ case 0xB933445A41726162LLU: // tjo_Arab_DZ
+ case 0xBD3341554C61746ELLU: // tjp_Latn_AU
+ case 0xC933434E4C61746ELLU: // tjs_Latn_CN
+ case 0xD13341554C61746ELLU: // tju_Latn_AU
+ case 0xD93341554C61746ELLU: // tjw_Latn_AU
+ case 0x746B544D4C61746ELLU: // tk_Latn_TM
+ case 0x815342524C61746ELLU: // tka_Latn_BR
+ case 0x8553494E44657661LLU: // tkb_Deva_IN
+ case 0x8D53544C4C61746ELLU: // tkd_Latn_TL
+ case 0x91534D5A4C61746ELLU: // tke_Latn_MZ
+ case 0x955342524C61746ELLU: // tkf_Latn_BR
+ case 0x99534D474C61746ELLU: // tkg_Latn_MG
+ case 0xAD53544B4C61746ELLU: // tkl_Latn_TK
+ case 0xBD5353424C61746ELLU: // tkp_Latn_SB
+ case 0xC1534E474C61746ELLU: // tkq_Latn_NG
+ case 0xC553415A4C61746ELLU: // tkr_Latn_AZ
+ case 0xC953495241726162LLU: // tks_Arab_IR
+ case 0xCD534E5044657661LLU: // tkt_Deva_NP
+ case 0xD1534D584C61746ELLU: // tku_Latn_MX
+ case 0xD55350474C61746ELLU: // tkv_Latn_PG
+ case 0xD95353424C61746ELLU: // tkw_Latn_SB
+ case 0xDD5349444C61746ELLU: // tkx_Latn_ID
+ case 0xE553564E4C61746ELLU: // tkz_Latn_VN
+ case 0x746C50484C61746ELLU: // tl_Latn_PH
+ case 0x81734D584C61746ELLU: // tla_Latn_MX
+ case 0x857349444C61746ELLU: // tlb_Latn_ID
+ case 0x89734D584C61746ELLU: // tlc_Latn_MX
+ case 0x8D7349444C61746ELLU: // tld_Latn_ID
+ case 0x957350474C61746ELLU: // tlf_Latn_PG
+ case 0x997349444C61746ELLU: // tlg_Latn_ID
+ case 0xA17355534C61746ELLU: // tli_Latn_US
+ case 0xA57355474C61746ELLU: // tlj_Latn_UG
+ case 0xA97349444C61746ELLU: // tlk_Latn_ID
+ case 0xAD7343444C61746ELLU: // tll_Latn_CD
+ case 0xB17356554C61746ELLU: // tlm_Latn_VU
+ case 0xB57349444C61746ELLU: // tln_Latn_ID
+ case 0xBD734D584C61746ELLU: // tlp_Latn_MX
+ case 0xC1734D4D4C61746ELLU: // tlq_Latn_MM
+ case 0xC57353424C61746ELLU: // tlr_Latn_SB
+ case 0xC97356554C61746ELLU: // tls_Latn_VU
+ case 0xCD7349444C61746ELLU: // tlt_Latn_ID
+ case 0xD17349444C61746ELLU: // tlu_Latn_ID
+ case 0xD57349444C61746ELLU: // tlv_Latn_ID
+ case 0xDD7350474C61746ELLU: // tlx_Latn_PG
+ case 0xE173415A4C61746ELLU: // tly_Latn_AZ
+ case 0x819354444C61746ELLU: // tma_Latn_TD
+ case 0x859356554C61746ELLU: // tmb_Latn_VU
+ case 0x899354444C61746ELLU: // tmc_Latn_TD
+ case 0x8D9350474C61746ELLU: // tmd_Latn_PG
+ case 0x919342524C61746ELLU: // tme_Latn_BR
+ case 0x959350594C61746ELLU: // tmf_Latn_PY
+ case 0x999349444C61746ELLU: // tmg_Latn_ID
+ case 0x9D934E454C61746ELLU: // tmh_Latn_NE
+ case 0xA19356554C61746ELLU: // tmi_Latn_VU
+ case 0xA59349444C61746ELLU: // tmj_Latn_ID
+ case 0xAD9349444C61746ELLU: // tml_Latn_ID
+ case 0xB193564E4C61746ELLU: // tmm_Latn_VN
+ case 0xB59349444C61746ELLU: // tmn_Latn_ID
+ case 0xB9934D594C61746ELLU: // tmo_Latn_MY
+ case 0xC19350474C61746ELLU: // tmq_Latn_PG
+ case 0xC593494C53797263LLU: // tmr_Syrc_IL
+ case 0xCD9356554C61746ELLU: // tmt_Latn_VU
+ case 0xD19349444C61746ELLU: // tmu_Latn_ID
+ case 0xD59343444C61746ELLU: // tmv_Latn_CD
+ case 0xD9934D594C61746ELLU: // tmw_Latn_MY
+ case 0xE19350474C61746ELLU: // tmy_Latn_PG
+ case 0xE59356454C61746ELLU: // tmz_Latn_VE
+ case 0x746E5A414C61746ELLU: // tn_Latn_ZA
+ case 0x81B3424F4C61746ELLU: // tna_Latn_BO
+ case 0x85B3434F4C61746ELLU: // tnb_Latn_CO
+ case 0x89B3434F4C61746ELLU: // tnc_Latn_CO
+ case 0x8DB3434F4C61746ELLU: // tnd_Latn_CO
+ case 0x99B354444C61746ELLU: // tng_Latn_TD
+ case 0x9DB350474C61746ELLU: // tnh_Latn_PG
+ case 0xA1B349444C61746ELLU: // tni_Latn_ID
+ case 0xA9B356554C61746ELLU: // tnk_Latn_VU
+ case 0xADB356554C61746ELLU: // tnl_Latn_VU
+ case 0xB1B349444C61746ELLU: // tnm_Latn_ID
+ case 0xB5B356554C61746ELLU: // tnn_Latn_VU
+ case 0xB9B3424F4C61746ELLU: // tno_Latn_BO
+ case 0xBDB356554C61746ELLU: // tnp_Latn_VU
+ case 0xC1B350524C61746ELLU: // tnq_Latn_PR
+ case 0xC5B3534E4C61746ELLU: // tnr_Latn_SN
+ case 0xC9B350474C61746ELLU: // tns_Latn_PG
+ case 0xCDB349444C61746ELLU: // tnt_Latn_ID
+ case 0xD5B3424443616B6DLLU: // tnv_Cakm_BD
+ case 0xD9B349444C61746ELLU: // tnw_Latn_ID
+ case 0xDDB353424C61746ELLU: // tnx_Latn_SB
+ case 0xE1B3545A4C61746ELLU: // tny_Latn_TZ
+ case 0x746F544F4C61746ELLU: // to_Latn_TO
+ case 0x85D341524C61746ELLU: // tob_Latn_AR
+ case 0x89D34D584C61746ELLU: // toc_Latn_MX
+ case 0x8DD3474E4C61746ELLU: // tod_Latn_GN
+ case 0x95D350474C61746ELLU: // tof_Latn_PG
+ case 0x99D34D574C61746ELLU: // tog_Latn_MW
+ case 0x9DD34D5A4C61746ELLU: // toh_Latn_MZ
+ case 0xA1D35A4D4C61746ELLU: // toi_Latn_ZM
+ case 0xA5D34D584C61746ELLU: // toj_Latn_MX
+ case 0xADD355534C61746ELLU: // tol_Latn_US
+ case 0xB1D349444C61746ELLU: // tom_Latn_ID
+ case 0xB9D34D584C61746ELLU: // too_Latn_MX
+ case 0xBDD34D584C61746ELLU: // top_Latn_MX
+ case 0xC1D353534C61746ELLU: // toq_Latn_SS
+ case 0xC5D343444C61746ELLU: // tor_Latn_CD
+ case 0xC9D34D584C61746ELLU: // tos_Latn_MX
+ case 0xD1D3564E4C61746ELLU: // tou_Latn_VN
+ case 0xD5D3495241726162LLU: // tov_Arab_IR
+ case 0xD9D355534C61746ELLU: // tow_Latn_US
+ case 0xDDD350574C61746ELLU: // tox_Latn_PW
+ case 0xE1D349444C61746ELLU: // toy_Latn_ID
+ case 0xE5D3434D4C61746ELLU: // toz_Latn_CM
+ case 0x81F350474C61746ELLU: // tpa_Latn_PG
+ case 0x89F34D584C61746ELLU: // tpc_Latn_MX
+ case 0x91F342444C61746ELLU: // tpe_Latn_BD
+ case 0x95F349444C61746ELLU: // tpf_Latn_ID
+ case 0x99F349444C61746ELLU: // tpg_Latn_ID
+ case 0xA1F350474C61746ELLU: // tpi_Latn_PG
+ case 0xA5F350594C61746ELLU: // tpj_Latn_PY
+ case 0xA9F342524C61746ELLU: // tpk_Latn_BR
+ case 0xADF34D584C61746ELLU: // tpl_Latn_MX
+ case 0xB1F347484C61746ELLU: // tpm_Latn_GH
+ case 0xB5F342524C61746ELLU: // tpn_Latn_BR
+ case 0xBDF34D584C61746ELLU: // tpp_Latn_MX
+ case 0xC5F342524C61746ELLU: // tpr_Latn_BR
+ case 0xCDF34D584C61746ELLU: // tpt_Latn_MX
+ case 0xD1F34B484B686D72LLU: // tpu_Khmr_KH
+ case 0xD5F34D504C61746ELLU: // tpv_Latn_MP
+ case 0xDDF34D584C61746ELLU: // tpx_Latn_MX
+ case 0xE1F342524C61746ELLU: // tpy_Latn_BR
+ case 0xE5F350474C61746ELLU: // tpz_Latn_PG
+ case 0x861342524C61746ELLU: // tqb_Latn_BR
+ case 0xAE1356554C61746ELLU: // tql_Latn_VU
+ case 0xB21350474C61746ELLU: // tqm_Latn_PG
+ case 0xB61355534C61746ELLU: // tqn_Latn_US
+ case 0xBA1350474C61746ELLU: // tqo_Latn_PG
+ case 0xBE1350474C61746ELLU: // tqp_Latn_PG
+ case 0xCE134D584C61746ELLU: // tqt_Latn_MX
+ case 0xD21353424C61746ELLU: // tqu_Latn_SB
+ case 0xDA1355534C61746ELLU: // tqw_Latn_US
+ case 0x747254524C61746ELLU: // tr_Latn_TR
+ case 0x8233414641726162LLU: // tra_Arab_AF
+ case 0x863350474C61746ELLU: // trb_Latn_PG
+ case 0x8A334D584C61746ELLU: // trc_Latn_MX
+ case 0x923349444C61746ELLU: // tre_Latn_ID
+ case 0x963354544C61746ELLU: // trf_Latn_TT
+ case 0x9A33494C48656272LLU: // trg_Hebr_IL
+ case 0x9E3350474C61746ELLU: // trh_Latn_PG
+ case 0xA23353524C61746ELLU: // tri_Latn_SR
+ case 0xA63354444C61746ELLU: // trj_Latn_TD
+ case 0xAE3347424C61746ELLU: // trl_Latn_GB
+ case 0xB233414641726162LLU: // trm_Arab_AF
+ case 0xB633424F4C61746ELLU: // trn_Latn_BO
+ case 0xBA33494E4C61746ELLU: // tro_Latn_IN
+ case 0xBE33494E4C61746ELLU: // trp_Latn_IN
+ case 0xC2334D584C61746ELLU: // trq_Latn_MX
+ case 0xC63350454C61746ELLU: // trr_Latn_PE
+ case 0xCA334D584C61746ELLU: // trs_Latn_MX
+ case 0xCE3349444C61746ELLU: // trt_Latn_ID
+ case 0xD23354524C61746ELLU: // tru_Latn_TR
+ case 0xD63354574C61746ELLU: // trv_Latn_TW
+ case 0xDA33504B41726162LLU: // trw_Arab_PK
+ case 0xDE334D594C61746ELLU: // trx_Latn_MY
+ case 0xE233494E4C61746ELLU: // try_Latn_IN
+ case 0xE63342524C61746ELLU: // trz_Latn_BR
+ case 0x74735A414C61746ELLU: // ts_Latn_ZA
+ case 0x825343474C61746ELLU: // tsa_Latn_CG
+ case 0x865345544C61746ELLU: // tsb_Latn_ET
+ case 0x8A534D5A4C61746ELLU: // tsc_Latn_MZ
+ case 0x8E5347524772656BLLU: // tsd_Grek_GR
+ case 0x9A5350484C61746ELLU: // tsg_Latn_PH
+ case 0x9E53434D4C61746ELLU: // tsh_Latn_CM
+ case 0xA25343414C61746ELLU: // tsi_Latn_CA
+ case 0xA653425454696274LLU: // tsj_Tibt_BT
+ case 0xAE53564E4C61746ELLU: // tsl_Latn_VN
+ case 0xBE5342464C61746ELLU: // tsp_Latn_BF
+ case 0xC65356554C61746ELLU: // tsr_Latn_VU
+ case 0xCE534D4C4C61746ELLU: // tst_Latn_ML
+ case 0xD25354574C61746ELLU: // tsu_Latn_TW
+ case 0xD65347414C61746ELLU: // tsv_Latn_GA
+ case 0xDA534E474C61746ELLU: // tsw_Latn_NG
+ case 0xDE5350474C61746ELLU: // tsx_Latn_PG
+ case 0xE6534D584C61746ELLU: // tsz_Latn_MX
+ case 0x747452554379726CLLU: // tt_Cyrl_RU
+ case 0x86734E474C61746ELLU: // ttb_Latn_NG
+ case 0x8A7347544C61746ELLU: // ttc_Latn_GT
+ case 0x8E7350474C61746ELLU: // ttd_Latn_PG
+ case 0x927350474C61746ELLU: // tte_Latn_PG
+ case 0x9673434D4C61746ELLU: // ttf_Latn_CM
+ case 0x9E734C414C616F6FLLU: // tth_Laoo_LA
+ case 0xA27349444C61746ELLU: // tti_Latn_ID
+ case 0xA67355474C61746ELLU: // ttj_Latn_UG
+ case 0xAA73434F4C61746ELLU: // ttk_Latn_CO
+ case 0xAE735A4D4C61746ELLU: // ttl_Latn_ZM
+ case 0xB27343414C61746ELLU: // ttm_Latn_CA
+ case 0xB67349444C61746ELLU: // ttn_Latn_ID
+ case 0xBA734C414C616F6FLLU: // tto_Laoo_LA
+ case 0xBE7349444C61746ELLU: // ttp_Latn_ID
+ case 0xC6734E474C61746ELLU: // ttr_Latn_NG
+ case 0xCA73544854686169LLU: // tts_Thai_TH
+ case 0xCE73415A4C61746ELLU: // ttt_Latn_AZ
+ case 0xD27350474C61746ELLU: // ttu_Latn_PG
+ case 0xD67350474C61746ELLU: // ttv_Latn_PG
+ case 0xDA734D594C61746ELLU: // ttw_Latn_MY
+ case 0xE27349444C61746ELLU: // tty_Latn_ID
+ case 0xE6734E5044657661LLU: // ttz_Deva_NP
+ case 0x829350474C61746ELLU: // tua_Latn_PG
+ case 0x869355534C61746ELLU: // tub_Latn_US
+ case 0x8A9350474C61746ELLU: // tuc_Latn_PG
+ case 0x8E9342524C61746ELLU: // tud_Latn_BR
+ case 0x9293434F4C61746ELLU: // tue_Latn_CO
+ case 0x9693434F4C61746ELLU: // tuf_Latn_CO
+ case 0x9A9354444C61746ELLU: // tug_Latn_TD
+ case 0x9E9350474C61746ELLU: // tuh_Latn_PG
+ case 0xA293434D4C61746ELLU: // tui_Latn_CM
+ case 0xA69349444C61746ELLU: // tuj_Latn_ID
+ case 0xAE934E474C61746ELLU: // tul_Latn_NG
+ case 0xB2934D574C61746ELLU: // tum_Latn_MW
+ case 0xB69355534C61746ELLU: // tun_Latn_US
+ case 0xBA9342524C61746ELLU: // tuo_Latn_BR
+ case 0xC29354444C61746ELLU: // tuq_Latn_TD
+ case 0xCA9343414C61746ELLU: // tus_Latn_CA
+ case 0xD29355534C61746ELLU: // tuu_Latn_US
+ case 0xD6934B454C61746ELLU: // tuv_Latn_KE
+ case 0xDE9342524C61746ELLU: // tux_Latn_BR
+ case 0xE2934B454C61746ELLU: // tuy_Latn_KE
+ case 0xE69342464C61746ELLU: // tuz_Latn_BF
+ case 0x82B353424C61746ELLU: // tva_Latn_SB
+ case 0x8EB34E474C61746ELLU: // tvd_Latn_NG
+ case 0x92B349444C61746ELLU: // tve_Latn_ID
+ case 0xA2B34E474C61746ELLU: // tvi_Latn_NG
+ case 0xAAB356554C61746ELLU: // tvk_Latn_VU
+ case 0xAEB354564C61746ELLU: // tvl_Latn_TV
+ case 0xB2B349444C61746ELLU: // tvm_Latn_ID
+ case 0xB6B34D4D4D796D72LLU: // tvn_Mymr_MM
+ case 0xBAB349444C61746ELLU: // tvo_Latn_ID
+ case 0xCAB34B454C61746ELLU: // tvs_Latn_KE
+ case 0xCEB3494E4C61746ELLU: // tvt_Latn_IN
+ case 0xD2B3434D4C61746ELLU: // tvu_Latn_CM
+ case 0xDAB349444C61746ELLU: // tvw_Latn_ID
+ case 0xDEB354574C61746ELLU: // tvx_Latn_TW
+ case 0x82D355534C61746ELLU: // twa_Latn_US
+ case 0x86D350484C61746ELLU: // twb_Latn_PH
+ case 0x8ED34E4C4C61746ELLU: // twd_Latn_NL
+ case 0x92D349444C61746ELLU: // twe_Latn_ID
+ case 0x96D355534C61746ELLU: // twf_Latn_US
+ case 0x9AD349444C61746ELLU: // twg_Latn_ID
+ case 0x9ED3564E4C61746ELLU: // twh_Latn_VN
+ case 0xAED34D5A4C61746ELLU: // twl_Latn_MZ
+ case 0xB2D3494E44657661LLU: // twm_Deva_IN
+ case 0xB6D3434D4C61746ELLU: // twn_Latn_CM
+ case 0xBAD342574C61746ELLU: // two_Latn_BW
+ case 0xBED350474C61746ELLU: // twp_Latn_PG
+ case 0xC2D34E454C61746ELLU: // twq_Latn_NE
+ case 0xC6D34D584C61746ELLU: // twr_Latn_MX
+ case 0xCED342524C61746ELLU: // twt_Latn_BR
+ case 0xD2D349444C61746ELLU: // twu_Latn_ID
+ case 0xDAD350474C61746ELLU: // tww_Latn_PG
+ case 0xDED34D5A4C61746ELLU: // twx_Latn_MZ
+ case 0xE2D349444C61746ELLU: // twy_Latn_ID
+ case 0x82F34D594C61746ELLU: // txa_Latn_MY
+ case 0x92F349444C61746ELLU: // txe_Latn_ID
+ case 0x9AF3434E54616E67LLU: // txg_Tang_CN
+ case 0xA2F342524C61746ELLU: // txi_Latn_BR
+ case 0xA6F34E474C61746ELLU: // txj_Latn_NG
+ case 0xB2F349444C61746ELLU: // txm_Latn_ID
+ case 0xB6F349444C61746ELLU: // txn_Latn_ID
+ case 0xBAF3494E546F746FLLU: // txo_Toto_IN
+ case 0xC2F349444C61746ELLU: // txq_Latn_ID
+ case 0xCAF349444C61746ELLU: // txs_Latn_ID
+ case 0xCEF349444C61746ELLU: // txt_Latn_ID
+ case 0xD2F342524C61746ELLU: // txu_Latn_BR
+ case 0xDEF34D594C61746ELLU: // txx_Latn_MY
+ case 0xE2F34D474C61746ELLU: // txy_Latn_MG
+ case 0x747950464C61746ELLU: // ty_Latn_PF
+ case 0x831350474C61746ELLU: // tya_Latn_PG
+ case 0x93134E474C61746ELLU: // tye_Latn_NG
+ case 0x9F13564E4C61746ELLU: // tyh_Latn_VN
+ case 0xA31343474C61746ELLU: // tyi_Latn_CG
+ case 0xA713564E4C61746ELLU: // tyj_Latn_VN
+ case 0xAF13564E4C61746ELLU: // tyl_Latn_VN
+ case 0xB71349444C61746ELLU: // tyn_Latn_ID
+ case 0xBF1341554C61746ELLU: // typ_Latn_AU
+ case 0xC713564E54617674LLU: // tyr_Tavt_VN
+ case 0xCB13564E4C61746ELLU: // tys_Latn_VN
+ case 0xCF13564E4C61746ELLU: // tyt_Latn_VN
+ case 0xD31342574C61746ELLU: // tyu_Latn_BW
+ case 0xD71352554379726CLLU: // tyv_Cyrl_RU
+ case 0xDF1343474C61746ELLU: // tyx_Latn_CG
+ case 0xE3134E474C61746ELLU: // tyy_Latn_NG
+ case 0xE713564E4C61746ELLU: // tyz_Latn_VN
+ case 0x9F334D584C61746ELLU: // tzh_Latn_MX
+ case 0xA73347544C61746ELLU: // tzj_Latn_GT
+ case 0xB3334D414C61746ELLU: // tzm_Latn_MA
+ case 0xB73349444C61746ELLU: // tzn_Latn_ID
+ case 0xBB334D584C61746ELLU: // tzo_Latn_MX
+ case 0xDF3350474C61746ELLU: // tzx_Latn_PG
+ case 0xB01442524C61746ELLU: // uam_Latn_BR
+ case 0xC41450474C61746ELLU: // uar_Latn_PG
+ case 0x80344E474C61746ELLU: // uba_Latn_NG
+ case 0xA03454444C61746ELLU: // ubi_Latn_TD
+ case 0xAC3450484C61746ELLU: // ubl_Latn_PH
+ case 0xC43450474C61746ELLU: // ubr_Latn_PG
+ case 0xD03450474C61746ELLU: // ubu_Latn_PG
+ case 0xE03454524C61746ELLU: // uby_Latn_TR
+ case 0x80744E474C61746ELLU: // uda_Latn_NG
+ case 0x907452554379726CLLU: // ude_Cyrl_RU
+ case 0x9874494E4D6C796DLLU: // udg_Mlym_IN
+ case 0xA07452554379726CLLU: // udi_Cyrl_RU
+ case 0xA47449444C61746ELLU: // udj_Latn_ID
+ case 0xAC74434D4C61746ELLU: // udl_Latn_CM
+ case 0xB07452554379726CLLU: // udm_Cyrl_RU
+ case 0xD07453444C61746ELLU: // udu_Latn_SD
+ case 0xC89449444C61746ELLU: // ues_Latn_ID
+ case 0xA0B450474C61746ELLU: // ufi_Latn_PG
+ case 0x7567434E41726162LLU: // ug_Arab_CN
+ case 0x75674B5A4379726CLLU: // ug_Cyrl_KZ
+ case 0x80D4535955676172LLU: // uga_Ugar_SY
+ case 0x84D441554C61746ELLU: // ugb_Latn_AU
+ case 0x90D453424C61746ELLU: // uge_Latn_SB
+ case 0x9CD452554379726CLLU: // ugh_Cyrl_RU
+ case 0xB8D4544854686169LLU: // ugo_Thai_TH
+ case 0x80F44E474C61746ELLU: // uha_Latn_NG
+ case 0xB4F449444C61746ELLU: // uhn_Latn_ID
+ case 0xC91450474C61746ELLU: // uis_Latn_PG
+ case 0xD514434D4C61746ELLU: // uiv_Latn_CM
+ case 0xA1344E474C61746ELLU: // uji_Latn_NG
+ case 0x756B55414379726CLLU: // uk_Cyrl_UA
+ case 0x815449444C61746ELLU: // uka_Latn_ID
+ case 0x995450474C61746ELLU: // ukg_Latn_PG
+ case 0x9D5443464C61746ELLU: // ukh_Latn_CF
+ case 0xA154494E4F727961LLU: // uki_Orya_IN
+ case 0xA9544D4D4C61746ELLU: // ukk_Latn_MM
+ case 0xBD544E474C61746ELLU: // ukp_Latn_NG
+ case 0xC1544E474C61746ELLU: // ukq_Latn_NG
+ case 0xD1544E474C61746ELLU: // uku_Latn_NG
+ case 0xD55453534C61746ELLU: // ukv_Latn_SS
+ case 0xD9544E474C61746ELLU: // ukw_Latn_NG
+ case 0xE15441554C61746ELLU: // uky_Latn_AU
+ case 0x81744E474C61746ELLU: // ula_Latn_NG
+ case 0x85744E474C61746ELLU: // ulb_Latn_NG
+ case 0x897452554379726CLLU: // ulc_Cyrl_RU
+ case 0x917441524C61746ELLU: // ule_Latn_AR
+ case 0x957449444C61746ELLU: // ulf_Latn_ID
+ case 0xA174464D4C61746ELLU: // uli_Latn_FM
+ case 0xA97441554C61746ELLU: // ulk_Latn_AU
+ case 0xB17449444C61746ELLU: // ulm_Latn_ID
+ case 0xB57450474C61746ELLU: // uln_Latn_PG
+ case 0xD17449444C61746ELLU: // ulu_Latn_ID
+ case 0xD9744E494C61746ELLU: // ulw_Latn_NI
+ case 0xE1744E474C61746ELLU: // uly_Latn_NG
+ case 0x819455534C61746ELLU: // uma_Latn_US
+ case 0x8594414F4C61746ELLU: // umb_Latn_AO
+ case 0x8D9441554C61746ELLU: // umd_Latn_AU
+ case 0x999441554C61746ELLU: // umg_Latn_AU
+ case 0xA1944D594C61746ELLU: // umi_Latn_MY
+ case 0xB1944E474C61746ELLU: // umm_Latn_NG
+ case 0xB5944D4D4C61746ELLU: // umn_Latn_MM
+ case 0xB99442524C61746ELLU: // umo_Latn_BR
+ case 0xBD9441554C61746ELLU: // ump_Latn_AU
+ case 0xC59441554C61746ELLU: // umr_Latn_AU
+ case 0xC99449444C61746ELLU: // ums_Latn_ID
+ case 0x81B450474C61746ELLU: // una_Latn_PG
+ case 0x91B44E474C61746ELLU: // une_Latn_NG
+ case 0x99B441554C61746ELLU: // ung_Latn_AU
+ case 0xA1B450474C61746ELLU: // uni_Latn_PG
+ case 0xA9B442524C61746ELLU: // unk_Latn_BR
+ case 0xB1B455534C61746ELLU: // unm_Latn_US
+ case 0xB5B441554C61746ELLU: // unn_Latn_AU
+ case 0xC5B4494E42656E67LLU: // unr_Beng_IN
+ case 0xC5B44E5044657661LLU: // unr_Deva_NP
+ case 0xD1B450474C61746ELLU: // unu_Latn_PG
+ case 0xDDB4494E42656E67LLU: // unx_Beng_IN
+ case 0xE5B449444C61746ELLU: // unz_Latn_ID
+ case 0xB5D454574C61746ELLU: // uon_Latn_TW
+ case 0xA1F450474C61746ELLU: // upi_Latn_PG
+ case 0xD5F456554C61746ELLU: // upv_Latn_VU
+ case 0x7572504B41726162LLU: // ur_Arab_PK
+ case 0x823450454C61746ELLU: // ura_Latn_PE
+ case 0x863442524C61746ELLU: // urb_Latn_BR
+ case 0x8A3441554C61746ELLU: // urc_Latn_AU
+ case 0x9234424F4C61746ELLU: // ure_Latn_BO
+ case 0x963441554C61746ELLU: // urf_Latn_AU
+ case 0x9A3450474C61746ELLU: // urg_Latn_PG
+ case 0x9E344E474C61746ELLU: // urh_Latn_NG
+ case 0xA23450474C61746ELLU: // uri_Latn_PG
+ case 0xAA34544854686169LLU: // urk_Thai_TH
+ case 0xB23450474C61746ELLU: // urm_Latn_PG
+ case 0xB63449444C61746ELLU: // urn_Latn_ID
+ case 0xBA3450474C61746ELLU: // uro_Latn_PG
+ case 0xBE3442524C61746ELLU: // urp_Latn_BR
+ case 0xC63456554C61746ELLU: // urr_Latn_VU
+ case 0xCE3450474C61746ELLU: // urt_Latn_PG
+ case 0xD23442524C61746ELLU: // uru_Latn_BR
+ case 0xD63450474C61746ELLU: // urv_Latn_PG
+ case 0xDA3450474C61746ELLU: // urw_Latn_PG
+ case 0xDE3450474C61746ELLU: // urx_Latn_PG
+ case 0xE23449444C61746ELLU: // ury_Latn_ID
+ case 0xE63442524C61746ELLU: // urz_Latn_BR
+ case 0x825450474C61746ELLU: // usa_Latn_PG
+ case 0x9E54504B41726162LLU: // ush_Arab_PK
+ case 0xA25442444C61746ELLU: // usi_Latn_BD
+ case 0xAA54434D4C61746ELLU: // usk_Latn_CM
+ case 0xBE5447544C61746ELLU: // usp_Latn_GT
+ case 0xCA544E474C61746ELLU: // uss_Latn_NG
+ case 0xD25450474C61746ELLU: // usu_Latn_PG
+ case 0x82744E474C61746ELLU: // uta_Latn_NG
+ case 0x927455534C61746ELLU: // ute_Latn_US
+ case 0x9E744E474C61746ELLU: // uth_Latn_NG
+ case 0xBE7453424C61746ELLU: // utp_Latn_SB
+ case 0xC6744E474C61746ELLU: // utr_Latn_NG
+ case 0xD27450474C61746ELLU: // utu_Latn_PG
+ case 0xB29447454772656BLLU: // uum_Grek_GE
+ case 0xC69456554C61746ELLU: // uur_Latn_VU
+ case 0x92B44E434C61746ELLU: // uve_Latn_NC
+ case 0x9EB450474C61746ELLU: // uvh_Latn_PG
+ case 0xAEB450474C61746ELLU: // uvl_Latn_PG
+ case 0x82D441554C61746ELLU: // uwa_Latn_AU
+ case 0x83144E474C61746ELLU: // uya_Latn_NG
+ case 0x757A414641726162LLU: // uz_Arab_AF
+ case 0x757A555A4C61746ELLU: // uz_Latn_UZ
+ case 0xCB34414641726162LLU: // uzs_Arab_AF
+ case 0x8015494E54616D6CLLU: // vaa_Taml_IN
+ case 0x901543464C61746ELLU: // vae_Latn_CF
+ case 0x9415495241726162LLU: // vaf_Arab_IR
+ case 0x981547484C61746ELLU: // vag_Latn_GH
+ case 0x9C15494E44657661LLU: // vah_Deva_IN
+ case 0xA0154C5256616969LLU: // vai_Vaii_LR
+ case 0xA4154E414C61746ELLU: // vaj_Latn_NA
+ case 0xAC1550474C61746ELLU: // val_Latn_PG
+ case 0xB01550474C61746ELLU: // vam_Latn_PG
+ case 0xB41550474C61746ELLU: // van_Latn_PG
+ case 0xB81556554C61746ELLU: // vao_Latn_VU
+ case 0xBC15494E4C61746ELLU: // vap_Latn_IN
+ case 0xC4154D584C61746ELLU: // var_Latn_MX
+ case 0xC815494E44657661LLU: // vas_Deva_IN
+ case 0xD01543444C61746ELLU: // vau_Latn_CD
+ case 0xD415494E44657661LLU: // vav_Deva_IN
+ case 0xE0154E5044657661LLU: // vay_Deva_NP
+ case 0x843549444C61746ELLU: // vbb_Latn_ID
+ case 0xA83550484C61746ELLU: // vbk_Latn_PH
+ case 0x76655A414C61746ELLU: // ve_Latn_ZA
+ case 0x889549544C61746ELLU: // vec_Latn_IT
+ case 0xB0954E474C61746ELLU: // vem_Latn_NG
+ case 0xB89555534C61746ELLU: // veo_Latn_US
+ case 0xBC9552554C61746ELLU: // vep_Latn_RU
+ case 0xC4954E474C61746ELLU: // ver_Latn_NG
+ case 0xC4D5504B41726162LLU: // vgr_Arab_PK
+ case 0x7669564E4C61746ELLU: // vi_Latn_VN
+ case 0x891553584C61746ELLU: // vic_Latn_SX
+ case 0x8D15545A4C61746ELLU: // vid_Latn_TZ
+ case 0x951543474C61746ELLU: // vif_Latn_CG
+ case 0x991542464C61746ELLU: // vig_Latn_BF
+ case 0xAD1541524C61746ELLU: // vil_Latn_AR
+ case 0xB515545A4C61746ELLU: // vin_Latn_TZ
+ case 0xCD154E474C61746ELLU: // vit_Latn_NG
+ case 0xD51550474C61746ELLU: // viv_Latn_PG
+ case 0xA935494E44657661LLU: // vjk_Deva_IN
+ case 0x815541554C61746ELLU: // vka_Latn_AU
+ case 0xA55554444C61746ELLU: // vkj_Latn_TD
+ case 0xA95549444C61746ELLU: // vkk_Latn_ID
+ case 0xAD5549444C61746ELLU: // vkl_Latn_ID
+ case 0xB15542524C61746ELLU: // vkm_Latn_BR
+ case 0xB5554E474C61746ELLU: // vkn_Latn_NG
+ case 0xB95549444C61746ELLU: // vko_Latn_ID
+ case 0xBD55494E4C61746ELLU: // vkp_Latn_IN
+ case 0xCD5549444C61746ELLU: // vkt_Latn_ID
+ case 0xD15541554C61746ELLU: // vku_Latn_AU
+ case 0xE5554E474C61746ELLU: // vkz_Latn_NG
+ case 0xBD7556554C61746ELLU: // vlp_Latn_VU
+ case 0xC97542454C61746ELLU: // vls_Latn_BE
+ case 0x819541554C61746ELLU: // vma_Latn_AU
+ case 0x859541554C61746ELLU: // vmb_Latn_AU
+ case 0x89954D584C61746ELLU: // vmc_Latn_MX
+ case 0x8D95494E4B6E6461LLU: // vmd_Knda_IN
+ case 0x919549444C61746ELLU: // vme_Latn_ID
+ case 0x959544454C61746ELLU: // vmf_Latn_DE
+ case 0x999550474C61746ELLU: // vmg_Latn_PG
+ case 0x9D95495241726162LLU: // vmh_Arab_IR
+ case 0xA19541554C61746ELLU: // vmi_Latn_AU
+ case 0xA5954D584C61746ELLU: // vmj_Latn_MX
+ case 0xA9954D5A4C61746ELLU: // vmk_Latn_MZ
+ case 0xAD9541554C61746ELLU: // vml_Latn_AU
+ case 0xB1954D584C61746ELLU: // vmm_Latn_MX
+ case 0xBD954D584C61746ELLU: // vmp_Latn_MX
+ case 0xC1954D584C61746ELLU: // vmq_Latn_MX
+ case 0xC5954D5A4C61746ELLU: // vmr_Latn_MZ
+ case 0xC99549444C61746ELLU: // vms_Latn_ID
+ case 0xD19541554C61746ELLU: // vmu_Latn_AU
+ case 0xD9954D5A4C61746ELLU: // vmw_Latn_MZ
+ case 0xDD954D584C61746ELLU: // vmx_Latn_MX
+ case 0xE1954D584C61746ELLU: // vmy_Latn_MX
+ case 0xE5954D584C61746ELLU: // vmz_Latn_MX
+ case 0xA9B553424C61746ELLU: // vnk_Latn_SB
+ case 0xB1B556554C61746ELLU: // vnm_Latn_VU
+ case 0xBDB556554C61746ELLU: // vnp_Latn_VU
+ case 0xC5D54E474C61746ELLU: // vor_Latn_NG
+ case 0xCDD552554C61746ELLU: // vot_Latn_RU
+ case 0x823556554C61746ELLU: // vra_Latn_VU
+ case 0xBA3545454C61746ELLU: // vro_Latn_EE
+ case 0xCA3553424C61746ELLU: // vrs_Latn_SB
+ case 0xCE3556554C61746ELLU: // vrt_Latn_VU
+ case 0xBA7549444C61746ELLU: // vto_Latn_ID
+ case 0xB29547414C61746ELLU: // vum_Latn_GA
+ case 0xB695545A4C61746ELLU: // vun_Latn_TZ
+ case 0xCE95434D4C61746ELLU: // vut_Latn_CM
+ case 0x82D5434E4C61746ELLU: // vwa_Latn_CN
+ case 0x776142454C61746ELLU: // wa_Latn_BE
+ case 0x801655534C61746ELLU: // waa_Latn_US
+ case 0x841650474C61746ELLU: // wab_Latn_PG
+ case 0x881655534C61746ELLU: // wac_Latn_US
+ case 0x8C1649444C61746ELLU: // wad_Latn_ID
+ case 0x901643484C61746ELLU: // wae_Latn_CH
+ case 0x941642524C61746ELLU: // waf_Latn_BR
+ case 0x981650474C61746ELLU: // wag_Latn_PG
+ case 0x9C1649444C61746ELLU: // wah_Latn_ID
+ case 0xA01649444C61746ELLU: // wai_Latn_ID
+ case 0xA41650474C61746ELLU: // waj_Latn_PG
+ case 0xAC16455445746869LLU: // wal_Ethi_ET
+ case 0xB01655534C61746ELLU: // wam_Latn_US
+ case 0xB41643494C61746ELLU: // wan_Latn_CI
+ case 0xBC1647594C61746ELLU: // wap_Latn_GY
+ case 0xC01641554C61746ELLU: // waq_Latn_AU
+ case 0xC41650484C61746ELLU: // war_Latn_PH
+ case 0xC81655534C61746ELLU: // was_Latn_US
+ case 0xCC1650474C61746ELLU: // wat_Latn_PG
+ case 0xD01642524C61746ELLU: // wau_Latn_BR
+ case 0xD4164E474C61746ELLU: // wav_Latn_NG
+ case 0xD81642524C61746ELLU: // waw_Latn_BR
+ case 0xDC1650474C61746ELLU: // wax_Latn_PG
+ case 0xE01653524C61746ELLU: // way_Latn_SR
+ case 0xE41650474C61746ELLU: // waz_Latn_PG
+ case 0x803656454C61746ELLU: // wba_Latn_VE
+ case 0x843649444C61746ELLU: // wbb_Latn_ID
+ case 0x903649444C61746ELLU: // wbe_Latn_ID
+ case 0x943642464C61746ELLU: // wbf_Latn_BF
+ case 0x9C36545A4C61746ELLU: // wbh_Latn_TZ
+ case 0xA036545A4C61746ELLU: // wbi_Latn_TZ
+ case 0xA436545A4C61746ELLU: // wbj_Latn_TZ
+ case 0xA836414641726162LLU: // wbk_Arab_AF
+ case 0xAC36504B4C61746ELLU: // wbl_Latn_PK
+ case 0xB036434E4C61746ELLU: // wbm_Latn_CN
+ case 0xBC3641554C61746ELLU: // wbp_Latn_AU
+ case 0xC036494E54656C75LLU: // wbq_Telu_IN
+ case 0xC436494E44657661LLU: // wbr_Deva_IN
+ case 0xCC3641554C61746ELLU: // wbt_Latn_AU
+ case 0xD43641554C61746ELLU: // wbv_Latn_AU
+ case 0xD83649444C61746ELLU: // wbw_Latn_ID
+ case 0x805642524C61746ELLU: // wca_Latn_BR
+ case 0xA05654474C61746ELLU: // wci_Latn_TG
+ case 0x8C7647414C61746ELLU: // wdd_Latn_GA
+ case 0x987650474C61746ELLU: // wdg_Latn_PG
+ case 0xA47641554C61746ELLU: // wdj_Latn_AU
+ case 0xA87641554C61746ELLU: // wdk_Latn_AU
+ case 0xCC7643414C61746ELLU: // wdt_Latn_CA
+ case 0xD07641554C61746ELLU: // wdu_Latn_AU
+ case 0xE07641554C61746ELLU: // wdy_Latn_AU
+ case 0x889643494C61746ELLU: // wec_Latn_CI
+ case 0x8C9650474C61746ELLU: // wed_Latn_PG
+ case 0x989641554C61746ELLU: // weg_Latn_AU
+ case 0x9C96434D4C61746ELLU: // weh_Latn_CM
+ case 0xA09650474C61746ELLU: // wei_Latn_PG
+ case 0xB096424A4C61746ELLU: // wem_Latn_BJ
+ case 0xB89649444C61746ELLU: // weo_Latn_ID
+ case 0xBC9644454C61746ELLU: // wep_Latn_DE
+ case 0xC49650474C61746ELLU: // wer_Latn_PG
+ case 0xC896434D4C61746ELLU: // wes_Latn_CM
+ case 0xCC9649444C61746ELLU: // wet_Latn_ID
+ case 0xD0964D4D4C61746ELLU: // weu_Latn_MM
+ case 0xD89649444C61746ELLU: // wew_Latn_ID
+ case 0x98B649444C61746ELLU: // wfg_Latn_ID
+ case 0x80D641554C61746ELLU: // wga_Latn_AU
+ case 0x84D650474C61746ELLU: // wgb_Latn_PG
+ case 0x98D641554C61746ELLU: // wgg_Latn_AU
+ case 0xA0D650474C61746ELLU: // wgi_Latn_PG
+ case 0xB8D649444C61746ELLU: // wgo_Latn_ID
+ case 0xD0D641554C61746ELLU: // wgu_Latn_AU
+ case 0xE0D641554C61746ELLU: // wgy_Latn_AU
+ case 0x80F649444C61746ELLU: // wha_Latn_ID
+ case 0x98F650474C61746ELLU: // whg_Latn_PG
+ case 0xA8F649444C61746ELLU: // whk_Latn_ID
+ case 0xD0F649444C61746ELLU: // whu_Latn_ID
+ case 0x851642464C61746ELLU: // wib_Latn_BF
+ case 0x891655534C61746ELLU: // wic_Latn_US
+ case 0x911641554C61746ELLU: // wie_Latn_AU
+ case 0x951641554C61746ELLU: // wif_Latn_AU
+ case 0x991641554C61746ELLU: // wig_Latn_AU
+ case 0x9D1641554C61746ELLU: // wih_Latn_AU
+ case 0xA11650474C61746ELLU: // wii_Latn_PG
+ case 0xA51641554C61746ELLU: // wij_Latn_AU
+ case 0xA91641554C61746ELLU: // wik_Latn_AU
+ case 0xAD1641554C61746ELLU: // wil_Latn_AU
+ case 0xB11641554C61746ELLU: // wim_Latn_AU
+ case 0xB51655534C61746ELLU: // win_Latn_US
+ case 0xC51642524C61746ELLU: // wir_Latn_BR
+ case 0xD11650474C61746ELLU: // wiu_Latn_PG
+ case 0xD51650474C61746ELLU: // wiv_Latn_PG
+ case 0xE11655534C61746ELLU: // wiy_Latn_US
+ case 0x81364E474C61746ELLU: // wja_Latn_NG
+ case 0xA1364E474C61746ELLU: // wji_Latn_NG
+ case 0x8156545A4C61746ELLU: // wka_Latn_TZ
+ case 0x8D5649444C61746ELLU: // wkd_Latn_ID
+ case 0xC55641554C61746ELLU: // wkr_Latn_AU
+ case 0xD95641554C61746ELLU: // wkw_Latn_AU
+ case 0xE15641554C61746ELLU: // wky_Latn_AU
+ case 0x817650474C61746ELLU: // wla_Latn_PG
+ case 0x9176455445746869LLU: // wle_Ethi_ET
+ case 0x997641554C61746ELLU: // wlg_Latn_AU
+ case 0x9D76544C4C61746ELLU: // wlh_Latn_TL
+ case 0xA17649444C61746ELLU: // wli_Latn_ID
+ case 0xB17647424C61746ELLU: // wlm_Latn_GB
+ case 0xB976494441726162LLU: // wlo_Arab_ID
+ case 0xC57656554C61746ELLU: // wlr_Latn_VU
+ case 0xC97657464C61746ELLU: // wls_Latn_WF
+ case 0xD17641554C61746ELLU: // wlu_Latn_AU
+ case 0xD57641524C61746ELLU: // wlv_Latn_AR
+ case 0xD97649444C61746ELLU: // wlw_Latn_ID
+ case 0xDD7647484C61746ELLU: // wlx_Latn_GH
+ case 0x81964E474C61746ELLU: // wma_Latn_NG
+ case 0x859641554C61746ELLU: // wmb_Latn_AU
+ case 0x899650474C61746ELLU: // wmc_Latn_PG
+ case 0x8D9642524C61746ELLU: // wmd_Latn_BR
+ case 0x91964E5044657661LLU: // wme_Deva_NP
+ case 0x9D96544C4C61746ELLU: // wmh_Latn_TL
+ case 0xA19641554C61746ELLU: // wmi_Latn_AU
+ case 0xB19649444C61746ELLU: // wmm_Latn_ID
+ case 0xB5964E434C61746ELLU: // wmn_Latn_NC
+ case 0xB99650474C61746ELLU: // wmo_Latn_PG
+ case 0xC99649444C61746ELLU: // wms_Latn_ID
+ case 0xCD9641554C61746ELLU: // wmt_Latn_AU
+ case 0xD9964D5A4C61746ELLU: // wmw_Latn_MZ
+ case 0xDD9650474C61746ELLU: // wmx_Latn_PG
+ case 0x85B650474C61746ELLU: // wnb_Latn_PG
+ case 0x89B650474C61746ELLU: // wnc_Latn_PG
+ case 0x8DB641554C61746ELLU: // wnd_Latn_AU
+ case 0x91B6504B41726162LLU: // wne_Arab_PK
+ case 0x99B649444C61746ELLU: // wng_Latn_ID
+ case 0xA1B64B4D41726162LLU: // wni_Arab_KM
+ case 0xA9B649444C61746ELLU: // wnk_Latn_ID
+ case 0xB1B641554C61746ELLU: // wnm_Latn_AU
+ case 0xB5B641554C61746ELLU: // wnn_Latn_AU
+ case 0xB9B649444C61746ELLU: // wno_Latn_ID
+ case 0xBDB650474C61746ELLU: // wnp_Latn_PG
+ case 0xD1B650474C61746ELLU: // wnu_Latn_PG
+ case 0xD9B655534C61746ELLU: // wnw_Latn_US
+ case 0xE1B641554C61746ELLU: // wny_Latn_AU
+ case 0x776F534E4C61746ELLU: // wo_Latn_SN
+ case 0x81D641554C61746ELLU: // woa_Latn_AU
+ case 0x85D643494C61746ELLU: // wob_Latn_CI
+ case 0x89D650474C61746ELLU: // woc_Latn_PG
+ case 0x8DD649444C61746ELLU: // wod_Latn_ID
+ case 0x91D6464D4C61746ELLU: // woe_Latn_FM
+ case 0x95D6474D4C61746ELLU: // wof_Latn_GM
+ case 0x99D650474C61746ELLU: // wog_Latn_PG
+ case 0xA1D649444C61746ELLU: // woi_Latn_ID
+ case 0xA9D6434D4C61746ELLU: // wok_Latn_CM
+ case 0xB1D64E474C61746ELLU: // wom_Latn_NG
+ case 0xB5D643444C61746ELLU: // won_Latn_CD
+ case 0xB9D649444C61746ELLU: // woo_Latn_ID
+ case 0xC5D649444C61746ELLU: // wor_Latn_ID
+ case 0xC9D650474C61746ELLU: // wos_Latn_PG
+ case 0xD9D649444C61746ELLU: // wow_Latn_ID
+ case 0x89F656454C61746ELLU: // wpc_Latn_VE
+ case 0x863641554C61746ELLU: // wrb_Latn_AU
+ case 0x9A3641554C61746ELLU: // wrg_Latn_AU
+ case 0x9E3641554C61746ELLU: // wrh_Latn_AU
+ case 0xA23641554C61746ELLU: // wri_Latn_AU
+ case 0xAA3641554C61746ELLU: // wrk_Latn_AU
+ case 0xAE3641554C61746ELLU: // wrl_Latn_AU
+ case 0xB23641554C61746ELLU: // wrm_Latn_AU
+ case 0xBA3641554C61746ELLU: // wro_Latn_AU
+ case 0xBE3649444C61746ELLU: // wrp_Latn_ID
+ case 0xC63641554C61746ELLU: // wrr_Latn_AU
+ case 0xCA3650474C61746ELLU: // wrs_Latn_PG
+ case 0xD23649444C61746ELLU: // wru_Latn_ID
+ case 0xD63650474C61746ELLU: // wrv_Latn_PG
+ case 0xDA3641554C61746ELLU: // wrw_Latn_AU
+ case 0xDE3649444C61746ELLU: // wrx_Latn_ID
+ case 0xE63641554C61746ELLU: // wrz_Latn_AU
+ case 0x825649444C61746ELLU: // wsa_Latn_ID
+ case 0x9A56494E476F6E67LLU: // wsg_Gong_IN
+ case 0xA25656554C61746ELLU: // wsi_Latn_VU
+ case 0xAA5650474C61746ELLU: // wsk_Latn_PG
+ case 0xC65650474C61746ELLU: // wsr_Latn_PG
+ case 0xCA5647484C61746ELLU: // wss_Latn_GH
+ case 0xD25642524C61746ELLU: // wsu_Latn_BR
+ case 0xD656414641726162LLU: // wsv_Arab_AF
+ case 0x8676545A4C61746ELLU: // wtb_Latn_TZ
+ case 0x967650474C61746ELLU: // wtf_Latn_PG
+ case 0x9E7641554C61746ELLU: // wth_Latn_AU
+ case 0xA27645544C61746ELLU: // wti_Latn_ET
+ case 0xAA7650474C61746ELLU: // wtk_Latn_PG
+ case 0xB276494E44657661LLU: // wtm_Deva_IN
+ case 0xDA7649444C61746ELLU: // wtw_Latn_ID
+ case 0x829641554C61746ELLU: // wua_Latn_AU
+ case 0x869641554C61746ELLU: // wub_Latn_AU
+ case 0x8E9654474C61746ELLU: // wud_Latn_TG
+ case 0xAE9649444C61746ELLU: // wul_Latn_ID
+ case 0xB29647414C61746ELLU: // wum_Latn_GA
+ case 0xB696545A4C61746ELLU: // wun_Latn_TZ
+ case 0xC69641554C61746ELLU: // wur_Latn_AU
+ case 0xCE9650474C61746ELLU: // wut_Latn_PG
+ case 0xD296434E48616E73LLU: // wuu_Hans_CN
+ case 0xD69650474C61746ELLU: // wuv_Latn_PG
+ case 0xDE9641554C61746ELLU: // wux_Latn_AU
+ case 0xE29649444C61746ELLU: // wuy_Latn_ID
+ case 0x82D6424A4C61746ELLU: // wwa_Latn_BJ
+ case 0x86D641554C61746ELLU: // wwb_Latn_AU
+ case 0xBAD656554C61746ELLU: // wwo_Latn_VU
+ case 0xC6D641554C61746ELLU: // wwr_Latn_AU
+ case 0xDAD6434D4C61746ELLU: // www_Latn_CM
+ case 0xDAF641554C61746ELLU: // wxw_Latn_AU
+ case 0x871641554C61746ELLU: // wyb_Latn_AU
+ case 0xA31641554C61746ELLU: // wyi_Latn_AU
+ case 0xB316504C4C61746ELLU: // wym_Latn_PL
+ case 0xB71655534C61746ELLU: // wyn_Latn_US
+ case 0xC71642524C61746ELLU: // wyr_Latn_BR
+ case 0xE316464A4C61746ELLU: // wyy_Latn_FJ
+ case 0x801745534C61746ELLU: // xaa_Latn_ES
+ case 0x84174E474C61746ELLU: // xab_Latn_NG
+ case 0x9817415A41676862LLU: // xag_Aghb_AZ
+ case 0xA01742524C61746ELLU: // xai_Latn_BR
+ case 0xA41742524C61746ELLU: // xaj_Latn_BR
+ case 0xA81756454C61746ELLU: // xak_Latn_VE
+ case 0xAC1752554379726CLLU: // xal_Cyrl_RU
+ case 0xB0175A414C61746ELLU: // xam_Latn_ZA
+ case 0xB417455445746869LLU: // xan_Ethi_ET
+ case 0xB817564E4C61746ELLU: // xao_Latn_VN
+ case 0xC41750474C61746ELLU: // xar_Latn_PG
+ case 0xC81752554379726CLLU: // xas_Cyrl_RU
+ case 0xCC1742524C61746ELLU: // xat_Latn_BR
+ case 0xD01749444C61746ELLU: // xau_Latn_ID
+ case 0xD41742524C61746ELLU: // xav_Latn_BR
+ case 0xD81755534C61746ELLU: // xaw_Latn_US
+ case 0xE01749444C61746ELLU: // xay_Latn_ID
+ case 0x843741554C61746ELLU: // xbb_Latn_AU
+ case 0x8C3741554C61746ELLU: // xbd_Latn_AU
+ case 0x903741554C61746ELLU: // xbe_Latn_AU
+ case 0x983741554C61746ELLU: // xbg_Latn_AU
+ case 0xA03750474C61746ELLU: // xbi_Latn_PG
+ case 0xA43741554C61746ELLU: // xbj_Latn_AU
+ case 0xB03746524C61746ELLU: // xbm_Latn_FR
+ case 0xB4374D594C61746ELLU: // xbn_Latn_MY
+ case 0xBC3741554C61746ELLU: // xbp_Latn_AU
+ case 0xC43749444C61746ELLU: // xbr_Latn_ID
+ case 0xD83742524C61746ELLU: // xbw_Latn_BR
+ case 0xE03741554C61746ELLU: // xby_Latn_AU
+ case 0x9C5755534C61746ELLU: // xch_Latn_US
+ case 0xB857555A43687273LLU: // xco_Chrs_UZ
+ case 0xC457545243617269LLU: // xcr_Cari_TR
+ case 0x807741554C61746ELLU: // xda_Latn_AU
+ case 0xA87741554C61746ELLU: // xdk_Latn_AU
+ case 0xB877414F4C61746ELLU: // xdo_Latn_AO
+ case 0xC07752554379726CLLU: // xdq_Cyrl_RU
+ case 0xE07749444C61746ELLU: // xdy_Latn_ID
+ case 0x8C97434D4C61746ELLU: // xed_Latn_CM
+ case 0x98975A414C61746ELLU: // xeg_Latn_ZA
+ case 0xB09749444C61746ELLU: // xem_Latn_ID
+ case 0xC49742524C61746ELLU: // xer_Latn_BR
+ case 0xC89750474C61746ELLU: // xes_Latn_PG
+ case 0xCC9742524C61746ELLU: // xet_Latn_BR
+ case 0xD09750474C61746ELLU: // xeu_Latn_PG
+ case 0x84D743494C61746ELLU: // xgb_Latn_CI
+ case 0x8CD741554C61746ELLU: // xgd_Latn_AU
+ case 0x98D741554C61746ELLU: // xgg_Latn_AU
+ case 0xA0D741554C61746ELLU: // xgi_Latn_AU
+ case 0xB0D741554C61746ELLU: // xgm_Latn_AU
+ case 0xD0D741554C61746ELLU: // xgu_Latn_AU
+ case 0xD8D741554C61746ELLU: // xgw_Latn_AU
+ case 0x78685A414C61746ELLU: // xh_Latn_ZA
+ case 0x90F7504B41726162LLU: // xhe_Arab_PK
+ case 0xB0F74B484B686D72LLU: // xhm_Khmr_KH
+ case 0xD4F7564E4C61746ELLU: // xhv_Latn_VN
+ case 0xA1175A414C61746ELLU: // xii_Latn_ZA
+ case 0xB51747544C61746ELLU: // xin_Latn_GT
+ case 0xC51742524C61746ELLU: // xir_Latn_BR
+ case 0xC917494E4F727961LLU: // xis_Orya_IN
+ case 0xE11742524C61746ELLU: // xiy_Latn_BR
+ case 0x853741554C61746ELLU: // xjb_Latn_AU
+ case 0xCD3741554C61746ELLU: // xjt_Latn_AU
+ case 0x8157504B41726162LLU: // xka_Arab_PK
+ case 0x8557424A4C61746ELLU: // xkb_Latn_BJ
+ case 0x8957495241726162LLU: // xkc_Arab_IR
+ case 0x8D5749444C61746ELLU: // xkd_Latn_ID
+ case 0x915749444C61746ELLU: // xke_Latn_ID
+ case 0x9557425454696274LLU: // xkf_Tibt_BT
+ case 0x99574D4C4C61746ELLU: // xkg_Latn_ML
+ case 0xA557495241726162LLU: // xkj_Arab_IR
+ case 0xAD5749444C61746ELLU: // xkl_Latn_ID
+ case 0xB55749444C61746ELLU: // xkn_Latn_ID
+ case 0xBD57495241726162LLU: // xkp_Arab_IR
+ case 0xC15749444C61746ELLU: // xkq_Latn_ID
+ case 0xC55742524C61746ELLU: // xkr_Latn_BR
+ case 0xC95749444C61746ELLU: // xks_Latn_ID
+ case 0xCD5747484C61746ELLU: // xkt_Latn_GH
+ case 0xD15743474C61746ELLU: // xku_Latn_CG
+ case 0xD55742574C61746ELLU: // xkv_Latn_BW
+ case 0xD95749444C61746ELLU: // xkw_Latn_ID
+ case 0xDD5750474C61746ELLU: // xkx_Latn_PG
+ case 0xE1574D594C61746ELLU: // xky_Latn_MY
+ case 0xE55742544C61746ELLU: // xkz_Latn_BT
+ case 0x817750474C61746ELLU: // xla_Latn_PG
+ case 0x897754524C796369LLU: // xlc_Lyci_TR
+ case 0x8D7754524C796469LLU: // xld_Lydi_TR
+ case 0xE1774952456C796DLLU: // xly_Elym_IR
+ case 0x8197534F4C61746ELLU: // xma_Latn_SO
+ case 0x8597434D4C61746ELLU: // xmb_Latn_CM
+ case 0x89974D5A4C61746ELLU: // xmc_Latn_MZ
+ case 0x8D97434D4C61746ELLU: // xmd_Latn_CM
+ case 0x9597474547656F72LLU: // xmf_Geor_GE
+ case 0x9997434D4C61746ELLU: // xmg_Latn_CM
+ case 0x9D9741554C61746ELLU: // xmh_Latn_AU
+ case 0xA597434D4C61746ELLU: // xmj_Latn_CM
+ case 0xB19749444C61746ELLU: // xmm_Latn_ID
+ case 0xB597434E4D616E69LLU: // xmn_Mani_CN
+ case 0xB99742524C61746ELLU: // xmo_Latn_BR
+ case 0xBD9741554C61746ELLU: // xmp_Latn_AU
+ case 0xC19741554C61746ELLU: // xmq_Latn_AU
+ case 0xC59753444D657263LLU: // xmr_Merc_SD
+ case 0xCD9749444C61746ELLU: // xmt_Latn_ID
+ case 0xD19741554C61746ELLU: // xmu_Latn_AU
+ case 0xD5974D474C61746ELLU: // xmv_Latn_MG
+ case 0xD9974D474C61746ELLU: // xmw_Latn_MG
+ case 0xDD9749444C61746ELLU: // xmx_Latn_ID
+ case 0xE19741554C61746ELLU: // xmy_Latn_AU
+ case 0xE59749444C61746ELLU: // xmz_Latn_ID
+ case 0x81B753414E617262LLU: // xna_Narb_SA
+ case 0x85B754574C61746ELLU: // xnb_Latn_TW
+ case 0xA1B741554C61746ELLU: // xni_Latn_AU
+ case 0xA5B7545A4C61746ELLU: // xnj_Latn_TZ
+ case 0xA9B741554C61746ELLU: // xnk_Latn_AU
+ case 0xB1B741554C61746ELLU: // xnm_Latn_AU
+ case 0xB5B750484C61746ELLU: // xnn_Latn_PH
+ case 0xC1B74D5A4C61746ELLU: // xnq_Latn_MZ
+ case 0xC5B7494E44657661LLU: // xnr_Deva_IN
+ case 0xCDB755534C61746ELLU: // xnt_Latn_US
+ case 0xD1B741554C61746ELLU: // xnu_Latn_AU
+ case 0xE1B741554C61746ELLU: // xny_Latn_AU
+ case 0xE5B745474C61746ELLU: // xnz_Latn_EG
+ case 0x89D74E474C61746ELLU: // xoc_Latn_NG
+ case 0x8DD749444C61746ELLU: // xod_Latn_ID
+ case 0x99D755474C61746ELLU: // xog_Latn_UG
+ case 0xA1D750474C61746ELLU: // xoi_Latn_PG
+ case 0xA9D742524C61746ELLU: // xok_Latn_BR
+ case 0xB1D753444C61746ELLU: // xom_Latn_SD
+ case 0xB5D747484C61746ELLU: // xon_Latn_GH
+ case 0xB9D742524C61746ELLU: // xoo_Latn_BR
+ case 0xBDD750474C61746ELLU: // xop_Latn_PG
+ case 0xC5D742524C61746ELLU: // xor_Latn_BR
+ case 0xD9D750474C61746ELLU: // xow_Latn_PG
+ case 0x81F741554C61746ELLU: // xpa_Latn_AU
+ case 0x85F741554C61746ELLU: // xpb_Latn_AU
+ case 0x8DF741554C61746ELLU: // xpd_Latn_AU
+ case 0x95F741554C61746ELLU: // xpf_Latn_AU
+ case 0x99F754524772656BLLU: // xpg_Grek_TR
+ case 0x9DF741554C61746ELLU: // xph_Latn_AU
+ case 0xA1F747424F67616DLLU: // xpi_Ogam_GB
+ case 0xA5F741554C61746ELLU: // xpj_Latn_AU
+ case 0xA9F742524C61746ELLU: // xpk_Latn_BR
+ case 0xADF741554C61746ELLU: // xpl_Latn_AU
+ case 0xB1F752554379726CLLU: // xpm_Cyrl_RU
+ case 0xB5F742524C61746ELLU: // xpn_Latn_BR
+ case 0xB9F74D584C61746ELLU: // xpo_Latn_MX
+ case 0xC1F755534C61746ELLU: // xpq_Latn_US
+ case 0xC5F7495250727469LLU: // xpr_Prti_IR
+ case 0xCDF741554C61746ELLU: // xpt_Latn_AU
+ case 0xD5F741554C61746ELLU: // xpv_Latn_AU
+ case 0xD9F741554C61746ELLU: // xpw_Latn_AU
+ case 0xDDF741554C61746ELLU: // xpx_Latn_AU
+ case 0xE5F741554C61746ELLU: // xpz_Latn_AU
+ case 0x823742524C61746ELLU: // xra_Latn_BR
+ case 0x863742464C61746ELLU: // xrb_Latn_BF
+ case 0x8E3741554C61746ELLU: // xrd_Latn_AU
+ case 0x923742524C61746ELLU: // xre_Latn_BR
+ case 0x9A3741554C61746ELLU: // xrg_Latn_AU
+ case 0xA23742524C61746ELLU: // xri_Latn_BR
+ case 0xB23752554379726CLLU: // xrm_Cyrl_RU
+ case 0xB63752554379726CLLU: // xrn_Cyrl_RU
+ case 0xC63749544C61746ELLU: // xrr_Latn_IT
+ case 0xD23741554C61746ELLU: // xru_Latn_AU
+ case 0xDA3750474C61746ELLU: // xrw_Latn_PG
+ case 0x8257594553617262LLU: // xsa_Sarb_YE
+ case 0x865750484C61746ELLU: // xsb_Latn_PH
+ case 0x925749444C61746ELLU: // xse_Latn_ID
+ case 0x9E574E474C61746ELLU: // xsh_Latn_NG
+ case 0xA25750474C61746ELLU: // xsi_Latn_PG
+ case 0xB25747484C61746ELLU: // xsm_Latn_GH
+ case 0xB6574E474C61746ELLU: // xsn_Latn_NG
+ case 0xBE5750474C61746ELLU: // xsp_Latn_PG
+ case 0xC2574D5A4C61746ELLU: // xsq_Latn_MZ
+ case 0xC6574E5044657661LLU: // xsr_Deva_NP
+ case 0xD25756454C61746ELLU: // xsu_Latn_VE
+ case 0xE25754574C61746ELLU: // xsy_Latn_TW
+ case 0x82774D584C61746ELLU: // xta_Latn_MX
+ case 0x86774D584C61746ELLU: // xtb_Latn_MX
+ case 0x8A7753444C61746ELLU: // xtc_Latn_SD
+ case 0x8E774D584C61746ELLU: // xtd_Latn_MX
+ case 0x927749444C61746ELLU: // xte_Latn_ID
+ case 0x9E7741554C61746ELLU: // xth_Latn_AU
+ case 0xA2774D584C61746ELLU: // xti_Latn_MX
+ case 0xA6774D584C61746ELLU: // xtj_Latn_MX
+ case 0xAE774D584C61746ELLU: // xtl_Latn_MX
+ case 0xB2774D584C61746ELLU: // xtm_Latn_MX
+ case 0xB6774D584C61746ELLU: // xtn_Latn_MX
+ case 0xBE774D584C61746ELLU: // xtp_Latn_MX
+ case 0xC277495242726168LLU: // xtq_Brah_IR
+ case 0xCA774D584C61746ELLU: // xts_Latn_MX
+ case 0xCE774D584C61746ELLU: // xtt_Latn_MX
+ case 0xD2774D584C61746ELLU: // xtu_Latn_MX
+ case 0xD67741554C61746ELLU: // xtv_Latn_AU
+ case 0xDA7742524C61746ELLU: // xtw_Latn_BR
+ case 0xE2774D584C61746ELLU: // xty_Latn_MX
+ case 0x8697494E54616D6CLLU: // xub_Taml_IN
+ case 0x8E9741554C61746ELLU: // xud_Latn_AU
+ case 0xA697494E54616D6CLLU: // xuj_Taml_IN
+ case 0xAE9741554C61746ELLU: // xul_Latn_AU
+ case 0xB29749544C61746ELLU: // xum_Latn_IT
+ case 0xB69741554C61746ELLU: // xun_Latn_AU
+ case 0xBA9754444C61746ELLU: // xuo_Latn_TD
+ case 0xCE9741554C61746ELLU: // xut_Latn_AU
+ case 0xD2974E414C61746ELLU: // xuu_Latn_NA
+ case 0x92B749544974616CLLU: // xve_Ital_IT
+ case 0xA2B7414641726162LLU: // xvi_Arab_AF
+ case 0xB6B745534C61746ELLU: // xvn_Latn_ES
+ case 0xBAB749544C61746ELLU: // xvo_Latn_IT
+ case 0xCAB749544C61746ELLU: // xvs_Latn_IT
+ case 0x82D742524C61746ELLU: // xwa_Latn_BR
+ case 0x8ED741554C61746ELLU: // xwd_Latn_AU
+ case 0x92D7424A4C61746ELLU: // xwe_Latn_BJ
+ case 0xA6D741554C61746ELLU: // xwj_Latn_AU
+ case 0xAAD741554C61746ELLU: // xwk_Latn_AU
+ case 0xAED7424A4C61746ELLU: // xwl_Latn_BJ
+ case 0xBAD752554379726CLLU: // xwo_Cyrl_RU
+ case 0xC6D749444C61746ELLU: // xwr_Latn_ID
+ case 0xCED741554C61746ELLU: // xwt_Latn_AU
+ case 0xDAD741554C61746ELLU: // xww_Latn_AU
+ case 0x86F747484C61746ELLU: // xxb_Latn_GH
+ case 0xAAF749444C61746ELLU: // xxk_Latn_ID
+ case 0xB2F741554C61746ELLU: // xxm_Latn_AU
+ case 0xC6F742524C61746ELLU: // xxr_Latn_BR
+ case 0xCEF749444C61746ELLU: // xxt_Latn_ID
+ case 0x831741554C61746ELLU: // xya_Latn_AU
+ case 0x871741554C61746ELLU: // xyb_Latn_AU
+ case 0xA71741554C61746ELLU: // xyj_Latn_AU
+ case 0xAB1741554C61746ELLU: // xyk_Latn_AU
+ case 0xAF1742524C61746ELLU: // xyl_Latn_BR
+ case 0xCF1741554C61746ELLU: // xyt_Latn_AU
+ case 0xE31741554C61746ELLU: // xyy_Latn_AU
+ case 0x9F37434E4D617263LLU: // xzh_Marc_CN
+ case 0xBF374D584C61746ELLU: // xzp_Latn_MX
+ case 0x801850454C61746ELLU: // yaa_Latn_PE
+ case 0x841842524C61746ELLU: // yab_Latn_BR
+ case 0x881849444C61746ELLU: // yac_Latn_ID
+ case 0x8C1850454C61746ELLU: // yad_Latn_PE
+ case 0x901856454C61746ELLU: // yae_Latn_VE
+ case 0x941843444C61746ELLU: // yaf_Latn_CD
+ case 0x9818434C4C61746ELLU: // yag_Latn_CL
+ case 0x9C18544A4C61746ELLU: // yah_Latn_TJ
+ case 0xA018544A4379726CLLU: // yai_Cyrl_TJ
+ case 0xA41843464C61746ELLU: // yaj_Latn_CF
+ case 0xA81855534C61746ELLU: // yak_Latn_US
+ case 0xAC18474E4C61746ELLU: // yal_Latn_GN
+ case 0xB018434D4C61746ELLU: // yam_Latn_CM
+ case 0xB4184E494C61746ELLU: // yan_Latn_NI
+ case 0xB8184D5A4C61746ELLU: // yao_Latn_MZ
+ case 0xBC18464D4C61746ELLU: // yap_Latn_FM
+ case 0xC0184D584C61746ELLU: // yaq_Latn_MX
+ case 0xC41856454C61746ELLU: // yar_Latn_VE
+ case 0xC818434D4C61746ELLU: // yas_Latn_CM
+ case 0xCC18434D4C61746ELLU: // yat_Latn_CM
+ case 0xD01856454C61746ELLU: // yau_Latn_VE
+ case 0xD418434D4C61746ELLU: // yav_Latn_CM
+ case 0xD81842524C61746ELLU: // yaw_Latn_BR
+ case 0xDC18414F4C61746ELLU: // yax_Latn_AO
+ case 0xE0184E474C61746ELLU: // yay_Latn_NG
+ case 0xE4184E474C61746ELLU: // yaz_Latn_NG
+ case 0x80384E474C61746ELLU: // yba_Latn_NG
+ case 0x8438434D4C61746ELLU: // ybb_Latn_CM
+ case 0x9038434E4C61746ELLU: // ybe_Latn_CN
+ case 0x9C384E5044657661LLU: // ybh_Deva_NP
+ case 0xA0384E5044657661LLU: // ybi_Deva_NP
+ case 0xA4384E474C61746ELLU: // ybj_Latn_NG
+ case 0xAC384E474C61746ELLU: // ybl_Latn_NG
+ case 0xB03850474C61746ELLU: // ybm_Latn_PG
+ case 0xB43842524C61746ELLU: // ybn_Latn_BR
+ case 0xB83850474C61746ELLU: // ybo_Latn_PG
+ case 0xDC3850474C61746ELLU: // ybx_Latn_PG
+ case 0xE03850474C61746ELLU: // yby_Latn_PG
+ case 0xAC58434E4C61746ELLU: // ycl_Latn_CN
+ case 0xB458434F4C61746ELLU: // ycn_Latn_CO
+ case 0xC45854574C61746ELLU: // ycr_Latn_TW
+ case 0x807841554C61746ELLU: // yda_Latn_AU
+ case 0x907850474C61746ELLU: // yde_Latn_PG
+ case 0x9878504B41726162LLU: // ydg_Arab_PK
+ case 0xA87850474C61746ELLU: // ydk_Latn_PG
+ case 0x8098494E4D6C796DLLU: // yea_Mlym_IN
+ case 0x889844454C61746ELLU: // yec_Latn_DE
+ case 0x909850474C61746ELLU: // yee_Latn_PG
+ case 0xA098434D4C61746ELLU: // yei_Latn_CM
+ case 0xA49847524772656BLLU: // yej_Grek_GR
+ case 0xAC9843444C61746ELLU: // yel_Latn_CD
+ case 0xC4984E474C61746ELLU: // yer_Latn_NG
+ case 0xC8984E474C61746ELLU: // yes_Latn_NG
+ case 0xCC9849444C61746ELLU: // yet_Latn_ID
+ case 0xD098494E54656C75LLU: // yeu_Telu_IN
+ case 0xD49850474C61746ELLU: // yev_Latn_PG
+ case 0xE09842574C61746ELLU: // yey_Latn_BW
+ case 0x80D841554C61746ELLU: // yga_Latn_AU
+ case 0xA0D841554C61746ELLU: // ygi_Latn_AU
+ case 0xACD850474C61746ELLU: // ygl_Latn_PG
+ case 0xB0D850474C61746ELLU: // ygm_Latn_PG
+ case 0xBCD8434E506C7264LLU: // ygp_Plrd_CN
+ case 0xC4D850474C61746ELLU: // ygr_Latn_PG
+ case 0xD0D841554C61746ELLU: // ygu_Latn_AU
+ case 0xD8D850474C61746ELLU: // ygw_Latn_PG
+ case 0x8CF8494C48656272LLU: // yhd_Hebr_IL
+ case 0x7969554148656272LLU: // yi_Hebr_UA
+ case 0x811841554C61746ELLU: // yia_Latn_AU
+ case 0x9918434E59696969LLU: // yig_Yiii_CN
+ case 0x9D18444548656272LLU: // yih_Hebr_DE
+ case 0xA11841554C61746ELLU: // yii_Latn_AU
+ case 0xA51841554C61746ELLU: // yij_Latn_AU
+ case 0xAD1841554C61746ELLU: // yil_Latn_AU
+ case 0xB118494E4C61746ELLU: // yim_Latn_IN
+ case 0xC51849444C61746ELLU: // yir_Latn_ID
+ case 0xC91850474C61746ELLU: // yis_Latn_PG
+ case 0xD518434E59696969LLU: // yiv_Yiii_CN
+ case 0x815850484C61746ELLU: // yka_Latn_PH
+ case 0x995852554379726CLLU: // ykg_Cyrl_RU
+ case 0x9D584D4E4379726CLLU: // ykh_Cyrl_MN
+ case 0xA15849444C61746ELLU: // yki_Latn_ID
+ case 0xA95850474C61746ELLU: // ykk_Latn_PG
+ case 0xB15850474C61746ELLU: // ykm_Latn_PG
+ case 0xB958434D4C61746ELLU: // yko_Latn_CM
+ case 0xC55850474C61746ELLU: // ykr_Latn_PG
+ case 0xE15843464C61746ELLU: // yky_Latn_CF
+ case 0x817850474C61746ELLU: // yla_Latn_PG
+ case 0x857850474C61746ELLU: // ylb_Latn_PG
+ case 0x917850474C61746ELLU: // yle_Latn_PG
+ case 0x997850474C61746ELLU: // ylg_Latn_PG
+ case 0xA17849444C61746ELLU: // yli_Latn_ID
+ case 0xAD7850474C61746ELLU: // yll_Latn_PG
+ case 0xC57841554C61746ELLU: // ylr_Latn_AU
+ case 0xD17850474C61746ELLU: // ylu_Latn_PG
+ case 0xE1784E434C61746ELLU: // yly_Latn_NC
+ case 0x859850474C61746ELLU: // ymb_Latn_PG
+ case 0x919850454C61746ELLU: // yme_Latn_PE
+ case 0x999843444C61746ELLU: // ymg_Latn_CD
+ case 0xA9984D5A4C61746ELLU: // ymk_Latn_MZ
+ case 0xAD9850474C61746ELLU: // yml_Latn_PG
+ case 0xB198534F4C61746ELLU: // ymm_Latn_SO
+ case 0xB59849444C61746ELLU: // ymn_Latn_ID
+ case 0xB99850474C61746ELLU: // ymo_Latn_PG
+ case 0xBD9850474C61746ELLU: // ymp_Latn_PG
+ case 0x81B8434E506C7264LLU: // yna_Plrd_CN
+ case 0x8DB841554C61746ELLU: // ynd_Latn_AU
+ case 0x99B843444C61746ELLU: // yng_Latn_CD
+ case 0xA9B852554379726CLLU: // ynk_Cyrl_RU
+ case 0xADB850474C61746ELLU: // ynl_Latn_PG
+ case 0xC1B84E474C61746ELLU: // ynq_Latn_NG
+ case 0xC9B843444C61746ELLU: // yns_Latn_CD
+ case 0xD1B8434F4C61746ELLU: // ynu_Latn_CO
+ case 0x796F4E474C61746ELLU: // yo_Latn_NG
+ case 0x85D850474C61746ELLU: // yob_Latn_PG
+ case 0x99D850484C61746ELLU: // yog_Latn_PH
+ case 0xA1D84A504A70616ELLU: // yoi_Jpan_JP
+ case 0xA9D855534C61746ELLU: // yok_Latn_US
+ case 0xADD849454C61746ELLU: // yol_Latn_IE
+ case 0xB1D843444C61746ELLU: // yom_Latn_CD
+ case 0xB5D850474C61746ELLU: // yon_Latn_PG
+ case 0xCDD84E474C61746ELLU: // yot_Latn_NG
+ case 0xE1D8544854686169LLU: // yoy_Thai_TH
+ case 0x823850474C61746ELLU: // yra_Latn_PG
+ case 0x863850474C61746ELLU: // yrb_Latn_PG
+ case 0x923843494C61746ELLU: // yre_Latn_CI
+ case 0xAA3852554379726CLLU: // yrk_Cyrl_RU
+ case 0xAE3842524C61746ELLU: // yrl_Latn_BR
+ case 0xB23841554C61746ELLU: // yrm_Latn_AU
+ case 0xBA3842524C61746ELLU: // yro_Latn_BR
+ case 0xCA3849444C61746ELLU: // yrs_Latn_ID
+ case 0xDA3850474C61746ELLU: // yrw_Latn_PG
+ case 0xE23841554C61746ELLU: // yry_Latn_AU
+ case 0x8E58434E59696969LLU: // ysd_Yiii_CN
+ case 0xB658434E59696969LLU: // ysn_Yiii_CN
+ case 0xBE58434E59696969LLU: // ysp_Yiii_CN
+ case 0xC65852554379726CLLU: // ysr_Cyrl_RU
+ case 0xCA5850474C61746ELLU: // yss_Latn_PG
+ case 0xE258434E506C7264LLU: // ysy_Plrd_CN
+ case 0xDA7850474C61746ELLU: // ytw_Latn_PG
+ case 0xE27841554C61746ELLU: // yty_Latn_AU
+ case 0x82984D584C61746ELLU: // yua_Latn_MX
+ case 0x869841554C61746ELLU: // yub_Latn_AU
+ case 0x8A9855534C61746ELLU: // yuc_Latn_US
+ case 0x8E98494C48656272LLU: // yud_Hebr_IL
+ case 0x9298434E48616E73LLU: // yue_Hans_CN
+ case 0x9298484B48616E74LLU: // yue_Hant_HK
+ case 0x969855534C61746ELLU: // yuf_Latn_US
+ case 0x9A9852554379726CLLU: // yug_Cyrl_RU
+ case 0xA298434F4C61746ELLU: // yui_Latn_CO
+ case 0xA69850474C61746ELLU: // yuj_Latn_PG
+ case 0xAE9843464C61746ELLU: // yul_Latn_CF
+ case 0xB29855534C61746ELLU: // yum_Latn_US
+ case 0xB6984E474C61746ELLU: // yun_Latn_NG
+ case 0xBE98434F4C61746ELLU: // yup_Latn_CO
+ case 0xC298424F4C61746ELLU: // yuq_Latn_BO
+ case 0xC69855534C61746ELLU: // yur_Latn_US
+ case 0xCE9850474C61746ELLU: // yut_Latn_PG
+ case 0xDA9850474C61746ELLU: // yuw_Latn_PG
+ case 0xDE9852554379726CLLU: // yux_Cyrl_RU
+ case 0xE698424F4C61746ELLU: // yuz_Latn_BO
+ case 0x82B849444C61746ELLU: // yva_Latn_ID
+ case 0xCEB856454C61746ELLU: // yvt_Latn_VE
+ case 0x82D850474C61746ELLU: // ywa_Latn_PG
+ case 0x9AD841554C61746ELLU: // ywg_Latn_AU
+ case 0xB6D842524C61746ELLU: // ywn_Latn_BR
+ case 0xC2D8434E506C7264LLU: // ywq_Plrd_CN
+ case 0xC6D841554C61746ELLU: // ywr_Latn_AU
+ case 0xD2D8434E506C7264LLU: // ywu_Plrd_CN
+ case 0xDAD841554C61746ELLU: // yww_Latn_AU
+ case 0x82F841554C61746ELLU: // yxa_Latn_AU
+ case 0x9AF841554C61746ELLU: // yxg_Latn_AU
+ case 0xAEF841554C61746ELLU: // yxl_Latn_AU
+ case 0xB2F841554C61746ELLU: // yxm_Latn_AU
+ case 0xD2F841554C61746ELLU: // yxu_Latn_AU
+ case 0xE2F841554C61746ELLU: // yxy_Latn_AU
+ case 0xC71841554C61746ELLU: // yyr_Latn_AU
+ case 0xD31850474C61746ELLU: // yyu_Latn_PG
+ case 0x7A61434E4C61746ELLU: // za_Latn_CN
+ case 0x80194D584C61746ELLU: // zaa_Latn_MX
+ case 0x84194D584C61746ELLU: // zab_Latn_MX
+ case 0x88194D584C61746ELLU: // zac_Latn_MX
+ case 0x8C194D584C61746ELLU: // zad_Latn_MX
+ case 0x90194D584C61746ELLU: // zae_Latn_MX
+ case 0x94194D584C61746ELLU: // zaf_Latn_MX
+ case 0x981953444C61746ELLU: // zag_Latn_SD
+ case 0x9C194E474C61746ELLU: // zah_Latn_NG
+ case 0xA419545A4C61746ELLU: // zaj_Latn_TZ
+ case 0xA819545A4C61746ELLU: // zak_Latn_TZ
+ case 0xB0194D584C61746ELLU: // zam_Latn_MX
+ case 0xB8194D584C61746ELLU: // zao_Latn_MX
+ case 0xBC194D584C61746ELLU: // zap_Latn_MX
+ case 0xC0194D584C61746ELLU: // zaq_Latn_MX
+ case 0xC4194D584C61746ELLU: // zar_Latn_MX
+ case 0xC8194D584C61746ELLU: // zas_Latn_MX
+ case 0xCC194D584C61746ELLU: // zat_Latn_MX
+ case 0xD019494E54696274LLU: // zau_Tibt_IN
+ case 0xD4194D584C61746ELLU: // zav_Latn_MX
+ case 0xD8194D584C61746ELLU: // zaw_Latn_MX
+ case 0xDC194D584C61746ELLU: // zax_Latn_MX
+ case 0xE01945544C61746ELLU: // zay_Latn_ET
+ case 0xE4194E474C61746ELLU: // zaz_Latn_NG
+ case 0x88394D594C61746ELLU: // zbc_Latn_MY
+ case 0x90394D594C61746ELLU: // zbe_Latn_MY
+ case 0xCC3949444C61746ELLU: // zbt_Latn_ID
+ case 0xD0394E474C61746ELLU: // zbu_Latn_NG
+ case 0xD8394D594C61746ELLU: // zbw_Latn_MY
+ case 0x80594D584C61746ELLU: // zca_Latn_MX
+ case 0x9C59434E48616E69LLU: // zch_Hani_CN
+ case 0xA4794B4D41726162LLU: // zdj_Arab_KM
+ case 0x80994E4C4C61746ELLU: // zea_Latn_NL
+ case 0x989950474C61746ELLU: // zeg_Latn_PG
+ case 0x9C99434E48616E69LLU: // zeh_Hani_CN
+ case 0xB0994E474C61746ELLU: // zem_Latn_NG
+ case 0xB4994D5254666E67LLU: // zen_Tfng_MR
+ case 0x80D9545A4C61746ELLU: // zga_Latn_TZ
+ case 0x84D9434E48616E69LLU: // zgb_Hani_CN
+ case 0x9CD94D4154666E67LLU: // zgh_Tfng_MA
+ case 0xB0D9434E48616E69LLU: // zgm_Hani_CN
+ case 0xB4D9434E48616E69LLU: // zgn_Hani_CN
+ case 0xC4D950474C61746ELLU: // zgr_Latn_PG
+ case 0x7A685457426F706FLLU: // zh_Bopo_TW
+ case 0x7A68545748616E62LLU: // zh_Hanb_TW
+ case 0x7A68434E48616E73LLU: // zh_Hans_CN
+ case 0x7A68545748616E74LLU: // zh_Hant_TW
+ case 0x8CF9434E48616E69LLU: // zhd_Hani_CN
+ case 0xA0F94E474C61746ELLU: // zhi_Latn_NG
+ case 0xB4F9434E4C61746ELLU: // zhn_Latn_CN
+ case 0xD8F9434D4C61746ELLU: // zhw_Latn_CM
+ case 0xDCF9434E4E736875LLU: // zhx_Nshu_CN
+ case 0x811950474C61746ELLU: // zia_Latn_PG
+ case 0xA91950474C61746ELLU: // zik_Latn_PG
+ case 0xAD19474E4C61746ELLU: // zil_Latn_GN
+ case 0xB11954444C61746ELLU: // zim_Latn_TD
+ case 0xB519545A4C61746ELLU: // zin_Latn_TZ
+ case 0xD919545A4C61746ELLU: // ziw_Latn_TZ
+ case 0xE5194E474C61746ELLU: // ziz_Latn_NG
+ case 0x815949444C61746ELLU: // zka_Latn_ID
+ case 0x8D594D4D4C61746ELLU: // zkd_Latn_MM
+ case 0xB95952554379726CLLU: // zko_Cyrl_RU
+ case 0xBD5942524C61746ELLU: // zkp_Latn_BR
+ case 0xCD59434E4B697473LLU: // zkt_Kits_CN
+ case 0xD15941554C61746ELLU: // zku_Latn_AU
+ case 0xE55952554379726CLLU: // zkz_Cyrl_RU
+ case 0x817943444C61746ELLU: // zla_Latn_CD
+ case 0xA579434E48616E69LLU: // zlj_Hani_CN
+ case 0xB17954474C61746ELLU: // zlm_Latn_TG
+ case 0xB579434E48616E69LLU: // zln_Hani_CN
+ case 0xC179434E48616E69LLU: // zlq_Hani_CN
+ case 0xD1794E474C61746ELLU: // zlu_Latn_NG
+ case 0x819941554C61746ELLU: // zma_Latn_AU
+ case 0x859943444C61746ELLU: // zmb_Latn_CD
+ case 0x899941554C61746ELLU: // zmc_Latn_AU
+ case 0x8D9941554C61746ELLU: // zmd_Latn_AU
+ case 0x919941554C61746ELLU: // zme_Latn_AU
+ case 0x959943444C61746ELLU: // zmf_Latn_CD
+ case 0x999941554C61746ELLU: // zmg_Latn_AU
+ case 0x9D9950474C61746ELLU: // zmh_Latn_PG
+ case 0xA1994D594C61746ELLU: // zmi_Latn_MY
+ case 0xA59941554C61746ELLU: // zmj_Latn_AU
+ case 0xA99941554C61746ELLU: // zmk_Latn_AU
+ case 0xAD9941554C61746ELLU: // zml_Latn_AU
+ case 0xB19941554C61746ELLU: // zmm_Latn_AU
+ case 0xB59947414C61746ELLU: // zmn_Latn_GA
+ case 0xB99953444C61746ELLU: // zmo_Latn_SD
+ case 0xBD9943444C61746ELLU: // zmp_Latn_CD
+ case 0xC19943444C61746ELLU: // zmq_Latn_CD
+ case 0xC59941554C61746ELLU: // zmr_Latn_AU
+ case 0xC99943444C61746ELLU: // zms_Latn_CD
+ case 0xCD9941554C61746ELLU: // zmt_Latn_AU
+ case 0xD19941554C61746ELLU: // zmu_Latn_AU
+ case 0xD59941554C61746ELLU: // zmv_Latn_AU
+ case 0xD99943444C61746ELLU: // zmw_Latn_CD
+ case 0xDD9943474C61746ELLU: // zmx_Latn_CG
+ case 0xE19941554C61746ELLU: // zmy_Latn_AU
+ case 0xE59943444C61746ELLU: // zmz_Latn_CD
+ case 0x81B954444C61746ELLU: // zna_Latn_TD
+ case 0x91B943444C61746ELLU: // zne_Latn_CD
+ case 0x99B9564E4C61746ELLU: // zng_Latn_VN
+ case 0xA9B941554C61746ELLU: // znk_Latn_AU
+ case 0xC9B94E474C61746ELLU: // zns_Latn_NG
+ case 0x89D94D584C61746ELLU: // zoc_Latn_MX
+ case 0x9DD94D584C61746ELLU: // zoh_Latn_MX
+ case 0xB1D9494E4C61746ELLU: // zom_Latn_IN
+ case 0xB9D94D584C61746ELLU: // zoo_Latn_MX
+ case 0xC1D94D584C61746ELLU: // zoq_Latn_MX
+ case 0xC5D94D584C61746ELLU: // zor_Latn_MX
+ case 0xC9D94D584C61746ELLU: // zos_Latn_MX
+ case 0x81F94D584C61746ELLU: // zpa_Latn_MX
+ case 0x85F94D584C61746ELLU: // zpb_Latn_MX
+ case 0x89F94D584C61746ELLU: // zpc_Latn_MX
+ case 0x8DF94D584C61746ELLU: // zpd_Latn_MX
+ case 0x91F94D584C61746ELLU: // zpe_Latn_MX
+ case 0x95F94D584C61746ELLU: // zpf_Latn_MX
+ case 0x99F94D584C61746ELLU: // zpg_Latn_MX
+ case 0x9DF94D584C61746ELLU: // zph_Latn_MX
+ case 0xA1F94D584C61746ELLU: // zpi_Latn_MX
+ case 0xA5F94D584C61746ELLU: // zpj_Latn_MX
+ case 0xA9F94D584C61746ELLU: // zpk_Latn_MX
+ case 0xADF94D584C61746ELLU: // zpl_Latn_MX
+ case 0xB1F94D584C61746ELLU: // zpm_Latn_MX
+ case 0xB5F94D584C61746ELLU: // zpn_Latn_MX
+ case 0xB9F94D584C61746ELLU: // zpo_Latn_MX
+ case 0xBDF94D584C61746ELLU: // zpp_Latn_MX
+ case 0xC1F94D584C61746ELLU: // zpq_Latn_MX
+ case 0xC5F94D584C61746ELLU: // zpr_Latn_MX
+ case 0xC9F94D584C61746ELLU: // zps_Latn_MX
+ case 0xCDF94D584C61746ELLU: // zpt_Latn_MX
+ case 0xD1F94D584C61746ELLU: // zpu_Latn_MX
+ case 0xD5F94D584C61746ELLU: // zpv_Latn_MX
+ case 0xD9F94D584C61746ELLU: // zpw_Latn_MX
+ case 0xDDF94D584C61746ELLU: // zpx_Latn_MX
+ case 0xE1F94D584C61746ELLU: // zpy_Latn_MX
+ case 0xE5F94D584C61746ELLU: // zpz_Latn_MX
+ case 0x9219434E48616E69LLU: // zqe_Hani_CN
+ case 0x9A39494E4F727961LLU: // zrg_Orya_IN
+ case 0xB63954444C61746ELLU: // zrn_Latn_TD
+ case 0xBA3945434C61746ELLU: // zro_Latn_EC
+ case 0xBE39465248656272LLU: // zrp_Hebr_FR
+ case 0xCA3949444C61746ELLU: // zrs_Latn_ID
+ case 0x825950474C61746ELLU: // zsa_Latn_PG
+ case 0xC6594D584C61746ELLU: // zsr_Latn_MX
+ case 0xD25950474C61746ELLU: // zsu_Latn_PG
+ case 0x92794D584C61746ELLU: // zte_Latn_MX
+ case 0x9A794D584C61746ELLU: // ztg_Latn_MX
+ case 0xAE794D584C61746ELLU: // ztl_Latn_MX
+ case 0xB2794D584C61746ELLU: // ztm_Latn_MX
+ case 0xB6794D584C61746ELLU: // ztn_Latn_MX
+ case 0xBE794D584C61746ELLU: // ztp_Latn_MX
+ case 0xC2794D584C61746ELLU: // ztq_Latn_MX
+ case 0xCA794D584C61746ELLU: // zts_Latn_MX
+ case 0xCE794D584C61746ELLU: // ztt_Latn_MX
+ case 0xD2794D584C61746ELLU: // ztu_Latn_MX
+ case 0xDE794D584C61746ELLU: // ztx_Latn_MX
+ case 0xE2794D584C61746ELLU: // zty_Latn_MX
+ case 0x7A755A414C61746ELLU: // zu_Latn_ZA
+ case 0x9E9950474C61746ELLU: // zuh_Latn_PG
+ case 0xB2994F4D41726162LLU: // zum_Arab_OM
+ case 0xB69955534C61746ELLU: // zun_Latn_US
+ case 0xE299434D4C61746ELLU: // zuy_Latn_CM
+ case 0x82D9455445746869LLU: // zwa_Ethi_ET
+ case 0x9B19434E48616E69LLU: // zyg_Hani_CN
+ case 0xA719434E4C61746ELLU: // zyj_Latn_CN
+ case 0xB719434E48616E69LLU: // zyn_Hani_CN
+ case 0xBF194D4D4C61746ELLU: // zyp_Latn_MM
+ case 0x833954524C61746ELLU: // zza_Latn_TR
+ case 0xA739434E48616E69LLU: // zzj_Hani_CN
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint32_t findArabParent(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x61724145u: // ar-AE -> ar-015
+ case 0x6172445Au: // ar-DZ -> ar-015
+ case 0x61724548u: // ar-EH -> ar-015
+ case 0x61724C59u: // ar-LY -> ar-015
+ case 0x61724D41u: // ar-MA -> ar-015
+ case 0x6172544Eu: // ar-TN -> ar-015
+ return 0x61729420u;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t findDevaParent(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x68690000u: // hi-Latn -> en-IN
+ return 0x656E494Eu;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t findHantParent(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x7A684D4Fu: // zh-Hant-MO -> zh-Hant-HK
+ return 0x7A68484Bu;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t findLatnParent(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x656E80A1u: // en-150 -> en-001
+ case 0x656E4147u: // en-AG -> en-001
+ case 0x656E4149u: // en-AI -> en-001
+ case 0x656E4155u: // en-AU -> en-001
+ case 0x656E4242u: // en-BB -> en-001
+ case 0x656E424Du: // en-BM -> en-001
+ case 0x656E4253u: // en-BS -> en-001
+ case 0x656E4257u: // en-BW -> en-001
+ case 0x656E425Au: // en-BZ -> en-001
+ case 0x656E4343u: // en-CC -> en-001
+ case 0x656E434Bu: // en-CK -> en-001
+ case 0x656E434Du: // en-CM -> en-001
+ case 0x656E4358u: // en-CX -> en-001
+ case 0x656E4359u: // en-CY -> en-001
+ case 0x656E4447u: // en-DG -> en-001
+ case 0x656E444Du: // en-DM -> en-001
+ case 0x656E4552u: // en-ER -> en-001
+ case 0x656E464Au: // en-FJ -> en-001
+ case 0x656E464Bu: // en-FK -> en-001
+ case 0x656E464Du: // en-FM -> en-001
+ case 0x656E4742u: // en-GB -> en-001
+ case 0x656E4744u: // en-GD -> en-001
+ case 0x656E4747u: // en-GG -> en-001
+ case 0x656E4748u: // en-GH -> en-001
+ case 0x656E4749u: // en-GI -> en-001
+ case 0x656E474Du: // en-GM -> en-001
+ case 0x656E4759u: // en-GY -> en-001
+ case 0x656E484Bu: // en-HK -> en-001
+ case 0x656E4944u: // en-ID -> en-001
+ case 0x656E4945u: // en-IE -> en-001
+ case 0x656E494Cu: // en-IL -> en-001
+ case 0x656E494Du: // en-IM -> en-001
+ case 0x656E494Eu: // en-IN -> en-001
+ case 0x656E494Fu: // en-IO -> en-001
+ case 0x656E4A45u: // en-JE -> en-001
+ case 0x656E4A4Du: // en-JM -> en-001
+ case 0x656E4B45u: // en-KE -> en-001
+ case 0x656E4B49u: // en-KI -> en-001
+ case 0x656E4B4Eu: // en-KN -> en-001
+ case 0x656E4B59u: // en-KY -> en-001
+ case 0x656E4C43u: // en-LC -> en-001
+ case 0x656E4C52u: // en-LR -> en-001
+ case 0x656E4C53u: // en-LS -> en-001
+ case 0x656E4D47u: // en-MG -> en-001
+ case 0x656E4D4Fu: // en-MO -> en-001
+ case 0x656E4D53u: // en-MS -> en-001
+ case 0x656E4D54u: // en-MT -> en-001
+ case 0x656E4D55u: // en-MU -> en-001
+ case 0x656E4D56u: // en-MV -> en-001
+ case 0x656E4D57u: // en-MW -> en-001
+ case 0x656E4D59u: // en-MY -> en-001
+ case 0x656E4E41u: // en-NA -> en-001
+ case 0x656E4E46u: // en-NF -> en-001
+ case 0x656E4E47u: // en-NG -> en-001
+ case 0x656E4E52u: // en-NR -> en-001
+ case 0x656E4E55u: // en-NU -> en-001
+ case 0x656E4E5Au: // en-NZ -> en-001
+ case 0x656E5047u: // en-PG -> en-001
+ case 0x656E504Bu: // en-PK -> en-001
+ case 0x656E504Eu: // en-PN -> en-001
+ case 0x656E5057u: // en-PW -> en-001
+ case 0x656E5257u: // en-RW -> en-001
+ case 0x656E5342u: // en-SB -> en-001
+ case 0x656E5343u: // en-SC -> en-001
+ case 0x656E5344u: // en-SD -> en-001
+ case 0x656E5347u: // en-SG -> en-001
+ case 0x656E5348u: // en-SH -> en-001
+ case 0x656E534Cu: // en-SL -> en-001
+ case 0x656E5353u: // en-SS -> en-001
+ case 0x656E5358u: // en-SX -> en-001
+ case 0x656E535Au: // en-SZ -> en-001
+ case 0x656E5443u: // en-TC -> en-001
+ case 0x656E544Bu: // en-TK -> en-001
+ case 0x656E544Fu: // en-TO -> en-001
+ case 0x656E5454u: // en-TT -> en-001
+ case 0x656E5456u: // en-TV -> en-001
+ case 0x656E545Au: // en-TZ -> en-001
+ case 0x656E5547u: // en-UG -> en-001
+ case 0x656E5643u: // en-VC -> en-001
+ case 0x656E5647u: // en-VG -> en-001
+ case 0x656E5655u: // en-VU -> en-001
+ case 0x656E5753u: // en-WS -> en-001
+ case 0x656E5A41u: // en-ZA -> en-001
+ case 0x656E5A4Du: // en-ZM -> en-001
+ case 0x656E5A57u: // en-ZW -> en-001
+ return 0x656E8400u;
+ case 0x656E4154u: // en-AT -> en-150
+ case 0x656E4245u: // en-BE -> en-150
+ case 0x656E4348u: // en-CH -> en-150
+ case 0x656E435Au: // en-CZ -> en-150
+ case 0x656E4445u: // en-DE -> en-150
+ case 0x656E444Bu: // en-DK -> en-150
+ case 0x656E4553u: // en-ES -> en-150
+ case 0x656E4649u: // en-FI -> en-150
+ case 0x656E4652u: // en-FR -> en-150
+ case 0x656E4855u: // en-HU -> en-150
+ case 0x656E4954u: // en-IT -> en-150
+ case 0x656E4E4Cu: // en-NL -> en-150
+ case 0x656E4E4Fu: // en-NO -> en-150
+ case 0x656E504Cu: // en-PL -> en-150
+ case 0x656E5054u: // en-PT -> en-150
+ case 0x656E524Fu: // en-RO -> en-150
+ case 0x656E5345u: // en-SE -> en-150
+ case 0x656E5349u: // en-SI -> en-150
+ case 0x656E534Bu: // en-SK -> en-150
+ return 0x656E80A1u;
+ case 0x65734152u: // es-AR -> es-419
+ case 0x6573424Fu: // es-BO -> es-419
+ case 0x65734252u: // es-BR -> es-419
+ case 0x6573425Au: // es-BZ -> es-419
+ case 0x6573434Cu: // es-CL -> es-419
+ case 0x6573434Fu: // es-CO -> es-419
+ case 0x65734352u: // es-CR -> es-419
+ case 0x65734355u: // es-CU -> es-419
+ case 0x6573444Fu: // es-DO -> es-419
+ case 0x65734543u: // es-EC -> es-419
+ case 0x65734754u: // es-GT -> es-419
+ case 0x6573484Eu: // es-HN -> es-419
+ case 0x65734D58u: // es-MX -> es-419
+ case 0x65734E49u: // es-NI -> es-419
+ case 0x65735041u: // es-PA -> es-419
+ case 0x65735045u: // es-PE -> es-419
+ case 0x65735052u: // es-PR -> es-419
+ case 0x65735059u: // es-PY -> es-419
+ case 0x65735356u: // es-SV -> es-419
+ case 0x65735553u: // es-US -> es-419
+ case 0x65735559u: // es-UY -> es-419
+ case 0x65735645u: // es-VE -> es-419
+ return 0x6573A424u;
+ case 0x6E620000u: // nb -> no
+ case 0x6E6E0000u: // nn -> no
+ return 0x6E6F0000u;
+ case 0x7074414Fu: // pt-AO -> pt-PT
+ case 0x70744348u: // pt-CH -> pt-PT
+ case 0x70744356u: // pt-CV -> pt-PT
+ case 0x70744751u: // pt-GQ -> pt-PT
+ case 0x70744757u: // pt-GW -> pt-PT
+ case 0x70744C55u: // pt-LU -> pt-PT
+ case 0x70744D4Fu: // pt-MO -> pt-PT
+ case 0x70744D5Au: // pt-MZ -> pt-PT
+ case 0x70745354u: // pt-ST -> pt-PT
+ case 0x7074544Cu: // pt-TL -> pt-PT
+ return 0x70745054u;
+ default:
+ return 0;
+ }
+}
+
+static uint32_t find000BParent(uint32_t packed_lang_region) {
+ switch(packed_lang_region) {
+ case 0x61725842u: // ar-XB -> ar-015
+ return 0x61729420u;
+ default:
+ return 0;
+ }
+}
+
+uint32_t findParentLocalePackedKey(const char* script, uint32_t packed_lang_region) {
+ uint32_t packedScript = packScript(script);
+ switch (packedScript) {
+ case 0x41726162u: // Arab
+ return findArabParent(packed_lang_region);
+ case 0x44657661u: // Deva
+ return findDevaParent(packed_lang_region);
+ case 0x48616E74u: // Hant
+ return findHantParent(packed_lang_region);
+ case 0x4C61746Eu: // Latn
+ return findLatnParent(packed_lang_region);
+ case 0x7E7E7E42u: // ~~~B
+ return find000BParent(packed_lang_region);
+ default:
+ return 0;
+ }
+}
+
+uint32_t getMaxAncestorTreeDepth() {
+ return 3;
+}
+
+} // namespace android
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
deleted file mode 100644
index 94351182871a..000000000000
--- a/libs/androidfw/LocaleDataTables.cpp
+++ /dev/null
@@ -1,2461 +0,0 @@
-// Auto-generated by ./tools/localedata/extract_icu_data.py
-
-const char SCRIPT_CODES[][4] = {
- /* 0 */ {'A', 'g', 'h', 'b'},
- /* 1 */ {'A', 'h', 'o', 'm'},
- /* 2 */ {'A', 'r', 'a', 'b'},
- /* 3 */ {'A', 'r', 'm', 'i'},
- /* 4 */ {'A', 'r', 'm', 'n'},
- /* 5 */ {'A', 'v', 's', 't'},
- /* 6 */ {'B', 'a', 'm', 'u'},
- /* 7 */ {'B', 'a', 's', 's'},
- /* 8 */ {'B', 'e', 'n', 'g'},
- /* 9 */ {'B', 'r', 'a', 'h'},
- /* 10 */ {'C', 'a', 'k', 'm'},
- /* 11 */ {'C', 'a', 'n', 's'},
- /* 12 */ {'C', 'a', 'r', 'i'},
- /* 13 */ {'C', 'h', 'a', 'm'},
- /* 14 */ {'C', 'h', 'e', 'r'},
- /* 15 */ {'C', 'h', 'r', 's'},
- /* 16 */ {'C', 'o', 'p', 't'},
- /* 17 */ {'C', 'p', 'r', 't'},
- /* 18 */ {'C', 'y', 'r', 'l'},
- /* 19 */ {'D', 'e', 'v', 'a'},
- /* 20 */ {'E', 'g', 'y', 'p'},
- /* 21 */ {'E', 't', 'h', 'i'},
- /* 22 */ {'G', 'e', 'o', 'r'},
- /* 23 */ {'G', 'o', 'n', 'g'},
- /* 24 */ {'G', 'o', 'n', 'm'},
- /* 25 */ {'G', 'o', 't', 'h'},
- /* 26 */ {'G', 'r', 'e', 'k'},
- /* 27 */ {'G', 'u', 'j', 'r'},
- /* 28 */ {'G', 'u', 'r', 'u'},
- /* 29 */ {'H', 'a', 'n', 's'},
- /* 30 */ {'H', 'a', 'n', 't'},
- /* 31 */ {'H', 'e', 'b', 'r'},
- /* 32 */ {'H', 'l', 'u', 'w'},
- /* 33 */ {'H', 'm', 'n', 'p'},
- /* 34 */ {'I', 't', 'a', 'l'},
- /* 35 */ {'J', 'p', 'a', 'n'},
- /* 36 */ {'K', 'a', 'l', 'i'},
- /* 37 */ {'K', 'a', 'n', 'a'},
- /* 38 */ {'K', 'a', 'w', 'i'},
- /* 39 */ {'K', 'h', 'a', 'r'},
- /* 40 */ {'K', 'h', 'm', 'r'},
- /* 41 */ {'K', 'i', 't', 's'},
- /* 42 */ {'K', 'n', 'd', 'a'},
- /* 43 */ {'K', 'o', 'r', 'e'},
- /* 44 */ {'L', 'a', 'n', 'a'},
- /* 45 */ {'L', 'a', 'o', 'o'},
- /* 46 */ {'L', 'a', 't', 'n'},
- /* 47 */ {'L', 'e', 'p', 'c'},
- /* 48 */ {'L', 'i', 'n', 'a'},
- /* 49 */ {'L', 'i', 's', 'u'},
- /* 50 */ {'L', 'y', 'c', 'i'},
- /* 51 */ {'L', 'y', 'd', 'i'},
- /* 52 */ {'M', 'a', 'n', 'd'},
- /* 53 */ {'M', 'a', 'n', 'i'},
- /* 54 */ {'M', 'e', 'd', 'f'},
- /* 55 */ {'M', 'e', 'r', 'c'},
- /* 56 */ {'M', 'l', 'y', 'm'},
- /* 57 */ {'M', 'o', 'n', 'g'},
- /* 58 */ {'M', 'r', 'o', 'o'},
- /* 59 */ {'M', 'y', 'm', 'r'},
- /* 60 */ {'N', 'a', 'r', 'b'},
- /* 61 */ {'N', 'k', 'o', 'o'},
- /* 62 */ {'N', 's', 'h', 'u'},
- /* 63 */ {'O', 'g', 'a', 'm'},
- /* 64 */ {'O', 'l', 'c', 'k'},
- /* 65 */ {'O', 'r', 'k', 'h'},
- /* 66 */ {'O', 'r', 'y', 'a'},
- /* 67 */ {'O', 's', 'g', 'e'},
- /* 68 */ {'O', 'u', 'g', 'r'},
- /* 69 */ {'P', 'a', 'u', 'c'},
- /* 70 */ {'P', 'h', 'l', 'i'},
- /* 71 */ {'P', 'h', 'n', 'x'},
- /* 72 */ {'P', 'l', 'r', 'd'},
- /* 73 */ {'P', 'r', 't', 'i'},
- /* 74 */ {'R', 'o', 'h', 'g'},
- /* 75 */ {'R', 'u', 'n', 'r'},
- /* 76 */ {'S', 'a', 'm', 'r'},
- /* 77 */ {'S', 'a', 'r', 'b'},
- /* 78 */ {'S', 'a', 'u', 'r'},
- /* 79 */ {'S', 'g', 'n', 'w'},
- /* 80 */ {'S', 'i', 'n', 'h'},
- /* 81 */ {'S', 'o', 'g', 'd'},
- /* 82 */ {'S', 'o', 'r', 'a'},
- /* 83 */ {'S', 'o', 'y', 'o'},
- /* 84 */ {'S', 'y', 'r', 'c'},
- /* 85 */ {'T', 'a', 'l', 'e'},
- /* 86 */ {'T', 'a', 'l', 'u'},
- /* 87 */ {'T', 'a', 'm', 'l'},
- /* 88 */ {'T', 'a', 'n', 'g'},
- /* 89 */ {'T', 'a', 'v', 't'},
- /* 90 */ {'T', 'e', 'l', 'u'},
- /* 91 */ {'T', 'f', 'n', 'g'},
- /* 92 */ {'T', 'h', 'a', 'a'},
- /* 93 */ {'T', 'h', 'a', 'i'},
- /* 94 */ {'T', 'i', 'b', 't'},
- /* 95 */ {'T', 'n', 's', 'a'},
- /* 96 */ {'T', 'o', 't', 'o'},
- /* 97 */ {'U', 'g', 'a', 'r'},
- /* 98 */ {'V', 'a', 'i', 'i'},
- /* 99 */ {'W', 'c', 'h', 'o'},
- /* 100 */ {'X', 'p', 'e', 'o'},
- /* 101 */ {'X', 's', 'u', 'x'},
- /* 102 */ {'Y', 'i', 'i', 'i'},
- /* 103 */ {'~', '~', '~', 'A'},
- /* 104 */ {'~', '~', '~', 'B'},
-};
-
-
-const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({
- {0x61610000u, 46u}, // aa -> Latn
- {0xA0000000u, 46u}, // aai -> Latn
- {0xA8000000u, 46u}, // aak -> Latn
- {0xD0000000u, 46u}, // aau -> Latn
- {0x61620000u, 18u}, // ab -> Cyrl
- {0xA0200000u, 46u}, // abi -> Latn
- {0xC0200000u, 18u}, // abq -> Cyrl
- {0xC4200000u, 46u}, // abr -> Latn
- {0xCC200000u, 46u}, // abt -> Latn
- {0xE0200000u, 46u}, // aby -> Latn
- {0x8C400000u, 46u}, // acd -> Latn
- {0x90400000u, 46u}, // ace -> Latn
- {0x9C400000u, 46u}, // ach -> Latn
- {0x80600000u, 46u}, // ada -> Latn
- {0x90600000u, 46u}, // ade -> Latn
- {0xA4600000u, 46u}, // adj -> Latn
- {0xBC600000u, 94u}, // adp -> Tibt
- {0xE0600000u, 18u}, // ady -> Cyrl
- {0xE4600000u, 46u}, // adz -> Latn
- {0x61650000u, 5u}, // ae -> Avst
- {0x84800000u, 2u}, // aeb -> Arab
- {0xE0800000u, 46u}, // aey -> Latn
- {0x61660000u, 46u}, // af -> Latn
- {0x88C00000u, 46u}, // agc -> Latn
- {0x8CC00000u, 46u}, // agd -> Latn
- {0x98C00000u, 46u}, // agg -> Latn
- {0xB0C00000u, 46u}, // agm -> Latn
- {0xB8C00000u, 46u}, // ago -> Latn
- {0xC0C00000u, 46u}, // agq -> Latn
- {0x80E00000u, 46u}, // aha -> Latn
- {0xACE00000u, 46u}, // ahl -> Latn
- {0xB8E00000u, 1u}, // aho -> Ahom
- {0x99200000u, 46u}, // ajg -> Latn
- {0xCD200000u, 2u}, // ajt -> Arab
- {0x616B0000u, 46u}, // ak -> Latn
- {0xA9400000u, 101u}, // akk -> Xsux
- {0x81600000u, 46u}, // ala -> Latn
- {0xA1600000u, 46u}, // ali -> Latn
- {0xB5600000u, 46u}, // aln -> Latn
- {0xCD600000u, 18u}, // alt -> Cyrl
- {0x616D0000u, 21u}, // am -> Ethi
- {0xB1800000u, 46u}, // amm -> Latn
- {0xB5800000u, 46u}, // amn -> Latn
- {0xB9800000u, 46u}, // amo -> Latn
- {0xBD800000u, 46u}, // amp -> Latn
- {0x616E0000u, 46u}, // an -> Latn
- {0x89A00000u, 46u}, // anc -> Latn
- {0xA9A00000u, 46u}, // ank -> Latn
- {0xB5A00000u, 46u}, // ann -> Latn
- {0xE1A00000u, 46u}, // any -> Latn
- {0xA5C00000u, 46u}, // aoj -> Latn
- {0xB1C00000u, 46u}, // aom -> Latn
- {0xE5C00000u, 46u}, // aoz -> Latn
- {0x89E00000u, 2u}, // apc -> Arab
- {0x8DE00000u, 2u}, // apd -> Arab
- {0x91E00000u, 46u}, // ape -> Latn
- {0xC5E00000u, 46u}, // apr -> Latn
- {0xC9E00000u, 46u}, // aps -> Latn
- {0xE5E00000u, 46u}, // apz -> Latn
- {0x61720000u, 2u}, // ar -> Arab
- {0x61725842u, 104u}, // ar-XB -> ~~~B
- {0x8A200000u, 3u}, // arc -> Armi
- {0x9E200000u, 46u}, // arh -> Latn
- {0xB6200000u, 46u}, // arn -> Latn
- {0xBA200000u, 46u}, // aro -> Latn
- {0xC2200000u, 2u}, // arq -> Arab
- {0xCA200000u, 2u}, // ars -> Arab
- {0xE2200000u, 2u}, // ary -> Arab
- {0xE6200000u, 2u}, // arz -> Arab
- {0x61730000u, 8u}, // as -> Beng
- {0x82400000u, 46u}, // asa -> Latn
- {0x92400000u, 79u}, // ase -> Sgnw
- {0x9A400000u, 46u}, // asg -> Latn
- {0xBA400000u, 46u}, // aso -> Latn
- {0xCE400000u, 46u}, // ast -> Latn
- {0x82600000u, 46u}, // ata -> Latn
- {0x9A600000u, 46u}, // atg -> Latn
- {0xA6600000u, 46u}, // atj -> Latn
- {0xE2800000u, 46u}, // auy -> Latn
- {0x61760000u, 18u}, // av -> Cyrl
- {0xAEA00000u, 2u}, // avl -> Arab
- {0xB6A00000u, 46u}, // avn -> Latn
- {0xCEA00000u, 46u}, // avt -> Latn
- {0xD2A00000u, 46u}, // avu -> Latn
- {0x82C00000u, 19u}, // awa -> Deva
- {0x86C00000u, 46u}, // awb -> Latn
- {0xBAC00000u, 46u}, // awo -> Latn
- {0xDEC00000u, 46u}, // awx -> Latn
- {0x61790000u, 46u}, // ay -> Latn
- {0x87000000u, 46u}, // ayb -> Latn
- {0x617A0000u, 46u}, // az -> Latn
- {0x617A4951u, 2u}, // az-IQ -> Arab
- {0x617A4952u, 2u}, // az-IR -> Arab
- {0x617A5255u, 18u}, // az-RU -> Cyrl
- {0x62610000u, 18u}, // ba -> Cyrl
- {0xAC010000u, 2u}, // bal -> Arab
- {0xB4010000u, 46u}, // ban -> Latn
- {0xBC010000u, 19u}, // bap -> Deva
- {0xC4010000u, 46u}, // bar -> Latn
- {0xC8010000u, 46u}, // bas -> Latn
- {0xD4010000u, 46u}, // bav -> Latn
- {0xDC010000u, 6u}, // bax -> Bamu
- {0x80210000u, 46u}, // bba -> Latn
- {0x84210000u, 46u}, // bbb -> Latn
- {0x88210000u, 46u}, // bbc -> Latn
- {0x8C210000u, 46u}, // bbd -> Latn
- {0xA4210000u, 46u}, // bbj -> Latn
- {0xBC210000u, 46u}, // bbp -> Latn
- {0xC4210000u, 46u}, // bbr -> Latn
- {0x94410000u, 46u}, // bcf -> Latn
- {0x9C410000u, 46u}, // bch -> Latn
- {0xA0410000u, 46u}, // bci -> Latn
- {0xB0410000u, 46u}, // bcm -> Latn
- {0xB4410000u, 46u}, // bcn -> Latn
- {0xB8410000u, 46u}, // bco -> Latn
- {0xC0410000u, 21u}, // bcq -> Ethi
- {0xD0410000u, 46u}, // bcu -> Latn
- {0x8C610000u, 46u}, // bdd -> Latn
- {0x62650000u, 18u}, // be -> Cyrl
- {0x94810000u, 46u}, // bef -> Latn
- {0x9C810000u, 46u}, // beh -> Latn
- {0xA4810000u, 2u}, // bej -> Arab
- {0xB0810000u, 46u}, // bem -> Latn
- {0xCC810000u, 46u}, // bet -> Latn
- {0xD8810000u, 46u}, // bew -> Latn
- {0xDC810000u, 46u}, // bex -> Latn
- {0xE4810000u, 46u}, // bez -> Latn
- {0x8CA10000u, 46u}, // bfd -> Latn
- {0xC0A10000u, 87u}, // bfq -> Taml
- {0xCCA10000u, 2u}, // bft -> Arab
- {0xE0A10000u, 19u}, // bfy -> Deva
- {0x62670000u, 18u}, // bg -> Cyrl
- {0x88C10000u, 19u}, // bgc -> Deva
- {0xB4C10000u, 2u}, // bgn -> Arab
- {0xDCC10000u, 26u}, // bgx -> Grek
- {0x84E10000u, 19u}, // bhb -> Deva
- {0x98E10000u, 46u}, // bhg -> Latn
- {0xA0E10000u, 19u}, // bhi -> Deva
- {0xACE10000u, 46u}, // bhl -> Latn
- {0xB8E10000u, 19u}, // bho -> Deva
- {0xE0E10000u, 46u}, // bhy -> Latn
- {0x62690000u, 46u}, // bi -> Latn
- {0x85010000u, 46u}, // bib -> Latn
- {0x99010000u, 46u}, // big -> Latn
- {0xA9010000u, 46u}, // bik -> Latn
- {0xB1010000u, 46u}, // bim -> Latn
- {0xB5010000u, 46u}, // bin -> Latn
- {0xB9010000u, 46u}, // bio -> Latn
- {0xC1010000u, 46u}, // biq -> Latn
- {0x9D210000u, 46u}, // bjh -> Latn
- {0xA1210000u, 21u}, // bji -> Ethi
- {0xA5210000u, 19u}, // bjj -> Deva
- {0xB5210000u, 46u}, // bjn -> Latn
- {0xB9210000u, 46u}, // bjo -> Latn
- {0xC5210000u, 46u}, // bjr -> Latn
- {0xCD210000u, 46u}, // bjt -> Latn
- {0xE5210000u, 46u}, // bjz -> Latn
- {0x89410000u, 46u}, // bkc -> Latn
- {0xB1410000u, 46u}, // bkm -> Latn
- {0xC1410000u, 46u}, // bkq -> Latn
- {0xD1410000u, 46u}, // bku -> Latn
- {0xD5410000u, 46u}, // bkv -> Latn
- {0x81610000u, 46u}, // bla -> Latn
- {0x99610000u, 46u}, // blg -> Latn
- {0xCD610000u, 89u}, // blt -> Tavt
- {0x626D0000u, 46u}, // bm -> Latn
- {0x9D810000u, 46u}, // bmh -> Latn
- {0xA9810000u, 46u}, // bmk -> Latn
- {0xC1810000u, 46u}, // bmq -> Latn
- {0xD1810000u, 46u}, // bmu -> Latn
- {0x626E0000u, 8u}, // bn -> Beng
- {0x99A10000u, 46u}, // bng -> Latn
- {0xB1A10000u, 46u}, // bnm -> Latn
- {0xBDA10000u, 46u}, // bnp -> Latn
- {0x626F0000u, 94u}, // bo -> Tibt
- {0xA5C10000u, 46u}, // boj -> Latn
- {0xB1C10000u, 46u}, // bom -> Latn
- {0xB5C10000u, 46u}, // bon -> Latn
- {0xE1E10000u, 8u}, // bpy -> Beng
- {0x8A010000u, 46u}, // bqc -> Latn
- {0xA2010000u, 2u}, // bqi -> Arab
- {0xBE010000u, 46u}, // bqp -> Latn
- {0xD6010000u, 46u}, // bqv -> Latn
- {0x62720000u, 46u}, // br -> Latn
- {0x82210000u, 19u}, // bra -> Deva
- {0x9E210000u, 2u}, // brh -> Arab
- {0xDE210000u, 19u}, // brx -> Deva
- {0xE6210000u, 46u}, // brz -> Latn
- {0x62730000u, 46u}, // bs -> Latn
- {0xA6410000u, 46u}, // bsj -> Latn
- {0xC2410000u, 7u}, // bsq -> Bass
- {0xCA410000u, 46u}, // bss -> Latn
- {0xCE410000u, 21u}, // bst -> Ethi
- {0xBA610000u, 46u}, // bto -> Latn
- {0xCE610000u, 46u}, // btt -> Latn
- {0xD6610000u, 19u}, // btv -> Deva
- {0x82810000u, 18u}, // bua -> Cyrl
- {0x8A810000u, 46u}, // buc -> Latn
- {0x8E810000u, 46u}, // bud -> Latn
- {0x9A810000u, 46u}, // bug -> Latn
- {0xAA810000u, 46u}, // buk -> Latn
- {0xB2810000u, 46u}, // bum -> Latn
- {0xBA810000u, 46u}, // buo -> Latn
- {0xCA810000u, 46u}, // bus -> Latn
- {0xD2810000u, 46u}, // buu -> Latn
- {0x86A10000u, 46u}, // bvb -> Latn
- {0x8EC10000u, 46u}, // bwd -> Latn
- {0xC6C10000u, 46u}, // bwr -> Latn
- {0x9EE10000u, 46u}, // bxh -> Latn
- {0x93010000u, 46u}, // bye -> Latn
- {0xB7010000u, 21u}, // byn -> Ethi
- {0xC7010000u, 46u}, // byr -> Latn
- {0xCB010000u, 46u}, // bys -> Latn
- {0xD7010000u, 46u}, // byv -> Latn
- {0xDF010000u, 46u}, // byx -> Latn
- {0x83210000u, 46u}, // bza -> Latn
- {0x93210000u, 46u}, // bze -> Latn
- {0x97210000u, 46u}, // bzf -> Latn
- {0x9F210000u, 46u}, // bzh -> Latn
- {0xDB210000u, 46u}, // bzw -> Latn
- {0x63610000u, 46u}, // ca -> Latn
- {0x8C020000u, 46u}, // cad -> Latn
- {0xB4020000u, 46u}, // can -> Latn
- {0xA4220000u, 46u}, // cbj -> Latn
- {0x9C420000u, 46u}, // cch -> Latn
- {0xBC420000u, 10u}, // ccp -> Cakm
- {0x63650000u, 18u}, // ce -> Cyrl
- {0x84820000u, 46u}, // ceb -> Latn
- {0x80A20000u, 46u}, // cfa -> Latn
- {0x98C20000u, 46u}, // cgg -> Latn
- {0x63680000u, 46u}, // ch -> Latn
- {0xA8E20000u, 46u}, // chk -> Latn
- {0xB0E20000u, 18u}, // chm -> Cyrl
- {0xB8E20000u, 46u}, // cho -> Latn
- {0xBCE20000u, 46u}, // chp -> Latn
- {0xC4E20000u, 14u}, // chr -> Cher
- {0x89020000u, 46u}, // cic -> Latn
- {0x81220000u, 2u}, // cja -> Arab
- {0xB1220000u, 13u}, // cjm -> Cham
- {0xD5220000u, 46u}, // cjv -> Latn
- {0x85420000u, 2u}, // ckb -> Arab
- {0xAD420000u, 46u}, // ckl -> Latn
- {0xB9420000u, 46u}, // cko -> Latn
- {0xE1420000u, 46u}, // cky -> Latn
- {0x81620000u, 46u}, // cla -> Latn
- {0x89620000u, 46u}, // clc -> Latn
- {0x91820000u, 46u}, // cme -> Latn
- {0x99820000u, 83u}, // cmg -> Soyo
- {0x636F0000u, 46u}, // co -> Latn
- {0xBDC20000u, 16u}, // cop -> Copt
- {0xC9E20000u, 46u}, // cps -> Latn
- {0x63720000u, 11u}, // cr -> Cans
- {0x9A220000u, 46u}, // crg -> Latn
- {0x9E220000u, 18u}, // crh -> Cyrl
- {0xAA220000u, 11u}, // crk -> Cans
- {0xAE220000u, 11u}, // crl -> Cans
- {0xCA220000u, 46u}, // crs -> Latn
- {0x63730000u, 46u}, // cs -> Latn
- {0x86420000u, 46u}, // csb -> Latn
- {0xDA420000u, 11u}, // csw -> Cans
- {0x8E620000u, 69u}, // ctd -> Pauc
- {0x63750000u, 18u}, // cu -> Cyrl
- {0x63760000u, 18u}, // cv -> Cyrl
- {0x63790000u, 46u}, // cy -> Latn
- {0x64610000u, 46u}, // da -> Latn
- {0x8C030000u, 46u}, // dad -> Latn
- {0x94030000u, 46u}, // daf -> Latn
- {0x98030000u, 46u}, // dag -> Latn
- {0x9C030000u, 46u}, // dah -> Latn
- {0xA8030000u, 46u}, // dak -> Latn
- {0xC4030000u, 18u}, // dar -> Cyrl
- {0xD4030000u, 46u}, // dav -> Latn
- {0x8C230000u, 46u}, // dbd -> Latn
- {0xC0230000u, 46u}, // dbq -> Latn
- {0x88430000u, 2u}, // dcc -> Arab
- {0xB4630000u, 46u}, // ddn -> Latn
- {0x64650000u, 46u}, // de -> Latn
- {0x8C830000u, 46u}, // ded -> Latn
- {0xB4830000u, 46u}, // den -> Latn
- {0x80C30000u, 46u}, // dga -> Latn
- {0x9CC30000u, 46u}, // dgh -> Latn
- {0xA0C30000u, 46u}, // dgi -> Latn
- {0xACC30000u, 2u}, // dgl -> Arab
- {0xC4C30000u, 46u}, // dgr -> Latn
- {0xE4C30000u, 46u}, // dgz -> Latn
- {0x81030000u, 46u}, // dia -> Latn
- {0x91230000u, 46u}, // dje -> Latn
- {0x95830000u, 54u}, // dmf -> Medf
- {0xA5A30000u, 46u}, // dnj -> Latn
- {0x85C30000u, 46u}, // dob -> Latn
- {0xA1C30000u, 19u}, // doi -> Deva
- {0xBDC30000u, 46u}, // dop -> Latn
- {0xD9C30000u, 46u}, // dow -> Latn
- {0x9E230000u, 57u}, // drh -> Mong
- {0xA2230000u, 46u}, // dri -> Latn
- {0xCA230000u, 21u}, // drs -> Ethi
- {0x86430000u, 46u}, // dsb -> Latn
- {0xB2630000u, 46u}, // dtm -> Latn
- {0xBE630000u, 46u}, // dtp -> Latn
- {0xCA630000u, 46u}, // dts -> Latn
- {0xE2630000u, 19u}, // dty -> Deva
- {0x82830000u, 46u}, // dua -> Latn
- {0x8A830000u, 46u}, // duc -> Latn
- {0x8E830000u, 46u}, // dud -> Latn
- {0x9A830000u, 46u}, // dug -> Latn
- {0x64760000u, 92u}, // dv -> Thaa
- {0x82A30000u, 46u}, // dva -> Latn
- {0xDAC30000u, 46u}, // dww -> Latn
- {0xBB030000u, 46u}, // dyo -> Latn
- {0xD3030000u, 46u}, // dyu -> Latn
- {0x647A0000u, 94u}, // dz -> Tibt
- {0x9B230000u, 46u}, // dzg -> Latn
- {0xD0240000u, 46u}, // ebu -> Latn
- {0x65650000u, 46u}, // ee -> Latn
- {0xA0A40000u, 46u}, // efi -> Latn
- {0xACC40000u, 46u}, // egl -> Latn
- {0xE0C40000u, 20u}, // egy -> Egyp
- {0x81440000u, 46u}, // eka -> Latn
- {0xE1440000u, 36u}, // eky -> Kali
- {0x656C0000u, 26u}, // el -> Grek
- {0x81840000u, 46u}, // ema -> Latn
- {0xA1840000u, 46u}, // emi -> Latn
- {0x656E0000u, 46u}, // en -> Latn
- {0x656E5841u, 103u}, // en-XA -> ~~~A
- {0xB5A40000u, 46u}, // enn -> Latn
- {0xC1A40000u, 46u}, // enq -> Latn
- {0x656F0000u, 46u}, // eo -> Latn
- {0xA2240000u, 46u}, // eri -> Latn
- {0x65730000u, 46u}, // es -> Latn
- {0x9A440000u, 24u}, // esg -> Gonm
- {0xD2440000u, 46u}, // esu -> Latn
- {0x65740000u, 46u}, // et -> Latn
- {0xC6640000u, 46u}, // etr -> Latn
- {0xCE640000u, 34u}, // ett -> Ital
- {0xD2640000u, 46u}, // etu -> Latn
- {0xDE640000u, 46u}, // etx -> Latn
- {0x65750000u, 46u}, // eu -> Latn
- {0xBAC40000u, 46u}, // ewo -> Latn
- {0xCEE40000u, 46u}, // ext -> Latn
- {0x83240000u, 46u}, // eza -> Latn
- {0x66610000u, 2u}, // fa -> Arab
- {0x80050000u, 46u}, // faa -> Latn
- {0x84050000u, 46u}, // fab -> Latn
- {0x98050000u, 46u}, // fag -> Latn
- {0xA0050000u, 46u}, // fai -> Latn
- {0xB4050000u, 46u}, // fan -> Latn
- {0x66660000u, 46u}, // ff -> Latn
- {0xA0A50000u, 46u}, // ffi -> Latn
- {0xB0A50000u, 46u}, // ffm -> Latn
- {0x66690000u, 46u}, // fi -> Latn
- {0x81050000u, 2u}, // fia -> Arab
- {0xAD050000u, 46u}, // fil -> Latn
- {0xCD050000u, 46u}, // fit -> Latn
- {0x666A0000u, 46u}, // fj -> Latn
- {0xC5650000u, 46u}, // flr -> Latn
- {0xBD850000u, 46u}, // fmp -> Latn
- {0x666F0000u, 46u}, // fo -> Latn
- {0x8DC50000u, 46u}, // fod -> Latn
- {0xB5C50000u, 46u}, // fon -> Latn
- {0xC5C50000u, 46u}, // for -> Latn
- {0x91E50000u, 46u}, // fpe -> Latn
- {0xCA050000u, 46u}, // fqs -> Latn
- {0x66720000u, 46u}, // fr -> Latn
- {0x8A250000u, 46u}, // frc -> Latn
- {0xBE250000u, 46u}, // frp -> Latn
- {0xC6250000u, 46u}, // frr -> Latn
- {0xCA250000u, 46u}, // frs -> Latn
- {0x86850000u, 2u}, // fub -> Arab
- {0x8E850000u, 46u}, // fud -> Latn
- {0x92850000u, 46u}, // fue -> Latn
- {0x96850000u, 46u}, // fuf -> Latn
- {0x9E850000u, 46u}, // fuh -> Latn
- {0xC2850000u, 46u}, // fuq -> Latn
- {0xC6850000u, 46u}, // fur -> Latn
- {0xD6850000u, 46u}, // fuv -> Latn
- {0xE2850000u, 46u}, // fuy -> Latn
- {0xC6A50000u, 46u}, // fvr -> Latn
- {0x66790000u, 46u}, // fy -> Latn
- {0x67610000u, 46u}, // ga -> Latn
- {0x80060000u, 46u}, // gaa -> Latn
- {0x94060000u, 46u}, // gaf -> Latn
- {0x98060000u, 46u}, // gag -> Latn
- {0x9C060000u, 46u}, // gah -> Latn
- {0xA4060000u, 46u}, // gaj -> Latn
- {0xB0060000u, 46u}, // gam -> Latn
- {0xB4060000u, 29u}, // gan -> Hans
- {0xD8060000u, 46u}, // gaw -> Latn
- {0xE0060000u, 46u}, // gay -> Latn
- {0x80260000u, 46u}, // gba -> Latn
- {0x94260000u, 46u}, // gbf -> Latn
- {0xB0260000u, 19u}, // gbm -> Deva
- {0xE0260000u, 46u}, // gby -> Latn
- {0xE4260000u, 2u}, // gbz -> Arab
- {0xC4460000u, 46u}, // gcr -> Latn
- {0x67640000u, 46u}, // gd -> Latn
- {0x90660000u, 46u}, // gde -> Latn
- {0xB4660000u, 46u}, // gdn -> Latn
- {0xC4660000u, 46u}, // gdr -> Latn
- {0x84860000u, 46u}, // geb -> Latn
- {0xA4860000u, 46u}, // gej -> Latn
- {0xAC860000u, 46u}, // gel -> Latn
- {0xE4860000u, 21u}, // gez -> Ethi
- {0xA8A60000u, 46u}, // gfk -> Latn
- {0xB4C60000u, 19u}, // ggn -> Deva
- {0xC8E60000u, 46u}, // ghs -> Latn
- {0xAD060000u, 46u}, // gil -> Latn
- {0xB1060000u, 46u}, // gim -> Latn
- {0xA9260000u, 2u}, // gjk -> Arab
- {0xB5260000u, 46u}, // gjn -> Latn
- {0xD1260000u, 2u}, // gju -> Arab
- {0xB5460000u, 46u}, // gkn -> Latn
- {0xBD460000u, 46u}, // gkp -> Latn
- {0x676C0000u, 46u}, // gl -> Latn
- {0xA9660000u, 2u}, // glk -> Arab
- {0xB1860000u, 46u}, // gmm -> Latn
- {0xD5860000u, 21u}, // gmv -> Ethi
- {0x676E0000u, 46u}, // gn -> Latn
- {0x8DA60000u, 46u}, // gnd -> Latn
- {0x99A60000u, 46u}, // gng -> Latn
- {0x8DC60000u, 46u}, // god -> Latn
- {0x95C60000u, 21u}, // gof -> Ethi
- {0xA1C60000u, 46u}, // goi -> Latn
- {0xB1C60000u, 19u}, // gom -> Deva
- {0xB5C60000u, 90u}, // gon -> Telu
- {0xC5C60000u, 46u}, // gor -> Latn
- {0xC9C60000u, 46u}, // gos -> Latn
- {0xCDC60000u, 25u}, // got -> Goth
- {0x86260000u, 46u}, // grb -> Latn
- {0x8A260000u, 17u}, // grc -> Cprt
- {0xCE260000u, 8u}, // grt -> Beng
- {0xDA260000u, 46u}, // grw -> Latn
- {0xDA460000u, 46u}, // gsw -> Latn
- {0x67750000u, 27u}, // gu -> Gujr
- {0x86860000u, 46u}, // gub -> Latn
- {0x8A860000u, 46u}, // guc -> Latn
- {0x8E860000u, 46u}, // gud -> Latn
- {0xC6860000u, 46u}, // gur -> Latn
- {0xDA860000u, 46u}, // guw -> Latn
- {0xDE860000u, 46u}, // gux -> Latn
- {0xE6860000u, 46u}, // guz -> Latn
- {0x67760000u, 46u}, // gv -> Latn
- {0x96A60000u, 46u}, // gvf -> Latn
- {0xC6A60000u, 19u}, // gvr -> Deva
- {0xCAA60000u, 46u}, // gvs -> Latn
- {0x8AC60000u, 2u}, // gwc -> Arab
- {0xA2C60000u, 46u}, // gwi -> Latn
- {0xCEC60000u, 2u}, // gwt -> Arab
- {0xA3060000u, 46u}, // gyi -> Latn
- {0x68610000u, 46u}, // ha -> Latn
- {0x6861434Du, 2u}, // ha-CM -> Arab
- {0x68615344u, 2u}, // ha-SD -> Arab
- {0x98070000u, 46u}, // hag -> Latn
- {0xA8070000u, 29u}, // hak -> Hans
- {0xB0070000u, 46u}, // ham -> Latn
- {0xD8070000u, 46u}, // haw -> Latn
- {0xE4070000u, 2u}, // haz -> Arab
- {0x84270000u, 46u}, // hbb -> Latn
- {0xE0670000u, 21u}, // hdy -> Ethi
- {0x68650000u, 31u}, // he -> Hebr
- {0xE0E70000u, 46u}, // hhy -> Latn
- {0x68690000u, 19u}, // hi -> Deva
- {0x81070000u, 46u}, // hia -> Latn
- {0x95070000u, 46u}, // hif -> Latn
- {0x99070000u, 46u}, // hig -> Latn
- {0x9D070000u, 46u}, // hih -> Latn
- {0xAD070000u, 46u}, // hil -> Latn
- {0x81670000u, 46u}, // hla -> Latn
- {0xD1670000u, 32u}, // hlu -> Hluw
- {0x8D870000u, 72u}, // hmd -> Plrd
- {0xCD870000u, 46u}, // hmt -> Latn
- {0x8DA70000u, 2u}, // hnd -> Arab
- {0x91A70000u, 19u}, // hne -> Deva
- {0xA5A70000u, 33u}, // hnj -> Hmnp
- {0xB5A70000u, 46u}, // hnn -> Latn
- {0xB9A70000u, 2u}, // hno -> Arab
- {0x686F0000u, 46u}, // ho -> Latn
- {0x89C70000u, 19u}, // hoc -> Deva
- {0xA5C70000u, 19u}, // hoj -> Deva
- {0xCDC70000u, 46u}, // hot -> Latn
- {0x68720000u, 46u}, // hr -> Latn
- {0x86470000u, 46u}, // hsb -> Latn
- {0xB6470000u, 29u}, // hsn -> Hans
- {0x68740000u, 46u}, // ht -> Latn
- {0x68750000u, 46u}, // hu -> Latn
- {0xA2870000u, 46u}, // hui -> Latn
- {0xC6870000u, 46u}, // hur -> Latn
- {0x68790000u, 4u}, // hy -> Armn
- {0x687A0000u, 46u}, // hz -> Latn
- {0x69610000u, 46u}, // ia -> Latn
- {0xB4080000u, 46u}, // ian -> Latn
- {0xC4080000u, 46u}, // iar -> Latn
- {0x80280000u, 46u}, // iba -> Latn
- {0x84280000u, 46u}, // ibb -> Latn
- {0xE0280000u, 46u}, // iby -> Latn
- {0x80480000u, 46u}, // ica -> Latn
- {0x9C480000u, 46u}, // ich -> Latn
- {0x69640000u, 46u}, // id -> Latn
- {0x8C680000u, 46u}, // idd -> Latn
- {0xA0680000u, 46u}, // idi -> Latn
- {0xD0680000u, 46u}, // idu -> Latn
- {0x90A80000u, 46u}, // ife -> Latn
- {0x69670000u, 46u}, // ig -> Latn
- {0x84C80000u, 46u}, // igb -> Latn
- {0x90C80000u, 46u}, // ige -> Latn
- {0x69690000u, 102u}, // ii -> Yiii
- {0xA5280000u, 46u}, // ijj -> Latn
- {0x696B0000u, 46u}, // ik -> Latn
- {0xA9480000u, 46u}, // ikk -> Latn
- {0xD9480000u, 46u}, // ikw -> Latn
- {0xDD480000u, 46u}, // ikx -> Latn
- {0xB9680000u, 46u}, // ilo -> Latn
- {0xB9880000u, 46u}, // imo -> Latn
- {0x696E0000u, 46u}, // in -> Latn
- {0x9DA80000u, 18u}, // inh -> Cyrl
- {0x696F0000u, 46u}, // io -> Latn
- {0xD1C80000u, 46u}, // iou -> Latn
- {0xA2280000u, 46u}, // iri -> Latn
- {0x69730000u, 46u}, // is -> Latn
- {0x69740000u, 46u}, // it -> Latn
- {0x69750000u, 11u}, // iu -> Cans
- {0x69770000u, 31u}, // iw -> Hebr
- {0xB2C80000u, 46u}, // iwm -> Latn
- {0xCAC80000u, 46u}, // iws -> Latn
- {0x9F280000u, 46u}, // izh -> Latn
- {0xA3280000u, 46u}, // izi -> Latn
- {0x6A610000u, 35u}, // ja -> Jpan
- {0x84090000u, 46u}, // jab -> Latn
- {0xB0090000u, 46u}, // jam -> Latn
- {0xC4090000u, 46u}, // jar -> Latn
- {0xB8290000u, 46u}, // jbo -> Latn
- {0xD0290000u, 46u}, // jbu -> Latn
- {0xB4890000u, 46u}, // jen -> Latn
- {0xA8C90000u, 46u}, // jgk -> Latn
- {0xB8C90000u, 46u}, // jgo -> Latn
- {0x6A690000u, 31u}, // ji -> Hebr
- {0x85090000u, 46u}, // jib -> Latn
- {0x89890000u, 46u}, // jmc -> Latn
- {0xAD890000u, 19u}, // jml -> Deva
- {0x82290000u, 46u}, // jra -> Latn
- {0xCE890000u, 46u}, // jut -> Latn
- {0x6A760000u, 46u}, // jv -> Latn
- {0x6A770000u, 46u}, // jw -> Latn
- {0x6B610000u, 22u}, // ka -> Geor
- {0x800A0000u, 18u}, // kaa -> Cyrl
- {0x840A0000u, 46u}, // kab -> Latn
- {0x880A0000u, 46u}, // kac -> Latn
- {0x8C0A0000u, 46u}, // kad -> Latn
- {0xA00A0000u, 46u}, // kai -> Latn
- {0xA40A0000u, 46u}, // kaj -> Latn
- {0xB00A0000u, 46u}, // kam -> Latn
- {0xB80A0000u, 46u}, // kao -> Latn
- {0xD80A0000u, 38u}, // kaw -> Kawi
- {0x8C2A0000u, 18u}, // kbd -> Cyrl
- {0xB02A0000u, 46u}, // kbm -> Latn
- {0xBC2A0000u, 46u}, // kbp -> Latn
- {0xC02A0000u, 46u}, // kbq -> Latn
- {0xDC2A0000u, 46u}, // kbx -> Latn
- {0xE02A0000u, 2u}, // kby -> Arab
- {0x984A0000u, 46u}, // kcg -> Latn
- {0xA84A0000u, 46u}, // kck -> Latn
- {0xAC4A0000u, 46u}, // kcl -> Latn
- {0xCC4A0000u, 46u}, // kct -> Latn
- {0x906A0000u, 46u}, // kde -> Latn
- {0x9C6A0000u, 46u}, // kdh -> Latn
- {0xAC6A0000u, 46u}, // kdl -> Latn
- {0xCC6A0000u, 93u}, // kdt -> Thai
- {0x808A0000u, 46u}, // kea -> Latn
- {0xB48A0000u, 46u}, // ken -> Latn
- {0xE48A0000u, 46u}, // kez -> Latn
- {0xB8AA0000u, 46u}, // kfo -> Latn
- {0xC4AA0000u, 19u}, // kfr -> Deva
- {0xE0AA0000u, 19u}, // kfy -> Deva
- {0x6B670000u, 46u}, // kg -> Latn
- {0x90CA0000u, 46u}, // kge -> Latn
- {0x94CA0000u, 46u}, // kgf -> Latn
- {0xBCCA0000u, 46u}, // kgp -> Latn
- {0x80EA0000u, 46u}, // kha -> Latn
- {0x84EA0000u, 86u}, // khb -> Talu
- {0xB4EA0000u, 19u}, // khn -> Deva
- {0xC0EA0000u, 46u}, // khq -> Latn
- {0xC8EA0000u, 46u}, // khs -> Latn
- {0xCCEA0000u, 59u}, // kht -> Mymr
- {0xD8EA0000u, 2u}, // khw -> Arab
- {0xE4EA0000u, 46u}, // khz -> Latn
- {0x6B690000u, 46u}, // ki -> Latn
- {0xA50A0000u, 46u}, // kij -> Latn
- {0xD10A0000u, 46u}, // kiu -> Latn
- {0xD90A0000u, 46u}, // kiw -> Latn
- {0x6B6A0000u, 46u}, // kj -> Latn
- {0x8D2A0000u, 46u}, // kjd -> Latn
- {0x992A0000u, 45u}, // kjg -> Laoo
- {0xC92A0000u, 46u}, // kjs -> Latn
- {0xE12A0000u, 46u}, // kjy -> Latn
- {0x6B6B0000u, 18u}, // kk -> Cyrl
- {0x6B6B4146u, 2u}, // kk-AF -> Arab
- {0x6B6B434Eu, 2u}, // kk-CN -> Arab
- {0x6B6B4952u, 2u}, // kk-IR -> Arab
- {0x6B6B4D4Eu, 2u}, // kk-MN -> Arab
- {0x894A0000u, 46u}, // kkc -> Latn
- {0xA54A0000u, 46u}, // kkj -> Latn
- {0x6B6C0000u, 46u}, // kl -> Latn
- {0xB56A0000u, 46u}, // kln -> Latn
- {0xC16A0000u, 46u}, // klq -> Latn
- {0xCD6A0000u, 46u}, // klt -> Latn
- {0xDD6A0000u, 46u}, // klx -> Latn
- {0x6B6D0000u, 40u}, // km -> Khmr
- {0x858A0000u, 46u}, // kmb -> Latn
- {0x9D8A0000u, 46u}, // kmh -> Latn
- {0xB98A0000u, 46u}, // kmo -> Latn
- {0xC98A0000u, 46u}, // kms -> Latn
- {0xD18A0000u, 46u}, // kmu -> Latn
- {0xD98A0000u, 46u}, // kmw -> Latn
- {0x6B6E0000u, 42u}, // kn -> Knda
- {0x95AA0000u, 46u}, // knf -> Latn
- {0xBDAA0000u, 46u}, // knp -> Latn
- {0x6B6F0000u, 43u}, // ko -> Kore
- {0xA1CA0000u, 18u}, // koi -> Cyrl
- {0xA9CA0000u, 19u}, // kok -> Deva
- {0xADCA0000u, 46u}, // kol -> Latn
- {0xC9CA0000u, 46u}, // kos -> Latn
- {0xE5CA0000u, 46u}, // koz -> Latn
- {0x91EA0000u, 46u}, // kpe -> Latn
- {0x95EA0000u, 46u}, // kpf -> Latn
- {0xB9EA0000u, 46u}, // kpo -> Latn
- {0xC5EA0000u, 46u}, // kpr -> Latn
- {0xDDEA0000u, 46u}, // kpx -> Latn
- {0x860A0000u, 46u}, // kqb -> Latn
- {0x960A0000u, 46u}, // kqf -> Latn
- {0xCA0A0000u, 46u}, // kqs -> Latn
- {0xE20A0000u, 21u}, // kqy -> Ethi
- {0x6B720000u, 46u}, // kr -> Latn
- {0x8A2A0000u, 18u}, // krc -> Cyrl
- {0xA22A0000u, 46u}, // kri -> Latn
- {0xA62A0000u, 46u}, // krj -> Latn
- {0xAE2A0000u, 46u}, // krl -> Latn
- {0xCA2A0000u, 46u}, // krs -> Latn
- {0xD22A0000u, 19u}, // kru -> Deva
- {0x6B730000u, 2u}, // ks -> Arab
- {0x864A0000u, 46u}, // ksb -> Latn
- {0x8E4A0000u, 46u}, // ksd -> Latn
- {0x964A0000u, 46u}, // ksf -> Latn
- {0x9E4A0000u, 46u}, // ksh -> Latn
- {0xA64A0000u, 46u}, // ksj -> Latn
- {0xC64A0000u, 46u}, // ksr -> Latn
- {0x866A0000u, 21u}, // ktb -> Ethi
- {0xB26A0000u, 46u}, // ktm -> Latn
- {0xBA6A0000u, 46u}, // kto -> Latn
- {0xC66A0000u, 46u}, // ktr -> Latn
- {0x6B750000u, 46u}, // ku -> Latn
- {0x6B754952u, 2u}, // ku-IR -> Arab
- {0x6B754C42u, 2u}, // ku-LB -> Arab
- {0x868A0000u, 46u}, // kub -> Latn
- {0x8E8A0000u, 46u}, // kud -> Latn
- {0x928A0000u, 46u}, // kue -> Latn
- {0xA68A0000u, 46u}, // kuj -> Latn
- {0xB28A0000u, 18u}, // kum -> Cyrl
- {0xB68A0000u, 46u}, // kun -> Latn
- {0xBE8A0000u, 46u}, // kup -> Latn
- {0xCA8A0000u, 46u}, // kus -> Latn
- {0x6B760000u, 18u}, // kv -> Cyrl
- {0x9AAA0000u, 46u}, // kvg -> Latn
- {0xC6AA0000u, 46u}, // kvr -> Latn
- {0xDEAA0000u, 2u}, // kvx -> Arab
- {0x6B770000u, 46u}, // kw -> Latn
- {0xA6CA0000u, 46u}, // kwj -> Latn
- {0xAACA0000u, 46u}, // kwk -> Latn
- {0xBACA0000u, 46u}, // kwo -> Latn
- {0xC2CA0000u, 46u}, // kwq -> Latn
- {0x82EA0000u, 46u}, // kxa -> Latn
- {0x8AEA0000u, 21u}, // kxc -> Ethi
- {0x92EA0000u, 46u}, // kxe -> Latn
- {0xAEEA0000u, 19u}, // kxl -> Deva
- {0xB2EA0000u, 93u}, // kxm -> Thai
- {0xBEEA0000u, 2u}, // kxp -> Arab
- {0xDAEA0000u, 46u}, // kxw -> Latn
- {0xE6EA0000u, 46u}, // kxz -> Latn
- {0x6B790000u, 18u}, // ky -> Cyrl
- {0x6B79434Eu, 2u}, // ky-CN -> Arab
- {0x6B795452u, 46u}, // ky-TR -> Latn
- {0x930A0000u, 46u}, // kye -> Latn
- {0xDF0A0000u, 46u}, // kyx -> Latn
- {0x9F2A0000u, 2u}, // kzh -> Arab
- {0xA72A0000u, 46u}, // kzj -> Latn
- {0xC72A0000u, 46u}, // kzr -> Latn
- {0xCF2A0000u, 46u}, // kzt -> Latn
- {0x6C610000u, 46u}, // la -> Latn
- {0x840B0000u, 48u}, // lab -> Lina
- {0x8C0B0000u, 31u}, // lad -> Hebr
- {0x980B0000u, 46u}, // lag -> Latn
- {0x9C0B0000u, 2u}, // lah -> Arab
- {0xA40B0000u, 46u}, // laj -> Latn
- {0xC80B0000u, 46u}, // las -> Latn
- {0x6C620000u, 46u}, // lb -> Latn
- {0x902B0000u, 18u}, // lbe -> Cyrl
- {0xD02B0000u, 46u}, // lbu -> Latn
- {0xD82B0000u, 46u}, // lbw -> Latn
- {0xB04B0000u, 46u}, // lcm -> Latn
- {0xBC4B0000u, 93u}, // lcp -> Thai
- {0x846B0000u, 46u}, // ldb -> Latn
- {0x8C8B0000u, 46u}, // led -> Latn
- {0x908B0000u, 46u}, // lee -> Latn
- {0xB08B0000u, 46u}, // lem -> Latn
- {0xBC8B0000u, 47u}, // lep -> Lepc
- {0xC08B0000u, 46u}, // leq -> Latn
- {0xD08B0000u, 46u}, // leu -> Latn
- {0xE48B0000u, 18u}, // lez -> Cyrl
- {0x6C670000u, 46u}, // lg -> Latn
- {0x98CB0000u, 46u}, // lgg -> Latn
- {0x6C690000u, 46u}, // li -> Latn
- {0x810B0000u, 46u}, // lia -> Latn
- {0x8D0B0000u, 46u}, // lid -> Latn
- {0x950B0000u, 19u}, // lif -> Deva
- {0x990B0000u, 46u}, // lig -> Latn
- {0x9D0B0000u, 46u}, // lih -> Latn
- {0xA50B0000u, 46u}, // lij -> Latn
- {0xAD0B0000u, 46u}, // lil -> Latn
- {0xC90B0000u, 49u}, // lis -> Lisu
- {0xBD2B0000u, 46u}, // ljp -> Latn
- {0xA14B0000u, 2u}, // lki -> Arab
- {0xCD4B0000u, 46u}, // lkt -> Latn
- {0x916B0000u, 46u}, // lle -> Latn
- {0xB56B0000u, 46u}, // lln -> Latn
- {0xB58B0000u, 90u}, // lmn -> Telu
- {0xB98B0000u, 46u}, // lmo -> Latn
- {0xBD8B0000u, 46u}, // lmp -> Latn
- {0x6C6E0000u, 46u}, // ln -> Latn
- {0xC9AB0000u, 46u}, // lns -> Latn
- {0xD1AB0000u, 46u}, // lnu -> Latn
- {0x6C6F0000u, 45u}, // lo -> Laoo
- {0xA5CB0000u, 46u}, // loj -> Latn
- {0xA9CB0000u, 46u}, // lok -> Latn
- {0xADCB0000u, 46u}, // lol -> Latn
- {0xC5CB0000u, 46u}, // lor -> Latn
- {0xC9CB0000u, 46u}, // los -> Latn
- {0xE5CB0000u, 46u}, // loz -> Latn
- {0x8A2B0000u, 2u}, // lrc -> Arab
- {0x6C740000u, 46u}, // lt -> Latn
- {0x9A6B0000u, 46u}, // ltg -> Latn
- {0x6C750000u, 46u}, // lu -> Latn
- {0x828B0000u, 46u}, // lua -> Latn
- {0xBA8B0000u, 46u}, // luo -> Latn
- {0xE28B0000u, 46u}, // luy -> Latn
- {0xE68B0000u, 2u}, // luz -> Arab
- {0x6C760000u, 46u}, // lv -> Latn
- {0xAECB0000u, 93u}, // lwl -> Thai
- {0x9F2B0000u, 29u}, // lzh -> Hans
- {0xE72B0000u, 46u}, // lzz -> Latn
- {0x8C0C0000u, 46u}, // mad -> Latn
- {0x940C0000u, 46u}, // maf -> Latn
- {0x980C0000u, 19u}, // mag -> Deva
- {0xA00C0000u, 19u}, // mai -> Deva
- {0xA80C0000u, 46u}, // mak -> Latn
- {0xB40C0000u, 46u}, // man -> Latn
- {0xB40C474Eu, 61u}, // man-GN -> Nkoo
- {0xC80C0000u, 46u}, // mas -> Latn
- {0xD80C0000u, 46u}, // maw -> Latn
- {0xE40C0000u, 46u}, // maz -> Latn
- {0x9C2C0000u, 46u}, // mbh -> Latn
- {0xB82C0000u, 46u}, // mbo -> Latn
- {0xC02C0000u, 46u}, // mbq -> Latn
- {0xD02C0000u, 46u}, // mbu -> Latn
- {0xD82C0000u, 46u}, // mbw -> Latn
- {0xA04C0000u, 46u}, // mci -> Latn
- {0xBC4C0000u, 46u}, // mcp -> Latn
- {0xC04C0000u, 46u}, // mcq -> Latn
- {0xC44C0000u, 46u}, // mcr -> Latn
- {0xD04C0000u, 46u}, // mcu -> Latn
- {0x806C0000u, 46u}, // mda -> Latn
- {0x906C0000u, 2u}, // mde -> Arab
- {0x946C0000u, 18u}, // mdf -> Cyrl
- {0x9C6C0000u, 46u}, // mdh -> Latn
- {0xA46C0000u, 46u}, // mdj -> Latn
- {0xC46C0000u, 46u}, // mdr -> Latn
- {0xDC6C0000u, 21u}, // mdx -> Ethi
- {0x8C8C0000u, 46u}, // med -> Latn
- {0x908C0000u, 46u}, // mee -> Latn
- {0xA88C0000u, 46u}, // mek -> Latn
- {0xB48C0000u, 46u}, // men -> Latn
- {0xC48C0000u, 46u}, // mer -> Latn
- {0xCC8C0000u, 46u}, // met -> Latn
- {0xD08C0000u, 46u}, // meu -> Latn
- {0x80AC0000u, 2u}, // mfa -> Arab
- {0x90AC0000u, 46u}, // mfe -> Latn
- {0xB4AC0000u, 46u}, // mfn -> Latn
- {0xB8AC0000u, 46u}, // mfo -> Latn
- {0xC0AC0000u, 46u}, // mfq -> Latn
- {0x6D670000u, 46u}, // mg -> Latn
- {0x9CCC0000u, 46u}, // mgh -> Latn
- {0xACCC0000u, 46u}, // mgl -> Latn
- {0xB8CC0000u, 46u}, // mgo -> Latn
- {0xBCCC0000u, 19u}, // mgp -> Deva
- {0xE0CC0000u, 46u}, // mgy -> Latn
- {0x6D680000u, 46u}, // mh -> Latn
- {0xA0EC0000u, 46u}, // mhi -> Latn
- {0xACEC0000u, 46u}, // mhl -> Latn
- {0x6D690000u, 46u}, // mi -> Latn
- {0x890C0000u, 46u}, // mic -> Latn
- {0x950C0000u, 46u}, // mif -> Latn
- {0xB50C0000u, 46u}, // min -> Latn
- {0xD90C0000u, 46u}, // miw -> Latn
- {0x6D6B0000u, 18u}, // mk -> Cyrl
- {0xA14C0000u, 2u}, // mki -> Arab
- {0xAD4C0000u, 46u}, // mkl -> Latn
- {0xBD4C0000u, 46u}, // mkp -> Latn
- {0xD94C0000u, 46u}, // mkw -> Latn
- {0x6D6C0000u, 56u}, // ml -> Mlym
- {0x916C0000u, 46u}, // mle -> Latn
- {0xBD6C0000u, 46u}, // mlp -> Latn
- {0xC96C0000u, 46u}, // mls -> Latn
- {0xB98C0000u, 46u}, // mmo -> Latn
- {0xD18C0000u, 46u}, // mmu -> Latn
- {0xDD8C0000u, 46u}, // mmx -> Latn
- {0x6D6E0000u, 18u}, // mn -> Cyrl
- {0x6D6E434Eu, 57u}, // mn-CN -> Mong
- {0x81AC0000u, 46u}, // mna -> Latn
- {0x95AC0000u, 46u}, // mnf -> Latn
- {0xA1AC0000u, 8u}, // mni -> Beng
- {0xD9AC0000u, 59u}, // mnw -> Mymr
- {0x6D6F0000u, 46u}, // mo -> Latn
- {0x81CC0000u, 46u}, // moa -> Latn
- {0x91CC0000u, 46u}, // moe -> Latn
- {0x9DCC0000u, 46u}, // moh -> Latn
- {0xC9CC0000u, 46u}, // mos -> Latn
- {0xDDCC0000u, 46u}, // mox -> Latn
- {0xBDEC0000u, 46u}, // mpp -> Latn
- {0xC9EC0000u, 46u}, // mps -> Latn
- {0xCDEC0000u, 46u}, // mpt -> Latn
- {0xDDEC0000u, 46u}, // mpx -> Latn
- {0xAE0C0000u, 46u}, // mql -> Latn
- {0x6D720000u, 19u}, // mr -> Deva
- {0x8E2C0000u, 19u}, // mrd -> Deva
- {0xA62C0000u, 18u}, // mrj -> Cyrl
- {0xBA2C0000u, 58u}, // mro -> Mroo
- {0x6D730000u, 46u}, // ms -> Latn
- {0x6D734343u, 2u}, // ms-CC -> Arab
- {0x6D740000u, 46u}, // mt -> Latn
- {0x8A6C0000u, 46u}, // mtc -> Latn
- {0x966C0000u, 46u}, // mtf -> Latn
- {0xA26C0000u, 46u}, // mti -> Latn
- {0xC66C0000u, 19u}, // mtr -> Deva
- {0x828C0000u, 46u}, // mua -> Latn
- {0xC68C0000u, 46u}, // mur -> Latn
- {0xCA8C0000u, 46u}, // mus -> Latn
- {0x82AC0000u, 46u}, // mva -> Latn
- {0xB6AC0000u, 46u}, // mvn -> Latn
- {0xE2AC0000u, 2u}, // mvy -> Arab
- {0xAACC0000u, 46u}, // mwk -> Latn
- {0xC6CC0000u, 19u}, // mwr -> Deva
- {0xD6CC0000u, 46u}, // mwv -> Latn
- {0xDACC0000u, 33u}, // mww -> Hmnp
- {0x8AEC0000u, 46u}, // mxc -> Latn
- {0xB2EC0000u, 46u}, // mxm -> Latn
- {0x6D790000u, 59u}, // my -> Mymr
- {0xAB0C0000u, 46u}, // myk -> Latn
- {0xB30C0000u, 21u}, // mym -> Ethi
- {0xD70C0000u, 18u}, // myv -> Cyrl
- {0xDB0C0000u, 46u}, // myw -> Latn
- {0xDF0C0000u, 46u}, // myx -> Latn
- {0xE70C0000u, 52u}, // myz -> Mand
- {0xAB2C0000u, 46u}, // mzk -> Latn
- {0xB32C0000u, 46u}, // mzm -> Latn
- {0xB72C0000u, 2u}, // mzn -> Arab
- {0xBF2C0000u, 46u}, // mzp -> Latn
- {0xDB2C0000u, 46u}, // mzw -> Latn
- {0xE72C0000u, 46u}, // mzz -> Latn
- {0x6E610000u, 46u}, // na -> Latn
- {0x880D0000u, 46u}, // nac -> Latn
- {0x940D0000u, 46u}, // naf -> Latn
- {0xA80D0000u, 46u}, // nak -> Latn
- {0xB40D0000u, 29u}, // nan -> Hans
- {0xBC0D0000u, 46u}, // nap -> Latn
- {0xC00D0000u, 46u}, // naq -> Latn
- {0xC80D0000u, 46u}, // nas -> Latn
- {0x6E620000u, 46u}, // nb -> Latn
- {0x804D0000u, 46u}, // nca -> Latn
- {0x904D0000u, 46u}, // nce -> Latn
- {0x944D0000u, 46u}, // ncf -> Latn
- {0x9C4D0000u, 46u}, // nch -> Latn
- {0xB84D0000u, 46u}, // nco -> Latn
- {0xD04D0000u, 46u}, // ncu -> Latn
- {0x6E640000u, 46u}, // nd -> Latn
- {0x886D0000u, 46u}, // ndc -> Latn
- {0xC86D0000u, 46u}, // nds -> Latn
- {0x6E650000u, 19u}, // ne -> Deva
- {0x848D0000u, 46u}, // neb -> Latn
- {0xD88D0000u, 19u}, // new -> Deva
- {0xDC8D0000u, 46u}, // nex -> Latn
- {0xC4AD0000u, 46u}, // nfr -> Latn
- {0x6E670000u, 46u}, // ng -> Latn
- {0x80CD0000u, 46u}, // nga -> Latn
- {0x84CD0000u, 46u}, // ngb -> Latn
- {0xACCD0000u, 46u}, // ngl -> Latn
- {0x84ED0000u, 46u}, // nhb -> Latn
- {0x90ED0000u, 46u}, // nhe -> Latn
- {0xD8ED0000u, 46u}, // nhw -> Latn
- {0x950D0000u, 46u}, // nif -> Latn
- {0xA10D0000u, 46u}, // nii -> Latn
- {0xA50D0000u, 46u}, // nij -> Latn
- {0xB50D0000u, 46u}, // nin -> Latn
- {0xD10D0000u, 46u}, // niu -> Latn
- {0xE10D0000u, 46u}, // niy -> Latn
- {0xE50D0000u, 46u}, // niz -> Latn
- {0xB92D0000u, 46u}, // njo -> Latn
- {0x994D0000u, 46u}, // nkg -> Latn
- {0xB94D0000u, 46u}, // nko -> Latn
- {0x6E6C0000u, 46u}, // nl -> Latn
- {0x998D0000u, 46u}, // nmg -> Latn
- {0xE58D0000u, 46u}, // nmz -> Latn
- {0x6E6E0000u, 46u}, // nn -> Latn
- {0x95AD0000u, 46u}, // nnf -> Latn
- {0x9DAD0000u, 46u}, // nnh -> Latn
- {0xA9AD0000u, 46u}, // nnk -> Latn
- {0xB1AD0000u, 46u}, // nnm -> Latn
- {0xBDAD0000u, 99u}, // nnp -> Wcho
- {0x6E6F0000u, 46u}, // no -> Latn
- {0x8DCD0000u, 44u}, // nod -> Lana
- {0x91CD0000u, 19u}, // noe -> Deva
- {0xB5CD0000u, 75u}, // non -> Runr
- {0xBDCD0000u, 46u}, // nop -> Latn
- {0xD1CD0000u, 46u}, // nou -> Latn
- {0xBA0D0000u, 61u}, // nqo -> Nkoo
- {0x6E720000u, 46u}, // nr -> Latn
- {0x862D0000u, 46u}, // nrb -> Latn
- {0xAA4D0000u, 11u}, // nsk -> Cans
- {0xB64D0000u, 46u}, // nsn -> Latn
- {0xBA4D0000u, 46u}, // nso -> Latn
- {0xCA4D0000u, 46u}, // nss -> Latn
- {0xCE4D0000u, 95u}, // nst -> Tnsa
- {0xB26D0000u, 46u}, // ntm -> Latn
- {0xC66D0000u, 46u}, // ntr -> Latn
- {0xA28D0000u, 46u}, // nui -> Latn
- {0xBE8D0000u, 46u}, // nup -> Latn
- {0xCA8D0000u, 46u}, // nus -> Latn
- {0xD68D0000u, 46u}, // nuv -> Latn
- {0xDE8D0000u, 46u}, // nux -> Latn
- {0x6E760000u, 46u}, // nv -> Latn
- {0x86CD0000u, 46u}, // nwb -> Latn
- {0xC2ED0000u, 46u}, // nxq -> Latn
- {0xC6ED0000u, 46u}, // nxr -> Latn
- {0x6E790000u, 46u}, // ny -> Latn
- {0xB30D0000u, 46u}, // nym -> Latn
- {0xB70D0000u, 46u}, // nyn -> Latn
- {0xA32D0000u, 46u}, // nzi -> Latn
- {0x6F630000u, 46u}, // oc -> Latn
- {0x6F634553u, 46u}, // oc-ES -> Latn
- {0x88CE0000u, 46u}, // ogc -> Latn
- {0x6F6A0000u, 11u}, // oj -> Cans
- {0xC92E0000u, 11u}, // ojs -> Cans
- {0x814E0000u, 46u}, // oka -> Latn
- {0xC54E0000u, 46u}, // okr -> Latn
- {0xD54E0000u, 46u}, // okv -> Latn
- {0x6F6D0000u, 46u}, // om -> Latn
- {0x99AE0000u, 46u}, // ong -> Latn
- {0xB5AE0000u, 46u}, // onn -> Latn
- {0xC9AE0000u, 46u}, // ons -> Latn
- {0xB1EE0000u, 46u}, // opm -> Latn
- {0x6F720000u, 66u}, // or -> Orya
- {0xBA2E0000u, 46u}, // oro -> Latn
- {0xD22E0000u, 2u}, // oru -> Arab
- {0x6F730000u, 18u}, // os -> Cyrl
- {0x824E0000u, 67u}, // osa -> Osge
- {0x826E0000u, 2u}, // ota -> Arab
- {0xAA6E0000u, 65u}, // otk -> Orkh
- {0xA28E0000u, 68u}, // oui -> Ougr
- {0xB32E0000u, 46u}, // ozm -> Latn
- {0x70610000u, 28u}, // pa -> Guru
- {0x7061504Bu, 2u}, // pa-PK -> Arab
- {0x980F0000u, 46u}, // pag -> Latn
- {0xAC0F0000u, 70u}, // pal -> Phli
- {0xB00F0000u, 46u}, // pam -> Latn
- {0xBC0F0000u, 46u}, // pap -> Latn
- {0xD00F0000u, 46u}, // pau -> Latn
- {0xA02F0000u, 46u}, // pbi -> Latn
- {0x8C4F0000u, 46u}, // pcd -> Latn
- {0xB04F0000u, 46u}, // pcm -> Latn
- {0x886F0000u, 46u}, // pdc -> Latn
- {0xCC6F0000u, 46u}, // pdt -> Latn
- {0x8C8F0000u, 46u}, // ped -> Latn
- {0xB88F0000u, 100u}, // peo -> Xpeo
- {0xDC8F0000u, 46u}, // pex -> Latn
- {0xACAF0000u, 46u}, // pfl -> Latn
- {0xACEF0000u, 2u}, // phl -> Arab
- {0xB4EF0000u, 71u}, // phn -> Phnx
- {0xAD0F0000u, 46u}, // pil -> Latn
- {0xBD0F0000u, 46u}, // pip -> Latn
- {0xC90F0000u, 46u}, // pis -> Latn
- {0x814F0000u, 9u}, // pka -> Brah
- {0xB94F0000u, 46u}, // pko -> Latn
- {0x706C0000u, 46u}, // pl -> Latn
- {0x816F0000u, 46u}, // pla -> Latn
- {0xC98F0000u, 46u}, // pms -> Latn
- {0x99AF0000u, 46u}, // png -> Latn
- {0xB5AF0000u, 46u}, // pnn -> Latn
- {0xCDAF0000u, 26u}, // pnt -> Grek
- {0xB5CF0000u, 46u}, // pon -> Latn
- {0x81EF0000u, 19u}, // ppa -> Deva
- {0xB9EF0000u, 46u}, // ppo -> Latn
- {0xB20F0000u, 46u}, // pqm -> Latn
- {0x822F0000u, 39u}, // pra -> Khar
- {0x8E2F0000u, 2u}, // prd -> Arab
- {0x9A2F0000u, 46u}, // prg -> Latn
- {0x70730000u, 2u}, // ps -> Arab
- {0xCA4F0000u, 46u}, // pss -> Latn
- {0x70740000u, 46u}, // pt -> Latn
- {0xBE6F0000u, 46u}, // ptp -> Latn
- {0xD28F0000u, 46u}, // puu -> Latn
- {0x82CF0000u, 46u}, // pwa -> Latn
- {0x71750000u, 46u}, // qu -> Latn
- {0x8A900000u, 46u}, // quc -> Latn
- {0x9A900000u, 46u}, // qug -> Latn
- {0xA0110000u, 46u}, // rai -> Latn
- {0xA4110000u, 19u}, // raj -> Deva
- {0xB8110000u, 46u}, // rao -> Latn
- {0x94510000u, 46u}, // rcf -> Latn
- {0xA4910000u, 46u}, // rej -> Latn
- {0xAC910000u, 46u}, // rel -> Latn
- {0xC8910000u, 46u}, // res -> Latn
- {0xB4D10000u, 46u}, // rgn -> Latn
- {0x98F10000u, 74u}, // rhg -> Rohg
- {0x81110000u, 46u}, // ria -> Latn
- {0x95110000u, 91u}, // rif -> Tfng
- {0x95114E4Cu, 46u}, // rif-NL -> Latn
- {0xC9310000u, 19u}, // rjs -> Deva
- {0xCD510000u, 8u}, // rkt -> Beng
- {0x726D0000u, 46u}, // rm -> Latn
- {0x95910000u, 46u}, // rmf -> Latn
- {0xB9910000u, 46u}, // rmo -> Latn
- {0xCD910000u, 2u}, // rmt -> Arab
- {0xD1910000u, 46u}, // rmu -> Latn
- {0x726E0000u, 46u}, // rn -> Latn
- {0x81B10000u, 46u}, // rna -> Latn
- {0x99B10000u, 46u}, // rng -> Latn
- {0x726F0000u, 46u}, // ro -> Latn
- {0x85D10000u, 46u}, // rob -> Latn
- {0x95D10000u, 46u}, // rof -> Latn
- {0xB9D10000u, 46u}, // roo -> Latn
- {0xBA310000u, 46u}, // rro -> Latn
- {0xB2710000u, 46u}, // rtm -> Latn
- {0x72750000u, 18u}, // ru -> Cyrl
- {0x92910000u, 18u}, // rue -> Cyrl
- {0x9A910000u, 46u}, // rug -> Latn
- {0x72770000u, 46u}, // rw -> Latn
- {0xAAD10000u, 46u}, // rwk -> Latn
- {0xBAD10000u, 46u}, // rwo -> Latn
- {0xD3110000u, 37u}, // ryu -> Kana
- {0x73610000u, 19u}, // sa -> Deva
- {0x94120000u, 46u}, // saf -> Latn
- {0x9C120000u, 18u}, // sah -> Cyrl
- {0xC0120000u, 46u}, // saq -> Latn
- {0xC8120000u, 46u}, // sas -> Latn
- {0xCC120000u, 64u}, // sat -> Olck
- {0xD4120000u, 46u}, // sav -> Latn
- {0xE4120000u, 78u}, // saz -> Saur
- {0x80320000u, 46u}, // sba -> Latn
- {0x90320000u, 46u}, // sbe -> Latn
- {0xBC320000u, 46u}, // sbp -> Latn
- {0x73630000u, 46u}, // sc -> Latn
- {0xA8520000u, 19u}, // sck -> Deva
- {0xAC520000u, 2u}, // scl -> Arab
- {0xB4520000u, 46u}, // scn -> Latn
- {0xB8520000u, 46u}, // sco -> Latn
- {0x73640000u, 2u}, // sd -> Arab
- {0x7364494Eu, 19u}, // sd-IN -> Deva
- {0x88720000u, 46u}, // sdc -> Latn
- {0x9C720000u, 2u}, // sdh -> Arab
- {0x73650000u, 46u}, // se -> Latn
- {0x94920000u, 46u}, // sef -> Latn
- {0x9C920000u, 46u}, // seh -> Latn
- {0xA0920000u, 46u}, // sei -> Latn
- {0xC8920000u, 46u}, // ses -> Latn
- {0x73670000u, 46u}, // sg -> Latn
- {0x80D20000u, 63u}, // sga -> Ogam
- {0xC8D20000u, 46u}, // sgs -> Latn
- {0xD8D20000u, 21u}, // sgw -> Ethi
- {0xE4D20000u, 46u}, // sgz -> Latn
- {0x73680000u, 46u}, // sh -> Latn
- {0xA0F20000u, 91u}, // shi -> Tfng
- {0xA8F20000u, 46u}, // shk -> Latn
- {0xB4F20000u, 59u}, // shn -> Mymr
- {0xD0F20000u, 2u}, // shu -> Arab
- {0x73690000u, 80u}, // si -> Sinh
- {0x8D120000u, 46u}, // sid -> Latn
- {0x99120000u, 46u}, // sig -> Latn
- {0xAD120000u, 46u}, // sil -> Latn
- {0xB1120000u, 46u}, // sim -> Latn
- {0xC5320000u, 46u}, // sjr -> Latn
- {0x736B0000u, 46u}, // sk -> Latn
- {0x89520000u, 46u}, // skc -> Latn
- {0xC5520000u, 2u}, // skr -> Arab
- {0xC9520000u, 46u}, // sks -> Latn
- {0x736C0000u, 46u}, // sl -> Latn
- {0x8D720000u, 46u}, // sld -> Latn
- {0xA1720000u, 46u}, // sli -> Latn
- {0xAD720000u, 46u}, // sll -> Latn
- {0xE1720000u, 46u}, // sly -> Latn
- {0x736D0000u, 46u}, // sm -> Latn
- {0x81920000u, 46u}, // sma -> Latn
- {0x8D920000u, 46u}, // smd -> Latn
- {0xA5920000u, 46u}, // smj -> Latn
- {0xB5920000u, 46u}, // smn -> Latn
- {0xBD920000u, 76u}, // smp -> Samr
- {0xC1920000u, 46u}, // smq -> Latn
- {0xC9920000u, 46u}, // sms -> Latn
- {0x736E0000u, 46u}, // sn -> Latn
- {0x85B20000u, 46u}, // snb -> Latn
- {0x89B20000u, 46u}, // snc -> Latn
- {0xA9B20000u, 46u}, // snk -> Latn
- {0xBDB20000u, 46u}, // snp -> Latn
- {0xDDB20000u, 46u}, // snx -> Latn
- {0xE1B20000u, 46u}, // sny -> Latn
- {0x736F0000u, 46u}, // so -> Latn
- {0x99D20000u, 81u}, // sog -> Sogd
- {0xA9D20000u, 46u}, // sok -> Latn
- {0xC1D20000u, 46u}, // soq -> Latn
- {0xD1D20000u, 93u}, // sou -> Thai
- {0xE1D20000u, 46u}, // soy -> Latn
- {0x8DF20000u, 46u}, // spd -> Latn
- {0xADF20000u, 46u}, // spl -> Latn
- {0xC9F20000u, 46u}, // sps -> Latn
- {0x73710000u, 46u}, // sq -> Latn
- {0x73720000u, 18u}, // sr -> Cyrl
- {0x73724D45u, 46u}, // sr-ME -> Latn
- {0x7372524Fu, 46u}, // sr-RO -> Latn
- {0x73725255u, 46u}, // sr-RU -> Latn
- {0x73725452u, 46u}, // sr-TR -> Latn
- {0x86320000u, 82u}, // srb -> Sora
- {0xB6320000u, 46u}, // srn -> Latn
- {0xC6320000u, 46u}, // srr -> Latn
- {0xDE320000u, 19u}, // srx -> Deva
- {0x73730000u, 46u}, // ss -> Latn
- {0x8E520000u, 46u}, // ssd -> Latn
- {0x9A520000u, 46u}, // ssg -> Latn
- {0xE2520000u, 46u}, // ssy -> Latn
- {0x73740000u, 46u}, // st -> Latn
- {0xAA720000u, 46u}, // stk -> Latn
- {0xC2720000u, 46u}, // stq -> Latn
- {0x73750000u, 46u}, // su -> Latn
- {0x82920000u, 46u}, // sua -> Latn
- {0x92920000u, 46u}, // sue -> Latn
- {0xAA920000u, 46u}, // suk -> Latn
- {0xC6920000u, 46u}, // sur -> Latn
- {0xCA920000u, 46u}, // sus -> Latn
- {0x73760000u, 46u}, // sv -> Latn
- {0x73770000u, 46u}, // sw -> Latn
- {0x86D20000u, 2u}, // swb -> Arab
- {0x8AD20000u, 46u}, // swc -> Latn
- {0x9AD20000u, 46u}, // swg -> Latn
- {0xBED20000u, 46u}, // swp -> Latn
- {0xD6D20000u, 19u}, // swv -> Deva
- {0xB6F20000u, 46u}, // sxn -> Latn
- {0xDAF20000u, 46u}, // sxw -> Latn
- {0xAF120000u, 8u}, // syl -> Beng
- {0xC7120000u, 84u}, // syr -> Syrc
- {0xAF320000u, 46u}, // szl -> Latn
- {0x74610000u, 87u}, // ta -> Taml
- {0xA4130000u, 19u}, // taj -> Deva
- {0xAC130000u, 46u}, // tal -> Latn
- {0xB4130000u, 46u}, // tan -> Latn
- {0xC0130000u, 46u}, // taq -> Latn
- {0x88330000u, 46u}, // tbc -> Latn
- {0x8C330000u, 46u}, // tbd -> Latn
- {0x94330000u, 46u}, // tbf -> Latn
- {0x98330000u, 46u}, // tbg -> Latn
- {0xB8330000u, 46u}, // tbo -> Latn
- {0xD8330000u, 46u}, // tbw -> Latn
- {0xE4330000u, 46u}, // tbz -> Latn
- {0xA0530000u, 46u}, // tci -> Latn
- {0xE0530000u, 42u}, // tcy -> Knda
- {0x8C730000u, 85u}, // tdd -> Tale
- {0x98730000u, 19u}, // tdg -> Deva
- {0x9C730000u, 19u}, // tdh -> Deva
- {0xD0730000u, 46u}, // tdu -> Latn
- {0x74650000u, 90u}, // te -> Telu
- {0x8C930000u, 46u}, // ted -> Latn
- {0xB0930000u, 46u}, // tem -> Latn
- {0xB8930000u, 46u}, // teo -> Latn
- {0xCC930000u, 46u}, // tet -> Latn
- {0xA0B30000u, 46u}, // tfi -> Latn
- {0x74670000u, 18u}, // tg -> Cyrl
- {0x7467504Bu, 2u}, // tg-PK -> Arab
- {0x88D30000u, 46u}, // tgc -> Latn
- {0xB8D30000u, 46u}, // tgo -> Latn
- {0xD0D30000u, 46u}, // tgu -> Latn
- {0x74680000u, 93u}, // th -> Thai
- {0xACF30000u, 19u}, // thl -> Deva
- {0xC0F30000u, 19u}, // thq -> Deva
- {0xC4F30000u, 19u}, // thr -> Deva
- {0x74690000u, 21u}, // ti -> Ethi
- {0x95130000u, 46u}, // tif -> Latn
- {0x99130000u, 21u}, // tig -> Ethi
- {0xA9130000u, 46u}, // tik -> Latn
- {0xB1130000u, 46u}, // tim -> Latn
- {0xB9130000u, 46u}, // tio -> Latn
- {0xD5130000u, 46u}, // tiv -> Latn
- {0x746B0000u, 46u}, // tk -> Latn
- {0xAD530000u, 46u}, // tkl -> Latn
- {0xC5530000u, 46u}, // tkr -> Latn
- {0xCD530000u, 19u}, // tkt -> Deva
- {0x746C0000u, 46u}, // tl -> Latn
- {0x95730000u, 46u}, // tlf -> Latn
- {0xDD730000u, 46u}, // tlx -> Latn
- {0xE1730000u, 46u}, // tly -> Latn
- {0x9D930000u, 46u}, // tmh -> Latn
- {0xE1930000u, 46u}, // tmy -> Latn
- {0x746E0000u, 46u}, // tn -> Latn
- {0x9DB30000u, 46u}, // tnh -> Latn
- {0x746F0000u, 46u}, // to -> Latn
- {0x95D30000u, 46u}, // tof -> Latn
- {0x99D30000u, 46u}, // tog -> Latn
- {0xA9D30000u, 46u}, // tok -> Latn
- {0xC1D30000u, 46u}, // toq -> Latn
- {0xA1F30000u, 46u}, // tpi -> Latn
- {0xB1F30000u, 46u}, // tpm -> Latn
- {0xE5F30000u, 46u}, // tpz -> Latn
- {0xBA130000u, 46u}, // tqo -> Latn
- {0x74720000u, 46u}, // tr -> Latn
- {0xD2330000u, 46u}, // tru -> Latn
- {0xD6330000u, 46u}, // trv -> Latn
- {0xDA330000u, 2u}, // trw -> Arab
- {0x74730000u, 46u}, // ts -> Latn
- {0x8E530000u, 26u}, // tsd -> Grek
- {0x96530000u, 19u}, // tsf -> Deva
- {0x9A530000u, 46u}, // tsg -> Latn
- {0xA6530000u, 94u}, // tsj -> Tibt
- {0xDA530000u, 46u}, // tsw -> Latn
- {0x74740000u, 18u}, // tt -> Cyrl
- {0x8E730000u, 46u}, // ttd -> Latn
- {0x92730000u, 46u}, // tte -> Latn
- {0xA6730000u, 46u}, // ttj -> Latn
- {0xC6730000u, 46u}, // ttr -> Latn
- {0xCA730000u, 93u}, // tts -> Thai
- {0xCE730000u, 46u}, // ttt -> Latn
- {0x9E930000u, 46u}, // tuh -> Latn
- {0xAE930000u, 46u}, // tul -> Latn
- {0xB2930000u, 46u}, // tum -> Latn
- {0xC2930000u, 46u}, // tuq -> Latn
- {0x8EB30000u, 46u}, // tvd -> Latn
- {0xAEB30000u, 46u}, // tvl -> Latn
- {0xD2B30000u, 46u}, // tvu -> Latn
- {0x9ED30000u, 46u}, // twh -> Latn
- {0xC2D30000u, 46u}, // twq -> Latn
- {0x9AF30000u, 88u}, // txg -> Tang
- {0xBAF30000u, 96u}, // txo -> Toto
- {0x74790000u, 46u}, // ty -> Latn
- {0x83130000u, 46u}, // tya -> Latn
- {0xD7130000u, 18u}, // tyv -> Cyrl
- {0xB3330000u, 46u}, // tzm -> Latn
- {0xD0340000u, 46u}, // ubu -> Latn
- {0xA0740000u, 0u}, // udi -> Aghb
- {0xB0740000u, 18u}, // udm -> Cyrl
- {0x75670000u, 2u}, // ug -> Arab
- {0x75674B5Au, 18u}, // ug-KZ -> Cyrl
- {0x75674D4Eu, 18u}, // ug-MN -> Cyrl
- {0x80D40000u, 97u}, // uga -> Ugar
- {0x756B0000u, 18u}, // uk -> Cyrl
- {0xA1740000u, 46u}, // uli -> Latn
- {0x85940000u, 46u}, // umb -> Latn
- {0xC5B40000u, 8u}, // unr -> Beng
- {0xC5B44E50u, 19u}, // unr-NP -> Deva
- {0xDDB40000u, 8u}, // unx -> Beng
- {0xA9D40000u, 46u}, // uok -> Latn
- {0x75720000u, 2u}, // ur -> Arab
- {0xA2340000u, 46u}, // uri -> Latn
- {0xCE340000u, 46u}, // urt -> Latn
- {0xDA340000u, 46u}, // urw -> Latn
- {0x82540000u, 46u}, // usa -> Latn
- {0x9E740000u, 46u}, // uth -> Latn
- {0xC6740000u, 46u}, // utr -> Latn
- {0x9EB40000u, 46u}, // uvh -> Latn
- {0xAEB40000u, 46u}, // uvl -> Latn
- {0x757A0000u, 46u}, // uz -> Latn
- {0x757A4146u, 2u}, // uz-AF -> Arab
- {0x757A434Eu, 18u}, // uz-CN -> Cyrl
- {0x98150000u, 46u}, // vag -> Latn
- {0xA0150000u, 98u}, // vai -> Vaii
- {0xB4150000u, 46u}, // van -> Latn
- {0x76650000u, 46u}, // ve -> Latn
- {0x88950000u, 46u}, // vec -> Latn
- {0xBC950000u, 46u}, // vep -> Latn
- {0x76690000u, 46u}, // vi -> Latn
- {0x89150000u, 46u}, // vic -> Latn
- {0xD5150000u, 46u}, // viv -> Latn
- {0xC9750000u, 46u}, // vls -> Latn
- {0x95950000u, 46u}, // vmf -> Latn
- {0xD9950000u, 46u}, // vmw -> Latn
- {0x766F0000u, 46u}, // vo -> Latn
- {0xCDD50000u, 46u}, // vot -> Latn
- {0xBA350000u, 46u}, // vro -> Latn
- {0xB6950000u, 46u}, // vun -> Latn
- {0xCE950000u, 46u}, // vut -> Latn
- {0x77610000u, 46u}, // wa -> Latn
- {0x90160000u, 46u}, // wae -> Latn
- {0xA4160000u, 46u}, // waj -> Latn
- {0xAC160000u, 21u}, // wal -> Ethi
- {0xB4160000u, 46u}, // wan -> Latn
- {0xC4160000u, 46u}, // war -> Latn
- {0xBC360000u, 46u}, // wbp -> Latn
- {0xC0360000u, 90u}, // wbq -> Telu
- {0xC4360000u, 19u}, // wbr -> Deva
- {0xA0560000u, 46u}, // wci -> Latn
- {0xC4960000u, 46u}, // wer -> Latn
- {0xA0D60000u, 46u}, // wgi -> Latn
- {0x98F60000u, 46u}, // whg -> Latn
- {0x85160000u, 46u}, // wib -> Latn
- {0xD1160000u, 46u}, // wiu -> Latn
- {0xD5160000u, 46u}, // wiv -> Latn
- {0x81360000u, 46u}, // wja -> Latn
- {0xA1360000u, 46u}, // wji -> Latn
- {0xC9760000u, 46u}, // wls -> Latn
- {0xB9960000u, 46u}, // wmo -> Latn
- {0x89B60000u, 46u}, // wnc -> Latn
- {0xA1B60000u, 2u}, // wni -> Arab
- {0xD1B60000u, 46u}, // wnu -> Latn
- {0x776F0000u, 46u}, // wo -> Latn
- {0x85D60000u, 46u}, // wob -> Latn
- {0xC9D60000u, 46u}, // wos -> Latn
- {0xCA360000u, 46u}, // wrs -> Latn
- {0x9A560000u, 23u}, // wsg -> Gong
- {0xAA560000u, 46u}, // wsk -> Latn
- {0xB2760000u, 19u}, // wtm -> Deva
- {0xD2960000u, 29u}, // wuu -> Hans
- {0xD6960000u, 46u}, // wuv -> Latn
- {0x82D60000u, 46u}, // wwa -> Latn
- {0xD4170000u, 46u}, // xav -> Latn
- {0xA0370000u, 46u}, // xbi -> Latn
- {0xB8570000u, 15u}, // xco -> Chrs
- {0xC4570000u, 12u}, // xcr -> Cari
- {0xC8970000u, 46u}, // xes -> Latn
- {0x78680000u, 46u}, // xh -> Latn
- {0x81770000u, 46u}, // xla -> Latn
- {0x89770000u, 50u}, // xlc -> Lyci
- {0x8D770000u, 51u}, // xld -> Lydi
- {0x95970000u, 22u}, // xmf -> Geor
- {0xB5970000u, 53u}, // xmn -> Mani
- {0xC5970000u, 55u}, // xmr -> Merc
- {0x81B70000u, 60u}, // xna -> Narb
- {0xC5B70000u, 19u}, // xnr -> Deva
- {0x99D70000u, 46u}, // xog -> Latn
- {0xB5D70000u, 46u}, // xon -> Latn
- {0xC5F70000u, 73u}, // xpr -> Prti
- {0x86370000u, 46u}, // xrb -> Latn
- {0x82570000u, 77u}, // xsa -> Sarb
- {0xA2570000u, 46u}, // xsi -> Latn
- {0xB2570000u, 46u}, // xsm -> Latn
- {0xC6570000u, 19u}, // xsr -> Deva
- {0x92D70000u, 46u}, // xwe -> Latn
- {0xB0180000u, 46u}, // yam -> Latn
- {0xB8180000u, 46u}, // yao -> Latn
- {0xBC180000u, 46u}, // yap -> Latn
- {0xC8180000u, 46u}, // yas -> Latn
- {0xCC180000u, 46u}, // yat -> Latn
- {0xD4180000u, 46u}, // yav -> Latn
- {0xE0180000u, 46u}, // yay -> Latn
- {0xE4180000u, 46u}, // yaz -> Latn
- {0x80380000u, 46u}, // yba -> Latn
- {0x84380000u, 46u}, // ybb -> Latn
- {0xE0380000u, 46u}, // yby -> Latn
- {0xC4980000u, 46u}, // yer -> Latn
- {0xC4D80000u, 46u}, // ygr -> Latn
- {0xD8D80000u, 46u}, // ygw -> Latn
- {0x79690000u, 31u}, // yi -> Hebr
- {0xB9580000u, 46u}, // yko -> Latn
- {0x91780000u, 46u}, // yle -> Latn
- {0x99780000u, 46u}, // ylg -> Latn
- {0xAD780000u, 46u}, // yll -> Latn
- {0xAD980000u, 46u}, // yml -> Latn
- {0x796F0000u, 46u}, // yo -> Latn
- {0xB5D80000u, 46u}, // yon -> Latn
- {0x86380000u, 46u}, // yrb -> Latn
- {0x92380000u, 46u}, // yre -> Latn
- {0xAE380000u, 46u}, // yrl -> Latn
- {0xCA580000u, 46u}, // yss -> Latn
- {0x82980000u, 46u}, // yua -> Latn
- {0x92980000u, 30u}, // yue -> Hant
- {0x9298434Eu, 29u}, // yue-CN -> Hans
- {0xA6980000u, 46u}, // yuj -> Latn
- {0xCE980000u, 46u}, // yut -> Latn
- {0xDA980000u, 46u}, // yuw -> Latn
- {0x7A610000u, 46u}, // za -> Latn
- {0x98190000u, 46u}, // zag -> Latn
- {0xA4790000u, 2u}, // zdj -> Arab
- {0x80990000u, 46u}, // zea -> Latn
- {0x9CD90000u, 91u}, // zgh -> Tfng
- {0x7A680000u, 29u}, // zh -> Hans
- {0x7A684155u, 30u}, // zh-AU -> Hant
- {0x7A68424Eu, 30u}, // zh-BN -> Hant
- {0x7A684742u, 30u}, // zh-GB -> Hant
- {0x7A684746u, 30u}, // zh-GF -> Hant
- {0x7A68484Bu, 30u}, // zh-HK -> Hant
- {0x7A684944u, 30u}, // zh-ID -> Hant
- {0x7A684D4Fu, 30u}, // zh-MO -> Hant
- {0x7A685041u, 30u}, // zh-PA -> Hant
- {0x7A685046u, 30u}, // zh-PF -> Hant
- {0x7A685048u, 30u}, // zh-PH -> Hant
- {0x7A685352u, 30u}, // zh-SR -> Hant
- {0x7A685448u, 30u}, // zh-TH -> Hant
- {0x7A685457u, 30u}, // zh-TW -> Hant
- {0x7A685553u, 30u}, // zh-US -> Hant
- {0x7A68564Eu, 30u}, // zh-VN -> Hant
- {0xDCF90000u, 62u}, // zhx -> Nshu
- {0x81190000u, 46u}, // zia -> Latn
- {0xCD590000u, 41u}, // zkt -> Kits
- {0xB1790000u, 46u}, // zlm -> Latn
- {0xA1990000u, 46u}, // zmi -> Latn
- {0x91B90000u, 46u}, // zne -> Latn
- {0x7A750000u, 46u}, // zu -> Latn
- {0x83390000u, 46u}, // zza -> Latn
-});
-
-std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({
- 0x616145544C61746ELLU, // aa_Latn_ET
- 0x616247454379726CLLU, // ab_Cyrl_GE
- 0xC42047484C61746ELLU, // abr_Latn_GH
- 0x904049444C61746ELLU, // ace_Latn_ID
- 0x9C4055474C61746ELLU, // ach_Latn_UG
- 0x806047484C61746ELLU, // ada_Latn_GH
- 0xBC60425454696274LLU, // adp_Tibt_BT
- 0xE06052554379726CLLU, // ady_Cyrl_RU
- 0x6165495241767374LLU, // ae_Avst_IR
- 0x8480544E41726162LLU, // aeb_Arab_TN
- 0x61665A414C61746ELLU, // af_Latn_ZA
- 0xC0C0434D4C61746ELLU, // agq_Latn_CM
- 0xB8E0494E41686F6DLLU, // aho_Ahom_IN
- 0xCD20544E41726162LLU, // ajt_Arab_TN
- 0x616B47484C61746ELLU, // ak_Latn_GH
- 0xA940495158737578LLU, // akk_Xsux_IQ
- 0xB560584B4C61746ELLU, // aln_Latn_XK
- 0xCD6052554379726CLLU, // alt_Cyrl_RU
- 0x616D455445746869LLU, // am_Ethi_ET
- 0xB9804E474C61746ELLU, // amo_Latn_NG
- 0x616E45534C61746ELLU, // an_Latn_ES
- 0xB5A04E474C61746ELLU, // ann_Latn_NG
- 0xE5C049444C61746ELLU, // aoz_Latn_ID
- 0x8DE0544741726162LLU, // apd_Arab_TG
- 0x6172454741726162LLU, // ar_Arab_EG
- 0x8A20495241726D69LLU, // arc_Armi_IR
- 0x8A204A4F4E626174LLU, // arc_Nbat_JO
- 0x8A20535950616C6DLLU, // arc_Palm_SY
- 0xB620434C4C61746ELLU, // arn_Latn_CL
- 0xBA20424F4C61746ELLU, // aro_Latn_BO
- 0xC220445A41726162LLU, // arq_Arab_DZ
- 0xCA20534141726162LLU, // ars_Arab_SA
- 0xE2204D4141726162LLU, // ary_Arab_MA
- 0xE620454741726162LLU, // arz_Arab_EG
- 0x6173494E42656E67LLU, // as_Beng_IN
- 0x8240545A4C61746ELLU, // asa_Latn_TZ
- 0x9240555353676E77LLU, // ase_Sgnw_US
- 0xCE4045534C61746ELLU, // ast_Latn_ES
- 0xA66043414C61746ELLU, // atj_Latn_CA
- 0x617652554379726CLLU, // av_Cyrl_RU
- 0x82C0494E44657661LLU, // awa_Deva_IN
- 0x6179424F4C61746ELLU, // ay_Latn_BO
- 0x617A495241726162LLU, // az_Arab_IR
- 0x617A415A4C61746ELLU, // az_Latn_AZ
- 0x626152554379726CLLU, // ba_Cyrl_RU
- 0xAC01504B41726162LLU, // bal_Arab_PK
- 0xB40149444C61746ELLU, // ban_Latn_ID
- 0xBC014E5044657661LLU, // bap_Deva_NP
- 0xC40141544C61746ELLU, // bar_Latn_AT
- 0xC801434D4C61746ELLU, // bas_Latn_CM
- 0xDC01434D42616D75LLU, // bax_Bamu_CM
- 0x882149444C61746ELLU, // bbc_Latn_ID
- 0xA421434D4C61746ELLU, // bbj_Latn_CM
- 0xA04143494C61746ELLU, // bci_Latn_CI
- 0x626542594379726CLLU, // be_Cyrl_BY
- 0xA481534441726162LLU, // bej_Arab_SD
- 0xB0815A4D4C61746ELLU, // bem_Latn_ZM
- 0xD88149444C61746ELLU, // bew_Latn_ID
- 0xE481545A4C61746ELLU, // bez_Latn_TZ
- 0x8CA1434D4C61746ELLU, // bfd_Latn_CM
- 0xC0A1494E54616D6CLLU, // bfq_Taml_IN
- 0xCCA1504B41726162LLU, // bft_Arab_PK
- 0xE0A1494E44657661LLU, // bfy_Deva_IN
- 0x626742474379726CLLU, // bg_Cyrl_BG
- 0x88C1494E44657661LLU, // bgc_Deva_IN
- 0xB4C1504B41726162LLU, // bgn_Arab_PK
- 0xDCC154524772656BLLU, // bgx_Grek_TR
- 0x84E1494E44657661LLU, // bhb_Deva_IN
- 0xA0E1494E44657661LLU, // bhi_Deva_IN
- 0xB8E1494E44657661LLU, // bho_Deva_IN
- 0x626956554C61746ELLU, // bi_Latn_VU
- 0xA90150484C61746ELLU, // bik_Latn_PH
- 0xB5014E474C61746ELLU, // bin_Latn_NG
- 0xA521494E44657661LLU, // bjj_Deva_IN
- 0xB52149444C61746ELLU, // bjn_Latn_ID
- 0xCD21534E4C61746ELLU, // bjt_Latn_SN
- 0xB141434D4C61746ELLU, // bkm_Latn_CM
- 0xD14150484C61746ELLU, // bku_Latn_PH
- 0x816143414C61746ELLU, // bla_Latn_CA
- 0x99614D594C61746ELLU, // blg_Latn_MY
- 0xCD61564E54617674LLU, // blt_Tavt_VN
- 0x626D4D4C4C61746ELLU, // bm_Latn_ML
- 0xC1814D4C4C61746ELLU, // bmq_Latn_ML
- 0x626E424442656E67LLU, // bn_Beng_BD
- 0x626F434E54696274LLU, // bo_Tibt_CN
- 0xE1E1494E42656E67LLU, // bpy_Beng_IN
- 0xA201495241726162LLU, // bqi_Arab_IR
- 0xD60143494C61746ELLU, // bqv_Latn_CI
- 0x627246524C61746ELLU, // br_Latn_FR
- 0x8221494E44657661LLU, // bra_Deva_IN
- 0x9E21504B41726162LLU, // brh_Arab_PK
- 0xDE21494E44657661LLU, // brx_Deva_IN
- 0x627342414C61746ELLU, // bs_Latn_BA
- 0xC2414C5242617373LLU, // bsq_Bass_LR
- 0xCA41434D4C61746ELLU, // bss_Latn_CM
- 0xBA6150484C61746ELLU, // bto_Latn_PH
- 0xD661504B44657661LLU, // btv_Deva_PK
- 0x828152554379726CLLU, // bua_Cyrl_RU
- 0x8A8159544C61746ELLU, // buc_Latn_YT
- 0x9A8149444C61746ELLU, // bug_Latn_ID
- 0xB281434D4C61746ELLU, // bum_Latn_CM
- 0x86A147514C61746ELLU, // bvb_Latn_GQ
- 0xB701455245746869LLU, // byn_Ethi_ER
- 0xD701434D4C61746ELLU, // byv_Latn_CM
- 0x93214D4C4C61746ELLU, // bze_Latn_ML
- 0x636145534C61746ELLU, // ca_Latn_ES
- 0x8C0255534C61746ELLU, // cad_Latn_US
- 0x9C424E474C61746ELLU, // cch_Latn_NG
- 0xBC42424443616B6DLLU, // ccp_Cakm_BD
- 0x636552554379726CLLU, // ce_Cyrl_RU
- 0x848250484C61746ELLU, // ceb_Latn_PH
- 0x98C255474C61746ELLU, // cgg_Latn_UG
- 0x636847554C61746ELLU, // ch_Latn_GU
- 0xA8E2464D4C61746ELLU, // chk_Latn_FM
- 0xB0E252554379726CLLU, // chm_Cyrl_RU
- 0xB8E255534C61746ELLU, // cho_Latn_US
- 0xBCE243414C61746ELLU, // chp_Latn_CA
- 0xC4E2555343686572LLU, // chr_Cher_US
- 0x890255534C61746ELLU, // cic_Latn_US
- 0x81224B4841726162LLU, // cja_Arab_KH
- 0xB122564E4368616DLLU, // cjm_Cham_VN
- 0x8542495141726162LLU, // ckb_Arab_IQ
- 0x896243414C61746ELLU, // clc_Latn_CA
- 0x99824D4E536F796FLLU, // cmg_Soyo_MN
- 0x636F46524C61746ELLU, // co_Latn_FR
- 0xBDC24547436F7074LLU, // cop_Copt_EG
- 0xC9E250484C61746ELLU, // cps_Latn_PH
- 0x6372434143616E73LLU, // cr_Cans_CA
- 0x9A2243414C61746ELLU, // crg_Latn_CA
- 0x9E2255414379726CLLU, // crh_Cyrl_UA
- 0xAA22434143616E73LLU, // crk_Cans_CA
- 0xAE22434143616E73LLU, // crl_Cans_CA
- 0xCA2253434C61746ELLU, // crs_Latn_SC
- 0x6373435A4C61746ELLU, // cs_Latn_CZ
- 0x8642504C4C61746ELLU, // csb_Latn_PL
- 0xDA42434143616E73LLU, // csw_Cans_CA
- 0x8E624D4D50617563LLU, // ctd_Pauc_MM
- 0x637552554379726CLLU, // cu_Cyrl_RU
- 0x63754247476C6167LLU, // cu_Glag_BG
- 0x637652554379726CLLU, // cv_Cyrl_RU
- 0x637947424C61746ELLU, // cy_Latn_GB
- 0x6461444B4C61746ELLU, // da_Latn_DK
- 0x940343494C61746ELLU, // daf_Latn_CI
- 0xA80355534C61746ELLU, // dak_Latn_US
- 0xC40352554379726CLLU, // dar_Cyrl_RU
- 0xD4034B454C61746ELLU, // dav_Latn_KE
- 0x8843494E41726162LLU, // dcc_Arab_IN
- 0x646544454C61746ELLU, // de_Latn_DE
- 0xB48343414C61746ELLU, // den_Latn_CA
- 0xC4C343414C61746ELLU, // dgr_Latn_CA
- 0x91234E454C61746ELLU, // dje_Latn_NE
- 0x95834E474D656466LLU, // dmf_Medf_NG
- 0xA5A343494C61746ELLU, // dnj_Latn_CI
- 0xA1C3494E44657661LLU, // doi_Deva_IN
- 0x9E23434E4D6F6E67LLU, // drh_Mong_CN
- 0x864344454C61746ELLU, // dsb_Latn_DE
- 0xB2634D4C4C61746ELLU, // dtm_Latn_ML
- 0xBE634D594C61746ELLU, // dtp_Latn_MY
- 0xE2634E5044657661LLU, // dty_Deva_NP
- 0x8283434D4C61746ELLU, // dua_Latn_CM
- 0x64764D5654686161LLU, // dv_Thaa_MV
- 0xBB03534E4C61746ELLU, // dyo_Latn_SN
- 0xD30342464C61746ELLU, // dyu_Latn_BF
- 0x647A425454696274LLU, // dz_Tibt_BT
- 0xD0244B454C61746ELLU, // ebu_Latn_KE
- 0x656547484C61746ELLU, // ee_Latn_GH
- 0xA0A44E474C61746ELLU, // efi_Latn_NG
- 0xACC449544C61746ELLU, // egl_Latn_IT
- 0xE0C4454745677970LLU, // egy_Egyp_EG
- 0xE1444D4D4B616C69LLU, // eky_Kali_MM
- 0x656C47524772656BLLU, // el_Grek_GR
- 0x656E47424C61746ELLU, // en_Latn_GB
- 0x656E55534C61746ELLU, // en_Latn_US
- 0x656E474253686177LLU, // en_Shaw_GB
- 0x657345534C61746ELLU, // es_Latn_ES
- 0x65734D584C61746ELLU, // es_Latn_MX
- 0x657355534C61746ELLU, // es_Latn_US
- 0x9A44494E476F6E6DLLU, // esg_Gonm_IN
- 0xD24455534C61746ELLU, // esu_Latn_US
- 0x657445454C61746ELLU, // et_Latn_EE
- 0xCE6449544974616CLLU, // ett_Ital_IT
- 0x657545534C61746ELLU, // eu_Latn_ES
- 0xBAC4434D4C61746ELLU, // ewo_Latn_CM
- 0xCEE445534C61746ELLU, // ext_Latn_ES
- 0x6661495241726162LLU, // fa_Arab_IR
- 0xB40547514C61746ELLU, // fan_Latn_GQ
- 0x6666474E41646C6DLLU, // ff_Adlm_GN
- 0x6666534E4C61746ELLU, // ff_Latn_SN
- 0xB0A54D4C4C61746ELLU, // ffm_Latn_ML
- 0x666946494C61746ELLU, // fi_Latn_FI
- 0x8105534441726162LLU, // fia_Arab_SD
- 0xAD0550484C61746ELLU, // fil_Latn_PH
- 0xCD0553454C61746ELLU, // fit_Latn_SE
- 0x666A464A4C61746ELLU, // fj_Latn_FJ
- 0x666F464F4C61746ELLU, // fo_Latn_FO
- 0xB5C5424A4C61746ELLU, // fon_Latn_BJ
- 0x667246524C61746ELLU, // fr_Latn_FR
- 0x8A2555534C61746ELLU, // frc_Latn_US
- 0xBE2546524C61746ELLU, // frp_Latn_FR
- 0xC62544454C61746ELLU, // frr_Latn_DE
- 0xCA2544454C61746ELLU, // frs_Latn_DE
- 0x8685434D41726162LLU, // fub_Arab_CM
- 0x8E8557464C61746ELLU, // fud_Latn_WF
- 0x9685474E4C61746ELLU, // fuf_Latn_GN
- 0xC2854E454C61746ELLU, // fuq_Latn_NE
- 0xC68549544C61746ELLU, // fur_Latn_IT
- 0xD6854E474C61746ELLU, // fuv_Latn_NG
- 0xC6A553444C61746ELLU, // fvr_Latn_SD
- 0x66794E4C4C61746ELLU, // fy_Latn_NL
- 0x676149454C61746ELLU, // ga_Latn_IE
- 0x800647484C61746ELLU, // gaa_Latn_GH
- 0x98064D444C61746ELLU, // gag_Latn_MD
- 0xB406434E48616E73LLU, // gan_Hans_CN
- 0xE00649444C61746ELLU, // gay_Latn_ID
- 0xB026494E44657661LLU, // gbm_Deva_IN
- 0xE426495241726162LLU, // gbz_Arab_IR
- 0xC44647464C61746ELLU, // gcr_Latn_GF
- 0x676447424C61746ELLU, // gd_Latn_GB
- 0xE486455445746869LLU, // gez_Ethi_ET
- 0xB4C64E5044657661LLU, // ggn_Deva_NP
- 0xAD064B494C61746ELLU, // gil_Latn_KI
- 0xA926504B41726162LLU, // gjk_Arab_PK
- 0xD126504B41726162LLU, // gju_Arab_PK
- 0x676C45534C61746ELLU, // gl_Latn_ES
- 0xA966495241726162LLU, // glk_Arab_IR
- 0x676E50594C61746ELLU, // gn_Latn_PY
- 0xB1C6494E44657661LLU, // gom_Deva_IN
- 0xB5C6494E54656C75LLU, // gon_Telu_IN
- 0xC5C649444C61746ELLU, // gor_Latn_ID
- 0xC9C64E4C4C61746ELLU, // gos_Latn_NL
- 0xCDC65541476F7468LLU, // got_Goth_UA
- 0x8A26435943707274LLU, // grc_Cprt_CY
- 0x8A2647524C696E62LLU, // grc_Linb_GR
- 0xCE26494E42656E67LLU, // grt_Beng_IN
- 0xDA4643484C61746ELLU, // gsw_Latn_CH
- 0x6775494E47756A72LLU, // gu_Gujr_IN
- 0x868642524C61746ELLU, // gub_Latn_BR
- 0x8A86434F4C61746ELLU, // guc_Latn_CO
- 0xC68647484C61746ELLU, // gur_Latn_GH
- 0xE6864B454C61746ELLU, // guz_Latn_KE
- 0x6776494D4C61746ELLU, // gv_Latn_IM
- 0xC6A64E5044657661LLU, // gvr_Deva_NP
- 0xA2C643414C61746ELLU, // gwi_Latn_CA
- 0x68614E474C61746ELLU, // ha_Latn_NG
- 0xA807434E48616E73LLU, // hak_Hans_CN
- 0xD80755534C61746ELLU, // haw_Latn_US
- 0xE407414641726162LLU, // haz_Arab_AF
- 0x6865494C48656272LLU, // he_Hebr_IL
- 0x6869494E44657661LLU, // hi_Deva_IN
- 0x6869494E4C61746ELLU, // hi_Latn_IN
- 0x9507464A4C61746ELLU, // hif_Latn_FJ
- 0xAD0750484C61746ELLU, // hil_Latn_PH
- 0xD1675452486C7577LLU, // hlu_Hluw_TR
- 0x8D87434E506C7264LLU, // hmd_Plrd_CN
- 0x8DA7504B41726162LLU, // hnd_Arab_PK
- 0x91A7494E44657661LLU, // hne_Deva_IN
- 0xA5A75553486D6E70LLU, // hnj_Hmnp_US
- 0xB5A750484C61746ELLU, // hnn_Latn_PH
- 0xB9A7504B41726162LLU, // hno_Arab_PK
- 0x686F50474C61746ELLU, // ho_Latn_PG
- 0x89C7494E44657661LLU, // hoc_Deva_IN
- 0xA5C7494E44657661LLU, // hoj_Deva_IN
- 0x687248524C61746ELLU, // hr_Latn_HR
- 0x864744454C61746ELLU, // hsb_Latn_DE
- 0xB647434E48616E73LLU, // hsn_Hans_CN
- 0x687448544C61746ELLU, // ht_Latn_HT
- 0x687548554C61746ELLU, // hu_Latn_HU
- 0xC68743414C61746ELLU, // hur_Latn_CA
- 0x6879414D41726D6ELLU, // hy_Armn_AM
- 0x687A4E414C61746ELLU, // hz_Latn_NA
- 0x80284D594C61746ELLU, // iba_Latn_MY
- 0x84284E474C61746ELLU, // ibb_Latn_NG
- 0x696449444C61746ELLU, // id_Latn_ID
- 0x90A854474C61746ELLU, // ife_Latn_TG
- 0x69674E474C61746ELLU, // ig_Latn_NG
- 0x6969434E59696969LLU, // ii_Yiii_CN
- 0x696B55534C61746ELLU, // ik_Latn_US
- 0xB96850484C61746ELLU, // ilo_Latn_PH
- 0x696E49444C61746ELLU, // in_Latn_ID
- 0x9DA852554379726CLLU, // inh_Cyrl_RU
- 0x697349534C61746ELLU, // is_Latn_IS
- 0x697449544C61746ELLU, // it_Latn_IT
- 0x6975434143616E73LLU, // iu_Cans_CA
- 0x6977494C48656272LLU, // iw_Hebr_IL
- 0x9F2852554C61746ELLU, // izh_Latn_RU
- 0x6A614A504A70616ELLU, // ja_Jpan_JP
- 0xB0094A4D4C61746ELLU, // jam_Latn_JM
- 0xB8C9434D4C61746ELLU, // jgo_Latn_CM
- 0x8989545A4C61746ELLU, // jmc_Latn_TZ
- 0xAD894E5044657661LLU, // jml_Deva_NP
- 0xCE89444B4C61746ELLU, // jut_Latn_DK
- 0x6A7649444C61746ELLU, // jv_Latn_ID
- 0x6A7749444C61746ELLU, // jw_Latn_ID
- 0x6B61474547656F72LLU, // ka_Geor_GE
- 0x800A555A4379726CLLU, // kaa_Cyrl_UZ
- 0x840A445A4C61746ELLU, // kab_Latn_DZ
- 0x880A4D4D4C61746ELLU, // kac_Latn_MM
- 0xA40A4E474C61746ELLU, // kaj_Latn_NG
- 0xB00A4B454C61746ELLU, // kam_Latn_KE
- 0xB80A4D4C4C61746ELLU, // kao_Latn_ML
- 0xD80A49444B617769LLU, // kaw_Kawi_ID
- 0x8C2A52554379726CLLU, // kbd_Cyrl_RU
- 0xE02A4E4541726162LLU, // kby_Arab_NE
- 0x984A4E474C61746ELLU, // kcg_Latn_NG
- 0xA84A5A574C61746ELLU, // kck_Latn_ZW
- 0x906A545A4C61746ELLU, // kde_Latn_TZ
- 0x9C6A54474C61746ELLU, // kdh_Latn_TG
- 0xCC6A544854686169LLU, // kdt_Thai_TH
- 0x808A43564C61746ELLU, // kea_Latn_CV
- 0xB48A434D4C61746ELLU, // ken_Latn_CM
- 0xB8AA43494C61746ELLU, // kfo_Latn_CI
- 0xC4AA494E44657661LLU, // kfr_Deva_IN
- 0xE0AA494E44657661LLU, // kfy_Deva_IN
- 0x6B6743444C61746ELLU, // kg_Latn_CD
- 0x90CA49444C61746ELLU, // kge_Latn_ID
- 0xBCCA42524C61746ELLU, // kgp_Latn_BR
- 0x80EA494E4C61746ELLU, // kha_Latn_IN
- 0x84EA434E54616C75LLU, // khb_Talu_CN
- 0xB4EA494E44657661LLU, // khn_Deva_IN
- 0xC0EA4D4C4C61746ELLU, // khq_Latn_ML
- 0xCCEA494E4D796D72LLU, // kht_Mymr_IN
- 0xD8EA504B41726162LLU, // khw_Arab_PK
- 0x6B694B454C61746ELLU, // ki_Latn_KE
- 0xD10A54524C61746ELLU, // kiu_Latn_TR
- 0x6B6A4E414C61746ELLU, // kj_Latn_NA
- 0x992A4C414C616F6FLLU, // kjg_Laoo_LA
- 0x6B6B434E41726162LLU, // kk_Arab_CN
- 0x6B6B4B5A4379726CLLU, // kk_Cyrl_KZ
- 0xA54A434D4C61746ELLU, // kkj_Latn_CM
- 0x6B6C474C4C61746ELLU, // kl_Latn_GL
- 0xB56A4B454C61746ELLU, // kln_Latn_KE
- 0x6B6D4B484B686D72LLU, // km_Khmr_KH
- 0x858A414F4C61746ELLU, // kmb_Latn_AO
- 0x6B6E494E4B6E6461LLU, // kn_Knda_IN
- 0x95AA47574C61746ELLU, // knf_Latn_GW
- 0x6B6F4B524B6F7265LLU, // ko_Kore_KR
- 0xA1CA52554379726CLLU, // koi_Cyrl_RU
- 0xA9CA494E44657661LLU, // kok_Deva_IN
- 0xC9CA464D4C61746ELLU, // kos_Latn_FM
- 0x91EA4C524C61746ELLU, // kpe_Latn_LR
- 0x8A2A52554379726CLLU, // krc_Cyrl_RU
- 0xA22A534C4C61746ELLU, // kri_Latn_SL
- 0xA62A50484C61746ELLU, // krj_Latn_PH
- 0xAE2A52554C61746ELLU, // krl_Latn_RU
- 0xD22A494E44657661LLU, // kru_Deva_IN
- 0x6B73494E41726162LLU, // ks_Arab_IN
- 0x864A545A4C61746ELLU, // ksb_Latn_TZ
- 0x964A434D4C61746ELLU, // ksf_Latn_CM
- 0x9E4A44454C61746ELLU, // ksh_Latn_DE
- 0xC66A4D594C61746ELLU, // ktr_Latn_MY
- 0x6B75495141726162LLU, // ku_Arab_IQ
- 0x6B7554524C61746ELLU, // ku_Latn_TR
- 0x6B75474559657A69LLU, // ku_Yezi_GE
- 0xB28A52554379726CLLU, // kum_Cyrl_RU
- 0x6B7652554379726CLLU, // kv_Cyrl_RU
- 0xC6AA49444C61746ELLU, // kvr_Latn_ID
- 0xDEAA504B41726162LLU, // kvx_Arab_PK
- 0x6B7747424C61746ELLU, // kw_Latn_GB
- 0xAACA43414C61746ELLU, // kwk_Latn_CA
- 0xAEEA494E44657661LLU, // kxl_Deva_IN
- 0xB2EA544854686169LLU, // kxm_Thai_TH
- 0xBEEA504B41726162LLU, // kxp_Arab_PK
- 0x6B79434E41726162LLU, // ky_Arab_CN
- 0x6B794B474379726CLLU, // ky_Cyrl_KG
- 0x6B7954524C61746ELLU, // ky_Latn_TR
- 0xA72A4D594C61746ELLU, // kzj_Latn_MY
- 0xCF2A4D594C61746ELLU, // kzt_Latn_MY
- 0x6C6156414C61746ELLU, // la_Latn_VA
- 0x840B47524C696E61LLU, // lab_Lina_GR
- 0x8C0B494C48656272LLU, // lad_Hebr_IL
- 0x980B545A4C61746ELLU, // lag_Latn_TZ
- 0x9C0B504B41726162LLU, // lah_Arab_PK
- 0xA40B55474C61746ELLU, // laj_Latn_UG
- 0x6C624C554C61746ELLU, // lb_Latn_LU
- 0x902B52554379726CLLU, // lbe_Cyrl_RU
- 0xD82B49444C61746ELLU, // lbw_Latn_ID
- 0xBC4B434E54686169LLU, // lcp_Thai_CN
- 0xBC8B494E4C657063LLU, // lep_Lepc_IN
- 0xE48B52554379726CLLU, // lez_Cyrl_RU
- 0x6C6755474C61746ELLU, // lg_Latn_UG
- 0x6C694E4C4C61746ELLU, // li_Latn_NL
- 0x950B4E5044657661LLU, // lif_Deva_NP
- 0x950B494E4C696D62LLU, // lif_Limb_IN
- 0xA50B49544C61746ELLU, // lij_Latn_IT
- 0xAD0B43414C61746ELLU, // lil_Latn_CA
- 0xC90B434E4C697375LLU, // lis_Lisu_CN
- 0xBD2B49444C61746ELLU, // ljp_Latn_ID
- 0xA14B495241726162LLU, // lki_Arab_IR
- 0xCD4B55534C61746ELLU, // lkt_Latn_US
- 0xB58B494E54656C75LLU, // lmn_Telu_IN
- 0xB98B49544C61746ELLU, // lmo_Latn_IT
- 0x6C6E43444C61746ELLU, // ln_Latn_CD
- 0x6C6F4C414C616F6FLLU, // lo_Laoo_LA
- 0xADCB43444C61746ELLU, // lol_Latn_CD
- 0xE5CB5A4D4C61746ELLU, // loz_Latn_ZM
- 0x8A2B495241726162LLU, // lrc_Arab_IR
- 0x6C744C544C61746ELLU, // lt_Latn_LT
- 0x9A6B4C564C61746ELLU, // ltg_Latn_LV
- 0x6C7543444C61746ELLU, // lu_Latn_CD
- 0x828B43444C61746ELLU, // lua_Latn_CD
- 0xBA8B4B454C61746ELLU, // luo_Latn_KE
- 0xE28B4B454C61746ELLU, // luy_Latn_KE
- 0xE68B495241726162LLU, // luz_Arab_IR
- 0x6C764C564C61746ELLU, // lv_Latn_LV
- 0xAECB544854686169LLU, // lwl_Thai_TH
- 0x9F2B434E48616E73LLU, // lzh_Hans_CN
- 0xE72B54524C61746ELLU, // lzz_Latn_TR
- 0x8C0C49444C61746ELLU, // mad_Latn_ID
- 0x940C434D4C61746ELLU, // maf_Latn_CM
- 0x980C494E44657661LLU, // mag_Deva_IN
- 0xA00C494E44657661LLU, // mai_Deva_IN
- 0xA80C49444C61746ELLU, // mak_Latn_ID
- 0xB40C474D4C61746ELLU, // man_Latn_GM
- 0xB40C474E4E6B6F6FLLU, // man_Nkoo_GN
- 0xC80C4B454C61746ELLU, // mas_Latn_KE
- 0xE40C4D584C61746ELLU, // maz_Latn_MX
- 0x946C52554379726CLLU, // mdf_Cyrl_RU
- 0x9C6C50484C61746ELLU, // mdh_Latn_PH
- 0xC46C49444C61746ELLU, // mdr_Latn_ID
- 0xB48C534C4C61746ELLU, // men_Latn_SL
- 0xC48C4B454C61746ELLU, // mer_Latn_KE
- 0x80AC544841726162LLU, // mfa_Arab_TH
- 0x90AC4D554C61746ELLU, // mfe_Latn_MU
- 0x6D674D474C61746ELLU, // mg_Latn_MG
- 0x9CCC4D5A4C61746ELLU, // mgh_Latn_MZ
- 0xB8CC434D4C61746ELLU, // mgo_Latn_CM
- 0xBCCC4E5044657661LLU, // mgp_Deva_NP
- 0xE0CC545A4C61746ELLU, // mgy_Latn_TZ
- 0x6D684D484C61746ELLU, // mh_Latn_MH
- 0x6D694E5A4C61746ELLU, // mi_Latn_NZ
- 0x890C43414C61746ELLU, // mic_Latn_CA
- 0xB50C49444C61746ELLU, // min_Latn_ID
- 0x6D6B4D4B4379726CLLU, // mk_Cyrl_MK
- 0x6D6C494E4D6C796DLLU, // ml_Mlym_IN
- 0xC96C53444C61746ELLU, // mls_Latn_SD
- 0x6D6E4D4E4379726CLLU, // mn_Cyrl_MN
- 0x6D6E434E4D6F6E67LLU, // mn_Mong_CN
- 0xA1AC494E42656E67LLU, // mni_Beng_IN
- 0xD9AC4D4D4D796D72LLU, // mnw_Mymr_MM
- 0x6D6F524F4C61746ELLU, // mo_Latn_RO
- 0x91CC43414C61746ELLU, // moe_Latn_CA
- 0x9DCC43414C61746ELLU, // moh_Latn_CA
- 0xC9CC42464C61746ELLU, // mos_Latn_BF
- 0x6D72494E44657661LLU, // mr_Deva_IN
- 0x8E2C4E5044657661LLU, // mrd_Deva_NP
- 0xA62C52554379726CLLU, // mrj_Cyrl_RU
- 0xBA2C42444D726F6FLLU, // mro_Mroo_BD
- 0x6D734D594C61746ELLU, // ms_Latn_MY
- 0x6D744D544C61746ELLU, // mt_Latn_MT
- 0xC66C494E44657661LLU, // mtr_Deva_IN
- 0x828C434D4C61746ELLU, // mua_Latn_CM
- 0xCA8C55534C61746ELLU, // mus_Latn_US
- 0xE2AC504B41726162LLU, // mvy_Arab_PK
- 0xAACC4D4C4C61746ELLU, // mwk_Latn_ML
- 0xC6CC494E44657661LLU, // mwr_Deva_IN
- 0xD6CC49444C61746ELLU, // mwv_Latn_ID
- 0xDACC5553486D6E70LLU, // mww_Hmnp_US
- 0x8AEC5A574C61746ELLU, // mxc_Latn_ZW
- 0x6D794D4D4D796D72LLU, // my_Mymr_MM
- 0xD70C52554379726CLLU, // myv_Cyrl_RU
- 0xDF0C55474C61746ELLU, // myx_Latn_UG
- 0xE70C49524D616E64LLU, // myz_Mand_IR
- 0xB72C495241726162LLU, // mzn_Arab_IR
- 0x6E614E524C61746ELLU, // na_Latn_NR
- 0xB40D434E48616E73LLU, // nan_Hans_CN
- 0xBC0D49544C61746ELLU, // nap_Latn_IT
- 0xC00D4E414C61746ELLU, // naq_Latn_NA
- 0x6E624E4F4C61746ELLU, // nb_Latn_NO
- 0x9C4D4D584C61746ELLU, // nch_Latn_MX
- 0x6E645A574C61746ELLU, // nd_Latn_ZW
- 0x886D4D5A4C61746ELLU, // ndc_Latn_MZ
- 0xC86D44454C61746ELLU, // nds_Latn_DE
- 0x6E654E5044657661LLU, // ne_Deva_NP
- 0xD88D4E5044657661LLU, // new_Deva_NP
- 0x6E674E414C61746ELLU, // ng_Latn_NA
- 0xACCD4D5A4C61746ELLU, // ngl_Latn_MZ
- 0x90ED4D584C61746ELLU, // nhe_Latn_MX
- 0xD8ED4D584C61746ELLU, // nhw_Latn_MX
- 0xA50D49444C61746ELLU, // nij_Latn_ID
- 0xD10D4E554C61746ELLU, // niu_Latn_NU
- 0xB92D494E4C61746ELLU, // njo_Latn_IN
- 0x6E6C4E4C4C61746ELLU, // nl_Latn_NL
- 0x998D434D4C61746ELLU, // nmg_Latn_CM
- 0x6E6E4E4F4C61746ELLU, // nn_Latn_NO
- 0x9DAD434D4C61746ELLU, // nnh_Latn_CM
- 0xBDAD494E5763686FLLU, // nnp_Wcho_IN
- 0x6E6F4E4F4C61746ELLU, // no_Latn_NO
- 0x8DCD54484C616E61LLU, // nod_Lana_TH
- 0x91CD494E44657661LLU, // noe_Deva_IN
- 0xB5CD534552756E72LLU, // non_Runr_SE
- 0xBA0D474E4E6B6F6FLLU, // nqo_Nkoo_GN
- 0x6E725A414C61746ELLU, // nr_Latn_ZA
- 0xAA4D434143616E73LLU, // nsk_Cans_CA
- 0xBA4D5A414C61746ELLU, // nso_Latn_ZA
- 0xCE4D494E546E7361LLU, // nst_Tnsa_IN
- 0xCA8D53534C61746ELLU, // nus_Latn_SS
- 0x6E7655534C61746ELLU, // nv_Latn_US
- 0xC2ED434E4C61746ELLU, // nxq_Latn_CN
- 0x6E794D574C61746ELLU, // ny_Latn_MW
- 0xB30D545A4C61746ELLU, // nym_Latn_TZ
- 0xB70D55474C61746ELLU, // nyn_Latn_UG
- 0xA32D47484C61746ELLU, // nzi_Latn_GH
- 0x6F6346524C61746ELLU, // oc_Latn_FR
- 0x6F6A434143616E73LLU, // oj_Cans_CA
- 0xC92E434143616E73LLU, // ojs_Cans_CA
- 0x814E43414C61746ELLU, // oka_Latn_CA
- 0x6F6D45544C61746ELLU, // om_Latn_ET
- 0x6F72494E4F727961LLU, // or_Orya_IN
- 0x6F7347454379726CLLU, // os_Cyrl_GE
- 0x824E55534F736765LLU, // osa_Osge_US
- 0xAA6E4D4E4F726B68LLU, // otk_Orkh_MN
- 0xA28E8C814F756772LLU, // oui_Ougr_143
- 0x7061504B41726162LLU, // pa_Arab_PK
- 0x7061494E47757275LLU, // pa_Guru_IN
- 0x980F50484C61746ELLU, // pag_Latn_PH
- 0xAC0F495250686C69LLU, // pal_Phli_IR
- 0xAC0F434E50686C70LLU, // pal_Phlp_CN
- 0xB00F50484C61746ELLU, // pam_Latn_PH
- 0xBC0F41574C61746ELLU, // pap_Latn_AW
- 0xD00F50574C61746ELLU, // pau_Latn_PW
- 0x8C4F46524C61746ELLU, // pcd_Latn_FR
- 0xB04F4E474C61746ELLU, // pcm_Latn_NG
- 0x886F55534C61746ELLU, // pdc_Latn_US
- 0xCC6F43414C61746ELLU, // pdt_Latn_CA
- 0xB88F49525870656FLLU, // peo_Xpeo_IR
- 0xACAF44454C61746ELLU, // pfl_Latn_DE
- 0xB4EF4C4250686E78LLU, // phn_Phnx_LB
- 0xC90F53424C61746ELLU, // pis_Latn_SB
- 0x814F494E42726168LLU, // pka_Brah_IN
- 0xB94F4B454C61746ELLU, // pko_Latn_KE
- 0x706C504C4C61746ELLU, // pl_Latn_PL
- 0xC98F49544C61746ELLU, // pms_Latn_IT
- 0xCDAF47524772656BLLU, // pnt_Grek_GR
- 0xB5CF464D4C61746ELLU, // pon_Latn_FM
- 0x81EF494E44657661LLU, // ppa_Deva_IN
- 0xB20F43414C61746ELLU, // pqm_Latn_CA
- 0x822F504B4B686172LLU, // pra_Khar_PK
- 0x8E2F495241726162LLU, // prd_Arab_IR
- 0x7073414641726162LLU, // ps_Arab_AF
- 0x707442524C61746ELLU, // pt_Latn_BR
- 0xD28F47414C61746ELLU, // puu_Latn_GA
- 0x717550454C61746ELLU, // qu_Latn_PE
- 0x8A9047544C61746ELLU, // quc_Latn_GT
- 0x9A9045434C61746ELLU, // qug_Latn_EC
- 0xA411494E44657661LLU, // raj_Deva_IN
- 0x945152454C61746ELLU, // rcf_Latn_RE
- 0xA49149444C61746ELLU, // rej_Latn_ID
- 0xB4D149544C61746ELLU, // rgn_Latn_IT
- 0x98F14D4D526F6867LLU, // rhg_Rohg_MM
- 0x8111494E4C61746ELLU, // ria_Latn_IN
- 0x95114D4154666E67LLU, // rif_Tfng_MA
- 0xC9314E5044657661LLU, // rjs_Deva_NP
- 0xCD51424442656E67LLU, // rkt_Beng_BD
- 0x726D43484C61746ELLU, // rm_Latn_CH
- 0x959146494C61746ELLU, // rmf_Latn_FI
- 0xB99143484C61746ELLU, // rmo_Latn_CH
- 0xCD91495241726162LLU, // rmt_Arab_IR
- 0xD19153454C61746ELLU, // rmu_Latn_SE
- 0x726E42494C61746ELLU, // rn_Latn_BI
- 0x99B14D5A4C61746ELLU, // rng_Latn_MZ
- 0x726F524F4C61746ELLU, // ro_Latn_RO
- 0x85D149444C61746ELLU, // rob_Latn_ID
- 0x95D1545A4C61746ELLU, // rof_Latn_TZ
- 0xB271464A4C61746ELLU, // rtm_Latn_FJ
- 0x727552554379726CLLU, // ru_Cyrl_RU
- 0x929155414379726CLLU, // rue_Cyrl_UA
- 0x9A9153424C61746ELLU, // rug_Latn_SB
- 0x727752574C61746ELLU, // rw_Latn_RW
- 0xAAD1545A4C61746ELLU, // rwk_Latn_TZ
- 0xD3114A504B616E61LLU, // ryu_Kana_JP
- 0x7361494E44657661LLU, // sa_Deva_IN
- 0x941247484C61746ELLU, // saf_Latn_GH
- 0x9C1252554379726CLLU, // sah_Cyrl_RU
- 0xC0124B454C61746ELLU, // saq_Latn_KE
- 0xC81249444C61746ELLU, // sas_Latn_ID
- 0xCC12494E4F6C636BLLU, // sat_Olck_IN
- 0xD412534E4C61746ELLU, // sav_Latn_SN
- 0xE412494E53617572LLU, // saz_Saur_IN
- 0xBC32545A4C61746ELLU, // sbp_Latn_TZ
- 0x736349544C61746ELLU, // sc_Latn_IT
- 0xA852494E44657661LLU, // sck_Deva_IN
- 0xB45249544C61746ELLU, // scn_Latn_IT
- 0xB85247424C61746ELLU, // sco_Latn_GB
- 0x7364504B41726162LLU, // sd_Arab_PK
- 0x7364494E44657661LLU, // sd_Deva_IN
- 0x7364494E4B686F6ALLU, // sd_Khoj_IN
- 0x7364494E53696E64LLU, // sd_Sind_IN
- 0x887249544C61746ELLU, // sdc_Latn_IT
- 0x9C72495241726162LLU, // sdh_Arab_IR
- 0x73654E4F4C61746ELLU, // se_Latn_NO
- 0x949243494C61746ELLU, // sef_Latn_CI
- 0x9C924D5A4C61746ELLU, // seh_Latn_MZ
- 0xA0924D584C61746ELLU, // sei_Latn_MX
- 0xC8924D4C4C61746ELLU, // ses_Latn_ML
- 0x736743464C61746ELLU, // sg_Latn_CF
- 0x80D249454F67616DLLU, // sga_Ogam_IE
- 0xC8D24C544C61746ELLU, // sgs_Latn_LT
- 0xA0F24D4154666E67LLU, // shi_Tfng_MA
- 0xB4F24D4D4D796D72LLU, // shn_Mymr_MM
- 0x73694C4B53696E68LLU, // si_Sinh_LK
- 0x8D1245544C61746ELLU, // sid_Latn_ET
- 0x736B534B4C61746ELLU, // sk_Latn_SK
- 0xC552504B41726162LLU, // skr_Arab_PK
- 0x736C53494C61746ELLU, // sl_Latn_SI
- 0xA172504C4C61746ELLU, // sli_Latn_PL
- 0xE17249444C61746ELLU, // sly_Latn_ID
- 0x736D57534C61746ELLU, // sm_Latn_WS
- 0x819253454C61746ELLU, // sma_Latn_SE
- 0x8D92414F4C61746ELLU, // smd_Latn_AO
- 0xA59253454C61746ELLU, // smj_Latn_SE
- 0xB59246494C61746ELLU, // smn_Latn_FI
- 0xBD92494C53616D72LLU, // smp_Samr_IL
- 0xC99246494C61746ELLU, // sms_Latn_FI
- 0x736E5A574C61746ELLU, // sn_Latn_ZW
- 0x85B24D594C61746ELLU, // snb_Latn_MY
- 0xA9B24D4C4C61746ELLU, // snk_Latn_ML
- 0x736F534F4C61746ELLU, // so_Latn_SO
- 0x99D2555A536F6764LLU, // sog_Sogd_UZ
- 0xD1D2544854686169LLU, // sou_Thai_TH
- 0x7371414C4C61746ELLU, // sq_Latn_AL
- 0x737252534379726CLLU, // sr_Cyrl_RS
- 0x737252534C61746ELLU, // sr_Latn_RS
- 0x8632494E536F7261LLU, // srb_Sora_IN
- 0xB63253524C61746ELLU, // srn_Latn_SR
- 0xC632534E4C61746ELLU, // srr_Latn_SN
- 0xDE32494E44657661LLU, // srx_Deva_IN
- 0x73735A414C61746ELLU, // ss_Latn_ZA
- 0xE25245524C61746ELLU, // ssy_Latn_ER
- 0x73745A414C61746ELLU, // st_Latn_ZA
- 0xC27244454C61746ELLU, // stq_Latn_DE
- 0x737549444C61746ELLU, // su_Latn_ID
- 0xAA92545A4C61746ELLU, // suk_Latn_TZ
- 0xCA92474E4C61746ELLU, // sus_Latn_GN
- 0x737653454C61746ELLU, // sv_Latn_SE
- 0x7377545A4C61746ELLU, // sw_Latn_TZ
- 0x86D2595441726162LLU, // swb_Arab_YT
- 0x8AD243444C61746ELLU, // swc_Latn_CD
- 0x9AD244454C61746ELLU, // swg_Latn_DE
- 0xD6D2494E44657661LLU, // swv_Deva_IN
- 0xB6F249444C61746ELLU, // sxn_Latn_ID
- 0xAF12424442656E67LLU, // syl_Beng_BD
- 0xC712495153797263LLU, // syr_Syrc_IQ
- 0xAF32504C4C61746ELLU, // szl_Latn_PL
- 0x7461494E54616D6CLLU, // ta_Taml_IN
- 0xA4134E5044657661LLU, // taj_Deva_NP
- 0xD83350484C61746ELLU, // tbw_Latn_PH
- 0xE053494E4B6E6461LLU, // tcy_Knda_IN
- 0x8C73434E54616C65LLU, // tdd_Tale_CN
- 0x98734E5044657661LLU, // tdg_Deva_NP
- 0x9C734E5044657661LLU, // tdh_Deva_NP
- 0xD0734D594C61746ELLU, // tdu_Latn_MY
- 0x7465494E54656C75LLU, // te_Telu_IN
- 0xB093534C4C61746ELLU, // tem_Latn_SL
- 0xB89355474C61746ELLU, // teo_Latn_UG
- 0xCC93544C4C61746ELLU, // tet_Latn_TL
- 0x7467504B41726162LLU, // tg_Arab_PK
- 0x7467544A4379726CLLU, // tg_Cyrl_TJ
- 0x7468544854686169LLU, // th_Thai_TH
- 0xACF34E5044657661LLU, // thl_Deva_NP
- 0xC0F34E5044657661LLU, // thq_Deva_NP
- 0xC4F34E5044657661LLU, // thr_Deva_NP
- 0x7469455445746869LLU, // ti_Ethi_ET
- 0x9913455245746869LLU, // tig_Ethi_ER
- 0xD5134E474C61746ELLU, // tiv_Latn_NG
- 0x746B544D4C61746ELLU, // tk_Latn_TM
- 0xAD53544B4C61746ELLU, // tkl_Latn_TK
- 0xC553415A4C61746ELLU, // tkr_Latn_AZ
- 0xCD534E5044657661LLU, // tkt_Deva_NP
- 0x746C50484C61746ELLU, // tl_Latn_PH
- 0xE173415A4C61746ELLU, // tly_Latn_AZ
- 0x9D934E454C61746ELLU, // tmh_Latn_NE
- 0x746E5A414C61746ELLU, // tn_Latn_ZA
- 0x746F544F4C61746ELLU, // to_Latn_TO
- 0x99D34D574C61746ELLU, // tog_Latn_MW
- 0xA1F350474C61746ELLU, // tpi_Latn_PG
- 0x747254524C61746ELLU, // tr_Latn_TR
- 0xD23354524C61746ELLU, // tru_Latn_TR
- 0xD63354574C61746ELLU, // trv_Latn_TW
- 0xDA33504B41726162LLU, // trw_Arab_PK
- 0x74735A414C61746ELLU, // ts_Latn_ZA
- 0x8E5347524772656BLLU, // tsd_Grek_GR
- 0x96534E5044657661LLU, // tsf_Deva_NP
- 0x9A5350484C61746ELLU, // tsg_Latn_PH
- 0xA653425454696274LLU, // tsj_Tibt_BT
- 0x747452554379726CLLU, // tt_Cyrl_RU
- 0xA67355474C61746ELLU, // ttj_Latn_UG
- 0xCA73544854686169LLU, // tts_Thai_TH
- 0xCE73415A4C61746ELLU, // ttt_Latn_AZ
- 0xB2934D574C61746ELLU, // tum_Latn_MW
- 0xAEB354564C61746ELLU, // tvl_Latn_TV
- 0xC2D34E454C61746ELLU, // twq_Latn_NE
- 0x9AF3434E54616E67LLU, // txg_Tang_CN
- 0xBAF3494E546F746FLLU, // txo_Toto_IN
- 0x747950464C61746ELLU, // ty_Latn_PF
- 0xD71352554379726CLLU, // tyv_Cyrl_RU
- 0xB3334D414C61746ELLU, // tzm_Latn_MA
- 0xA074525541676862LLU, // udi_Aghb_RU
- 0xB07452554379726CLLU, // udm_Cyrl_RU
- 0x7567434E41726162LLU, // ug_Arab_CN
- 0x75674B5A4379726CLLU, // ug_Cyrl_KZ
- 0x80D4535955676172LLU, // uga_Ugar_SY
- 0x756B55414379726CLLU, // uk_Cyrl_UA
- 0xA174464D4C61746ELLU, // uli_Latn_FM
- 0x8594414F4C61746ELLU, // umb_Latn_AO
- 0xC5B4494E42656E67LLU, // unr_Beng_IN
- 0xC5B44E5044657661LLU, // unr_Deva_NP
- 0xDDB4494E42656E67LLU, // unx_Beng_IN
- 0x7572504B41726162LLU, // ur_Arab_PK
- 0x757A414641726162LLU, // uz_Arab_AF
- 0x757A555A4C61746ELLU, // uz_Latn_UZ
- 0xA0154C5256616969LLU, // vai_Vaii_LR
- 0x76655A414C61746ELLU, // ve_Latn_ZA
- 0x889549544C61746ELLU, // vec_Latn_IT
- 0xBC9552554C61746ELLU, // vep_Latn_RU
- 0x7669564E4C61746ELLU, // vi_Latn_VN
- 0x891553584C61746ELLU, // vic_Latn_SX
- 0xC97542454C61746ELLU, // vls_Latn_BE
- 0x959544454C61746ELLU, // vmf_Latn_DE
- 0xD9954D5A4C61746ELLU, // vmw_Latn_MZ
- 0xCDD552554C61746ELLU, // vot_Latn_RU
- 0xBA3545454C61746ELLU, // vro_Latn_EE
- 0xB695545A4C61746ELLU, // vun_Latn_TZ
- 0x776142454C61746ELLU, // wa_Latn_BE
- 0x901643484C61746ELLU, // wae_Latn_CH
- 0xAC16455445746869LLU, // wal_Ethi_ET
- 0xC41650484C61746ELLU, // war_Latn_PH
- 0xBC3641554C61746ELLU, // wbp_Latn_AU
- 0xC036494E54656C75LLU, // wbq_Telu_IN
- 0xC436494E44657661LLU, // wbr_Deva_IN
- 0xC97657464C61746ELLU, // wls_Latn_WF
- 0xA1B64B4D41726162LLU, // wni_Arab_KM
- 0x776F534E4C61746ELLU, // wo_Latn_SN
- 0x9A56494E476F6E67LLU, // wsg_Gong_IN
- 0xB276494E44657661LLU, // wtm_Deva_IN
- 0xD296434E48616E73LLU, // wuu_Hans_CN
- 0xD41742524C61746ELLU, // xav_Latn_BR
- 0xB857555A43687273LLU, // xco_Chrs_UZ
- 0xC457545243617269LLU, // xcr_Cari_TR
- 0x78685A414C61746ELLU, // xh_Latn_ZA
- 0x897754524C796369LLU, // xlc_Lyci_TR
- 0x8D7754524C796469LLU, // xld_Lydi_TR
- 0x9597474547656F72LLU, // xmf_Geor_GE
- 0xB597434E4D616E69LLU, // xmn_Mani_CN
- 0xC59753444D657263LLU, // xmr_Merc_SD
- 0x81B753414E617262LLU, // xna_Narb_SA
- 0xC5B7494E44657661LLU, // xnr_Deva_IN
- 0x99D755474C61746ELLU, // xog_Latn_UG
- 0xC5F7495250727469LLU, // xpr_Prti_IR
- 0x8257594553617262LLU, // xsa_Sarb_YE
- 0xC6574E5044657661LLU, // xsr_Deva_NP
- 0xB8184D5A4C61746ELLU, // yao_Latn_MZ
- 0xBC18464D4C61746ELLU, // yap_Latn_FM
- 0xD418434D4C61746ELLU, // yav_Latn_CM
- 0x8438434D4C61746ELLU, // ybb_Latn_CM
- 0x796F4E474C61746ELLU, // yo_Latn_NG
- 0xAE3842524C61746ELLU, // yrl_Latn_BR
- 0x82984D584C61746ELLU, // yua_Latn_MX
- 0x9298434E48616E73LLU, // yue_Hans_CN
- 0x9298484B48616E74LLU, // yue_Hant_HK
- 0x7A61434E4C61746ELLU, // za_Latn_CN
- 0x981953444C61746ELLU, // zag_Latn_SD
- 0xA4794B4D41726162LLU, // zdj_Arab_KM
- 0x80994E4C4C61746ELLU, // zea_Latn_NL
- 0x9CD94D4154666E67LLU, // zgh_Tfng_MA
- 0x7A685457426F706FLLU, // zh_Bopo_TW
- 0x7A68545748616E62LLU, // zh_Hanb_TW
- 0x7A68434E48616E73LLU, // zh_Hans_CN
- 0x7A68545748616E74LLU, // zh_Hant_TW
- 0xDCF9434E4E736875LLU, // zhx_Nshu_CN
- 0xCD59434E4B697473LLU, // zkt_Kits_CN
- 0xB17954474C61746ELLU, // zlm_Latn_TG
- 0xA1994D594C61746ELLU, // zmi_Latn_MY
- 0x7A755A414C61746ELLU, // zu_Latn_ZA
- 0x833954524C61746ELLU, // zza_Latn_TR
-});
-
-const std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({
- {0x61724145u, 0x61729420u}, // ar-AE -> ar-015
- {0x6172445Au, 0x61729420u}, // ar-DZ -> ar-015
- {0x61724548u, 0x61729420u}, // ar-EH -> ar-015
- {0x61724C59u, 0x61729420u}, // ar-LY -> ar-015
- {0x61724D41u, 0x61729420u}, // ar-MA -> ar-015
- {0x6172544Eu, 0x61729420u}, // ar-TN -> ar-015
-});
-
-const std::unordered_map<uint32_t, uint32_t> DEVA_PARENTS({
- {0x68690000u, 0x656E494Eu}, // hi-Latn -> en-IN
-});
-
-const std::unordered_map<uint32_t, uint32_t> HANT_PARENTS({
- {0x7A684D4Fu, 0x7A68484Bu}, // zh-Hant-MO -> zh-Hant-HK
-});
-
-const std::unordered_map<uint32_t, uint32_t> LATN_PARENTS({
- {0x656E80A1u, 0x656E8400u}, // en-150 -> en-001
- {0x656E4147u, 0x656E8400u}, // en-AG -> en-001
- {0x656E4149u, 0x656E8400u}, // en-AI -> en-001
- {0x656E4154u, 0x656E80A1u}, // en-AT -> en-150
- {0x656E4155u, 0x656E8400u}, // en-AU -> en-001
- {0x656E4242u, 0x656E8400u}, // en-BB -> en-001
- {0x656E4245u, 0x656E80A1u}, // en-BE -> en-150
- {0x656E424Du, 0x656E8400u}, // en-BM -> en-001
- {0x656E4253u, 0x656E8400u}, // en-BS -> en-001
- {0x656E4257u, 0x656E8400u}, // en-BW -> en-001
- {0x656E425Au, 0x656E8400u}, // en-BZ -> en-001
- {0x656E4343u, 0x656E8400u}, // en-CC -> en-001
- {0x656E4348u, 0x656E80A1u}, // en-CH -> en-150
- {0x656E434Bu, 0x656E8400u}, // en-CK -> en-001
- {0x656E434Du, 0x656E8400u}, // en-CM -> en-001
- {0x656E4358u, 0x656E8400u}, // en-CX -> en-001
- {0x656E4359u, 0x656E8400u}, // en-CY -> en-001
- {0x656E4445u, 0x656E80A1u}, // en-DE -> en-150
- {0x656E4447u, 0x656E8400u}, // en-DG -> en-001
- {0x656E444Bu, 0x656E80A1u}, // en-DK -> en-150
- {0x656E444Du, 0x656E8400u}, // en-DM -> en-001
- {0x656E4552u, 0x656E8400u}, // en-ER -> en-001
- {0x656E4649u, 0x656E80A1u}, // en-FI -> en-150
- {0x656E464Au, 0x656E8400u}, // en-FJ -> en-001
- {0x656E464Bu, 0x656E8400u}, // en-FK -> en-001
- {0x656E464Du, 0x656E8400u}, // en-FM -> en-001
- {0x656E4742u, 0x656E8400u}, // en-GB -> en-001
- {0x656E4744u, 0x656E8400u}, // en-GD -> en-001
- {0x656E4747u, 0x656E8400u}, // en-GG -> en-001
- {0x656E4748u, 0x656E8400u}, // en-GH -> en-001
- {0x656E4749u, 0x656E8400u}, // en-GI -> en-001
- {0x656E474Du, 0x656E8400u}, // en-GM -> en-001
- {0x656E4759u, 0x656E8400u}, // en-GY -> en-001
- {0x656E484Bu, 0x656E8400u}, // en-HK -> en-001
- {0x656E4945u, 0x656E8400u}, // en-IE -> en-001
- {0x656E494Cu, 0x656E8400u}, // en-IL -> en-001
- {0x656E494Du, 0x656E8400u}, // en-IM -> en-001
- {0x656E494Eu, 0x656E8400u}, // en-IN -> en-001
- {0x656E494Fu, 0x656E8400u}, // en-IO -> en-001
- {0x656E4A45u, 0x656E8400u}, // en-JE -> en-001
- {0x656E4A4Du, 0x656E8400u}, // en-JM -> en-001
- {0x656E4B45u, 0x656E8400u}, // en-KE -> en-001
- {0x656E4B49u, 0x656E8400u}, // en-KI -> en-001
- {0x656E4B4Eu, 0x656E8400u}, // en-KN -> en-001
- {0x656E4B59u, 0x656E8400u}, // en-KY -> en-001
- {0x656E4C43u, 0x656E8400u}, // en-LC -> en-001
- {0x656E4C52u, 0x656E8400u}, // en-LR -> en-001
- {0x656E4C53u, 0x656E8400u}, // en-LS -> en-001
- {0x656E4D47u, 0x656E8400u}, // en-MG -> en-001
- {0x656E4D4Fu, 0x656E8400u}, // en-MO -> en-001
- {0x656E4D53u, 0x656E8400u}, // en-MS -> en-001
- {0x656E4D54u, 0x656E8400u}, // en-MT -> en-001
- {0x656E4D55u, 0x656E8400u}, // en-MU -> en-001
- {0x656E4D56u, 0x656E8400u}, // en-MV -> en-001
- {0x656E4D57u, 0x656E8400u}, // en-MW -> en-001
- {0x656E4D59u, 0x656E8400u}, // en-MY -> en-001
- {0x656E4E41u, 0x656E8400u}, // en-NA -> en-001
- {0x656E4E46u, 0x656E8400u}, // en-NF -> en-001
- {0x656E4E47u, 0x656E8400u}, // en-NG -> en-001
- {0x656E4E4Cu, 0x656E80A1u}, // en-NL -> en-150
- {0x656E4E52u, 0x656E8400u}, // en-NR -> en-001
- {0x656E4E55u, 0x656E8400u}, // en-NU -> en-001
- {0x656E4E5Au, 0x656E8400u}, // en-NZ -> en-001
- {0x656E5047u, 0x656E8400u}, // en-PG -> en-001
- {0x656E504Bu, 0x656E8400u}, // en-PK -> en-001
- {0x656E504Eu, 0x656E8400u}, // en-PN -> en-001
- {0x656E5057u, 0x656E8400u}, // en-PW -> en-001
- {0x656E5257u, 0x656E8400u}, // en-RW -> en-001
- {0x656E5342u, 0x656E8400u}, // en-SB -> en-001
- {0x656E5343u, 0x656E8400u}, // en-SC -> en-001
- {0x656E5344u, 0x656E8400u}, // en-SD -> en-001
- {0x656E5345u, 0x656E80A1u}, // en-SE -> en-150
- {0x656E5347u, 0x656E8400u}, // en-SG -> en-001
- {0x656E5348u, 0x656E8400u}, // en-SH -> en-001
- {0x656E5349u, 0x656E80A1u}, // en-SI -> en-150
- {0x656E534Cu, 0x656E8400u}, // en-SL -> en-001
- {0x656E5353u, 0x656E8400u}, // en-SS -> en-001
- {0x656E5358u, 0x656E8400u}, // en-SX -> en-001
- {0x656E535Au, 0x656E8400u}, // en-SZ -> en-001
- {0x656E5443u, 0x656E8400u}, // en-TC -> en-001
- {0x656E544Bu, 0x656E8400u}, // en-TK -> en-001
- {0x656E544Fu, 0x656E8400u}, // en-TO -> en-001
- {0x656E5454u, 0x656E8400u}, // en-TT -> en-001
- {0x656E5456u, 0x656E8400u}, // en-TV -> en-001
- {0x656E545Au, 0x656E8400u}, // en-TZ -> en-001
- {0x656E5547u, 0x656E8400u}, // en-UG -> en-001
- {0x656E5643u, 0x656E8400u}, // en-VC -> en-001
- {0x656E5647u, 0x656E8400u}, // en-VG -> en-001
- {0x656E5655u, 0x656E8400u}, // en-VU -> en-001
- {0x656E5753u, 0x656E8400u}, // en-WS -> en-001
- {0x656E5A41u, 0x656E8400u}, // en-ZA -> en-001
- {0x656E5A4Du, 0x656E8400u}, // en-ZM -> en-001
- {0x656E5A57u, 0x656E8400u}, // en-ZW -> en-001
- {0x65734152u, 0x6573A424u}, // es-AR -> es-419
- {0x6573424Fu, 0x6573A424u}, // es-BO -> es-419
- {0x65734252u, 0x6573A424u}, // es-BR -> es-419
- {0x6573425Au, 0x6573A424u}, // es-BZ -> es-419
- {0x6573434Cu, 0x6573A424u}, // es-CL -> es-419
- {0x6573434Fu, 0x6573A424u}, // es-CO -> es-419
- {0x65734352u, 0x6573A424u}, // es-CR -> es-419
- {0x65734355u, 0x6573A424u}, // es-CU -> es-419
- {0x6573444Fu, 0x6573A424u}, // es-DO -> es-419
- {0x65734543u, 0x6573A424u}, // es-EC -> es-419
- {0x65734754u, 0x6573A424u}, // es-GT -> es-419
- {0x6573484Eu, 0x6573A424u}, // es-HN -> es-419
- {0x65734D58u, 0x6573A424u}, // es-MX -> es-419
- {0x65734E49u, 0x6573A424u}, // es-NI -> es-419
- {0x65735041u, 0x6573A424u}, // es-PA -> es-419
- {0x65735045u, 0x6573A424u}, // es-PE -> es-419
- {0x65735052u, 0x6573A424u}, // es-PR -> es-419
- {0x65735059u, 0x6573A424u}, // es-PY -> es-419
- {0x65735356u, 0x6573A424u}, // es-SV -> es-419
- {0x65735553u, 0x6573A424u}, // es-US -> es-419
- {0x65735559u, 0x6573A424u}, // es-UY -> es-419
- {0x65735645u, 0x6573A424u}, // es-VE -> es-419
- {0x6E620000u, 0x6E6F0000u}, // nb -> no
- {0x6E6E0000u, 0x6E6F0000u}, // nn -> no
- {0x7074414Fu, 0x70745054u}, // pt-AO -> pt-PT
- {0x70744348u, 0x70745054u}, // pt-CH -> pt-PT
- {0x70744356u, 0x70745054u}, // pt-CV -> pt-PT
- {0x70744751u, 0x70745054u}, // pt-GQ -> pt-PT
- {0x70744757u, 0x70745054u}, // pt-GW -> pt-PT
- {0x70744C55u, 0x70745054u}, // pt-LU -> pt-PT
- {0x70744D4Fu, 0x70745054u}, // pt-MO -> pt-PT
- {0x70744D5Au, 0x70745054u}, // pt-MZ -> pt-PT
- {0x70745354u, 0x70745054u}, // pt-ST -> pt-PT
- {0x7074544Cu, 0x70745054u}, // pt-TL -> pt-PT
-});
-
-const std::unordered_map<uint32_t, uint32_t> ___B_PARENTS({
- {0x61725842u, 0x61729420u}, // ar-XB -> ar-015
-});
-
-const struct {
- const char script[4];
- const std::unordered_map<uint32_t, uint32_t>* map;
-} SCRIPT_PARENTS[] = {
- {{'L', 'a', 't', 'n'}, &LATN_PARENTS},
- {{'A', 'r', 'a', 'b'}, &ARAB_PARENTS},
- {{'D', 'e', 'v', 'a'}, &DEVA_PARENTS},
- {{'H', 'a', 'n', 't'}, &HANT_PARENTS},
- {{'~', '~', '~', 'B'}, &___B_PARENTS},
-};
-
-const size_t MAX_PARENT_DEPTH = 3;
diff --git a/libs/androidfw/OWNERS b/libs/androidfw/OWNERS
index ef4cc46cb1c8..47b2a1e9a54f 100644
--- a/libs/androidfw/OWNERS
+++ b/libs/androidfw/OWNERS
@@ -3,4 +3,4 @@ zyy@google.com
patb@google.com
per-file CursorWindow.cpp=omakoto@google.com
-per-file LocaleDataTables.cpp=vichang@google.com,ngeoffray@google.com
+per-file LocaleDataLookup.cpp=vichang@google.com,ngeoffray@google.com
diff --git a/libs/androidfw/include/androidfw/LocaleDataLookup.h b/libs/androidfw/include/androidfw/LocaleDataLookup.h
new file mode 100644
index 000000000000..5a24e832bda1
--- /dev/null
+++ b/libs/androidfw/include/androidfw/LocaleDataLookup.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+namespace android {
+
+constexpr size_t SCRIPT_LENGTH = 4;
+
+constexpr inline uint32_t packLocale(const char* language, const char* region) {
+ const unsigned char* lang = reinterpret_cast<const unsigned char*>(language);
+ const unsigned char* reg = reinterpret_cast<const unsigned char*>(region);
+ return (static_cast<uint32_t>(lang[0]) << 24u) |
+ (static_cast<uint32_t>(lang[1]) << 16u) |
+ (static_cast<uint32_t>(reg[0]) << 8u) |
+ static_cast<uint32_t>(reg[1]);
+}
+
+constexpr inline uint32_t dropRegion(uint32_t packed_locale) {
+ return packed_locale & 0xFFFF0000LU;
+}
+
+constexpr inline bool hasRegion(uint32_t packed_locale) {
+ return (packed_locale & 0x0000FFFFLU) != 0;
+}
+
+constexpr inline uint32_t packScript(const char* script) {
+ const unsigned char* s = reinterpret_cast<const unsigned char*>(script);
+ return ((static_cast<uint32_t>(s[0]) << 24u) |
+ (static_cast<uint32_t>(s[1]) << 16u) |
+ (static_cast<uint32_t>(s[2]) << 8u) |
+ static_cast<uint32_t>(s[3]));
+}
+
+/**
+ * Return nullptr if the key isn't found. The input packed_lang_region can be computed
+ * by android::packLocale.
+ * Note that the returned char* is either nullptr or 4-byte char seqeuence, but isn't
+ * a null-terminated string.
+ */
+const char* lookupLikelyScript(uint32_t packed_lang_region);
+/**
+ * Return false if the key isn't representative. The input lookup key can be computed
+ * by android::packLocale.
+ */
+bool isLocaleRepresentative(uint32_t language_and_region, const char* script);
+
+/**
+ * Return a parent packed key for a given script and child packed key. Return 0 if
+ * no parent is found.
+ */
+uint32_t findParentLocalePackedKey(const char* script, uint32_t packed_lang_region);
+
+uint32_t getMaxAncestorTreeDepth();
+
+} // namespace android
diff --git a/libs/androidfw/tests/LocaleDataLookup_bench.cpp b/libs/androidfw/tests/LocaleDataLookup_bench.cpp
new file mode 100644
index 000000000000..60ce3b944551
--- /dev/null
+++ b/libs/androidfw/tests/LocaleDataLookup_bench.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "benchmark/benchmark.h"
+
+#include "androidfw/LocaleDataLookup.h"
+
+namespace android {
+
+static void BM_LocaleDataLookupIsLocaleRepresentative(benchmark::State& state) {
+ for (auto&& _ : state) {
+ isLocaleRepresentative(packLocale("en", "US"), "Latn");
+ isLocaleRepresentative(packLocale("es", "ES"), "Latn");
+ isLocaleRepresentative(packLocale("zh", "CN"), "Hans");
+ isLocaleRepresentative(packLocale("pt", "BR"), "Latn");
+ isLocaleRepresentative(packLocale("ar", "EG"), "Arab");
+ isLocaleRepresentative(packLocale("hi", "IN"), "Deva");
+ isLocaleRepresentative(packLocale("jp", "JP"), "Jpan");
+ }
+}
+BENCHMARK(BM_LocaleDataLookupIsLocaleRepresentative);
+
+static void BM_LocaleDataLookupLikelyScript(benchmark::State& state) {
+ for (auto&& _ : state) {
+ lookupLikelyScript(packLocale("en", ""));
+ lookupLikelyScript(packLocale("es", ""));
+ lookupLikelyScript(packLocale("zh", ""));
+ lookupLikelyScript(packLocale("pt", ""));
+ lookupLikelyScript(packLocale("ar", ""));
+ lookupLikelyScript(packLocale("hi", ""));
+ lookupLikelyScript(packLocale("jp", ""));
+ lookupLikelyScript(packLocale("en", "US"));
+ lookupLikelyScript(packLocale("es", "ES"));
+ lookupLikelyScript(packLocale("zh", "CN"));
+ lookupLikelyScript(packLocale("pt", "BR"));
+ lookupLikelyScript(packLocale("ar", "EG"));
+ lookupLikelyScript(packLocale("hi", "IN"));
+ lookupLikelyScript(packLocale("jp", "JP"));
+ }
+}
+BENCHMARK(BM_LocaleDataLookupLikelyScript);
+
+
+} // namespace android
diff --git a/libs/androidfw/tests/LocaleDataLookup_test.cpp b/libs/androidfw/tests/LocaleDataLookup_test.cpp
new file mode 100644
index 000000000000..26b220d63169
--- /dev/null
+++ b/libs/androidfw/tests/LocaleDataLookup_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "androidfw/LocaleDataLookup.h"
+
+#include <cstddef>
+#include <string>
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+
+namespace android {
+
+constexpr const char NULL_SCRIPT[4] = {'\0', '\0', '\0','\0' };
+
+#define EXPECT_SCEIPT_EQ(ex, s) EXPECT_EQ(0, s == nullptr ? -1 : memcmp(ex, s, 4))
+
+// Similar to packLanguageOrRegion() in ResourceTypes.cpp
+static uint32_t encodeLanguageOrRegionLiteral(const char* in, const char base) {
+ size_t len = strlen(in);
+ if (len <= 1) {
+ return 0;
+ }
+
+ if (len == 2) {
+ return (((uint8_t) in[0]) << 8) | ((uint8_t) in[1]);
+ }
+ uint8_t first = (in[0] - base) & 0x007f;
+ uint8_t second = (in[1] - base) & 0x007f;
+ uint8_t third = (in[2] - base) & 0x007f;
+
+ return ((uint8_t) (0x80 | (third << 2) | (second >> 3)) << 8) | ((second << 5) | first);
+}
+
+static uint32_t encodeLocale(const char* language, const char* region) {
+ return (encodeLanguageOrRegionLiteral(language, 'a') << 16) |
+ encodeLanguageOrRegionLiteral(region, '0');
+}
+
+TEST(LocaleDataLookupTest, lookupLikelyScript) {
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("", "")));
+ EXPECT_SCEIPT_EQ("Latn", lookupLikelyScript(encodeLocale("en", "")));
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("en", "US")));
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("en", "GB")));
+ EXPECT_SCEIPT_EQ("Latn", lookupLikelyScript(encodeLocale("fr", "")));
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("fr", "FR")));
+
+
+ EXPECT_SCEIPT_EQ("~~~A", lookupLikelyScript(encodeLocale("en", "XA")));
+ EXPECT_SCEIPT_EQ("Latn", lookupLikelyScript(encodeLocale("ha", "")));
+ EXPECT_SCEIPT_EQ("Arab", lookupLikelyScript(encodeLocale("ha", "SD")));
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("ha", "Sd"))); // case sensitive
+ EXPECT_SCEIPT_EQ("Hans", lookupLikelyScript(encodeLocale("zh", "")));
+ EXPECT_EQ(nullptr, lookupLikelyScript(encodeLocale("zh", "CN")));
+ EXPECT_SCEIPT_EQ("Hant", lookupLikelyScript(encodeLocale("zh", "HK")));
+
+ EXPECT_SCEIPT_EQ("Nshu", lookupLikelyScript(encodeLocale("zhx", "")));
+ EXPECT_SCEIPT_EQ("Nshu", lookupLikelyScript(0xDCF90000u)); // encoded "zhx"
+}
+
+TEST(LocaleDataLookupTest, isLocaleRepresentative) {
+ EXPECT_TRUE(isLocaleRepresentative(encodeLocale("en", "US"), "Latn"));
+ EXPECT_TRUE(isLocaleRepresentative(encodeLocale("en", "GB"), "Latn"));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("en", "US"), NULL_SCRIPT));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("en", ""), "Latn"));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("en", ""), NULL_SCRIPT));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("en", "US"), "Arab"));
+
+ EXPECT_TRUE(isLocaleRepresentative(encodeLocale("fr", "FR"), "Latn"));
+
+ EXPECT_TRUE(isLocaleRepresentative(encodeLocale("zh", "CN"), "Hans"));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("zh", "TW"), "Hans"));
+ EXPECT_FALSE(isLocaleRepresentative(encodeLocale("zhx", "CN"), "Hans"));
+ EXPECT_FALSE(isLocaleRepresentative(0xDCF9434E, "Hans"));
+ EXPECT_TRUE(isLocaleRepresentative(encodeLocale("zhx", "CN"), "Nshu"));
+ EXPECT_TRUE(isLocaleRepresentative(0xDCF9434E, "Nshu"));
+}
+
+TEST(LocaleDataLookupTest, findParentLocalePackedKey) {
+ EXPECT_EQ(encodeLocale("en", "001"), findParentLocalePackedKey("Latn", encodeLocale("en", "GB")));
+ EXPECT_EQ(0x656E8400u, findParentLocalePackedKey("Latn", encodeLocale("en", "GB")));
+
+ EXPECT_EQ(encodeLocale("en", "IN"), findParentLocalePackedKey("Deva", encodeLocale("hi", "")));
+
+ EXPECT_EQ(encodeLocale("ar", "015"), findParentLocalePackedKey("Arab", encodeLocale("ar", "AE")));
+ EXPECT_EQ(0x61729420u, findParentLocalePackedKey("Arab", encodeLocale("ar", "AE")));
+
+ EXPECT_EQ(encodeLocale("ar", "015"), findParentLocalePackedKey("~~~B", encodeLocale("ar", "XB")));
+ EXPECT_EQ(0x61729420u, findParentLocalePackedKey("Arab", encodeLocale("ar", "AE")));
+
+ EXPECT_EQ(encodeLocale("zh", "HK"), findParentLocalePackedKey("Hant", encodeLocale("zh", "MO")));
+}
+
+} // namespace android
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index e2db2c9e3827..850e7c1aebb1 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -203,6 +203,9 @@ java_sdk_library {
visibility: [
"//frameworks/base", // Framework
],
+ impl_library_visibility: [
+ "//frameworks/base/ravenwood",
+ ],
srcs: [
":framework-graphics-srcs",
@@ -227,6 +230,14 @@ java_sdk_library {
}
filegroup {
+ name: "framework-graphics-ravenwood-policies",
+ srcs: [
+ "framework-graphics-ravenwood-policies.txt",
+ ],
+ visibility: ["//frameworks/base/ravenwood"],
+}
+
+filegroup {
name: "framework-graphics-srcs",
srcs: [
"apex/java/**/*.java",
diff --git a/libs/hwui/OWNERS b/libs/hwui/OWNERS
index bc174599a4d3..9c06fd5f0225 100644
--- a/libs/hwui/OWNERS
+++ b/libs/hwui/OWNERS
@@ -3,8 +3,7 @@
alecmouri@google.com
djsollen@google.com
jreck@google.com
-njawad@google.com
-scroggo@google.com
+nscobie@google.com
sumir@google.com
# For text, e.g. Typeface, Font, Minikin, etc.
diff --git a/libs/hwui/framework-graphics-ravenwood-policies.txt b/libs/hwui/framework-graphics-ravenwood-policies.txt
new file mode 100644
index 000000000000..7296225ccfe8
--- /dev/null
+++ b/libs/hwui/framework-graphics-ravenwood-policies.txt
@@ -0,0 +1 @@
+class android.graphics.ColorMatrix keepclass
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index cb3753822035..c31d0be74cb6 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -312,7 +312,7 @@ private:
};
// Need at least 4 because we do quad buffer. Add a few more for good measure.
- RingBuffer<SwapHistory, 7> mSwapHistory;
+ RingBuffer<SwapHistory, 8> mSwapHistory;
// Frame numbers start at 1, 0 means uninitialized
uint64_t mFrameNumber = 0;
int64_t mDamageId = 0;
diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h
index 859cc57dea9f..4c9656792dac 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.h
+++ b/libs/hwui/renderthread/HintSessionWrapper.h
@@ -20,6 +20,7 @@
#include <private/performance_hint_private.h>
#include <future>
+#include <memory>
#include <optional>
#include <vector>
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 715153b5083d..77879cf992b7 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -206,7 +206,7 @@ void RenderProxy::buildLayer(RenderNode* node) {
}
bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
- ATRACE_NAME("TextureView#getBitmap");
+ ATRACE_NAME("RenderProxy#copyLayerInto readback");
auto& thread = RenderThread::getInstance();
return thread.queue().runSync([&]() -> bool {
return thread.readback().copyLayerInto(layer, &bitmap) == CopyResult::Success;
@@ -473,7 +473,7 @@ void RenderProxy::prepareToDraw(Bitmap& bitmap) {
}
int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
- ATRACE_NAME("HardwareBitmap readback");
+ ATRACE_NAME("RenderProxy#copyHWBitmapInto readback");
RenderThread& thread = RenderThread::getInstance();
if (RenderThread::isCurrent()) {
// TODO: fix everything that hits this. We should never be triggering a readback ourselves.
@@ -485,6 +485,7 @@ int RenderProxy::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) {
}
int RenderProxy::copyImageInto(const sk_sp<SkImage>& image, SkBitmap* bitmap) {
+ ATRACE_NAME("RenderProxy#copyImageInto readback");
RenderThread& thread = RenderThread::getInstance();
if (RenderThread::isCurrent()) {
// TODO: fix everything that hits this. We should never be triggering a readback ourselves.
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 6571d92aeafa..a67aea466c1c 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -729,7 +729,7 @@ VulkanManager::VkDrawResult VulkanManager::finishFrame(SkSurface* surface) {
VkSemaphore semaphore;
VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore);
ALOGE_IF(VK_SUCCESS != err,
- "VulkanManager::makeSwapSemaphore(): Failed to create semaphore");
+ "VulkanManager::finishFrame(): Failed to create semaphore");
if (err == VK_SUCCESS) {
sharedSemaphore = sp<SharedSemaphoreInfo>::make(mDestroySemaphore, mDevice, semaphore);
@@ -777,7 +777,7 @@ VulkanManager::VkDrawResult VulkanManager::finishFrame(SkSurface* surface) {
int fenceFd = -1;
VkResult err = mGetSemaphoreFdKHR(mDevice, &getFdInfo, &fenceFd);
- ALOGE_IF(VK_SUCCESS != err, "VulkanManager::swapBuffers(): Failed to get semaphore Fd");
+ ALOGE_IF(VK_SUCCESS != err, "VulkanManager::finishFrame(): Failed to get semaphore Fd");
drawResult.presentFence.reset(fenceFd);
} else {
ALOGE("VulkanManager::finishFrame(): Semaphore submission failed");
diff --git a/libs/protoutil/Android.bp b/libs/protoutil/Android.bp
index 8af4b7e8f4c8..4fecf4de0312 100644
--- a/libs/protoutil/Android.bp
+++ b/libs/protoutil/Android.bp
@@ -59,7 +59,6 @@ cc_library {
apex_available: [
"//apex_available:platform",
"com.android.os.statsd",
- "test_com.android.os.statsd",
"com.android.uprobestats",
],
}
diff --git a/location/Android.bp b/location/Android.bp
index bc02d1f852de..80556a2376bf 100644
--- a/location/Android.bp
+++ b/location/Android.bp
@@ -42,6 +42,7 @@ java_sdk_library {
"FlaggedApi",
],
},
+ jarjar_prefix: "com.android.internal.hidden_from_bootclasspath",
}
platform_compat_config {
diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java
index cdde7c66e268..9746dab4151c 100644
--- a/location/java/android/location/Geocoder.java
+++ b/location/java/android/location/Geocoder.java
@@ -83,8 +83,11 @@ public final class Geocoder {
* succeed.
*/
public static boolean isPresent() {
- ILocationManager lm = Objects.requireNonNull(ILocationManager.Stub.asInterface(
- ServiceManager.getService(Context.LOCATION_SERVICE)));
+ ILocationManager lm = ILocationManager.Stub.asInterface(
+ ServiceManager.getService(Context.LOCATION_SERVICE));
+ if (lm == null) {
+ return false;
+ }
try {
return lm.isGeocodeAvailable();
} catch (RemoteException e) {
diff --git a/media/OWNERS b/media/OWNERS
index 5e391959b663..50995ea6de58 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -18,5 +18,4 @@ wonsik@google.com
include platform/frameworks/av:/media/janitors/media_solutions_OWNERS
# SEA/KIR/BVE
-jtinker@google.com
robertshih@google.com
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index e52e0b16eca3..6a21496f1165 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -1,7 +1,10 @@
{
"presubmit": [
{
- "name": "CtsMediaBetterTogetherTestCases"
+ "name": "CtsMediaRouterTestCases"
+ },
+ {
+ "name": "CtsMediaSessionTestCases"
},
{
"name": "mediaroutertest"
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 23f87abaffed..b8259ef45de4 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2037,9 +2037,10 @@ public class ExifInterface {
// Ignore exceptions in order to keep the compatibility with the old versions of
// ExifInterface.
mIsSupportedFile = false;
- Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file"
- + "(ExifInterface supports JPEG and some RAW image formats only) "
- + "or a corrupted JPEG file to ExifInterface.", e);
+ Log.d(
+ TAG,
+ "Invalid image: ExifInterface got an unsupported or corrupted image file",
+ e);
} finally {
addDefaultValuesForCompatibility();
diff --git a/media/java/android/media/FadeManagerConfiguration.java b/media/java/android/media/FadeManagerConfiguration.java
index 6d84e7066839..b91a5b57ac6b 100644
--- a/media/java/android/media/FadeManagerConfiguration.java
+++ b/media/java/android/media/FadeManagerConfiguration.java
@@ -673,6 +673,7 @@ public final class FadeManagerConfiguration implements Parcelable {
return config != null ? config.getDuration() : DURATION_NOT_SET;
}
+ @Nullable
private VolumeShaper.Configuration getVolumeShaperConfigFromWrapper(
FadeVolumeShaperConfigsWrapper wrapper, boolean isFadeIn) {
// if no volume shaper config is available, return null
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index d6fe68253be6..486063ed5f6b 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -180,6 +180,15 @@ public abstract class Image implements AutoCloseable {
* a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
* </td>
* </tr>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#YCBCR_P210 YCBCR_P210}</td>
+ * <td>3</td>
+ * <td>P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed by a WxH Cb and Cr planes. Each sample is represented by a 16-bit
+ * little-endian value, with the lower 6 bits set to zero. Since this is guaranteed to be
+ * a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
+ * </td>
+ * </tr>
* </table>
*
* @see android.graphics.ImageFormat
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index c7678067f0b5..7c6ba838b24f 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -56,6 +56,7 @@ class ImageUtils {
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:
case ImageFormat.YCBCR_P010:
+ case ImageFormat.YCBCR_P210:
return 3;
case ImageFormat.NV16:
return 2;
@@ -95,6 +96,7 @@ class ImageUtils {
switch(hardwareBufferFormat) {
case HardwareBuffer.YCBCR_420_888:
case HardwareBuffer.YCBCR_P010:
+ case HardwareBuffer.YCBCR_P210:
return 3;
case HardwareBuffer.RGBA_8888:
case HardwareBuffer.RGBX_8888:
@@ -281,6 +283,7 @@ class ImageUtils {
case PixelFormat.RGBA_8888:
case PixelFormat.RGBX_8888:
case PixelFormat.RGBA_1010102:
+ case ImageFormat.YCBCR_P210:
estimatedBytePerPixel = 4.0;
break;
default:
@@ -335,6 +338,12 @@ class ImageUtils {
return new Size(image.getWidth(), image.getHeight());
case ImageFormat.PRIVATE:
return new Size(0, 0);
+ case ImageFormat.YCBCR_P210:
+ if (planeIdx == 0) {
+ return new Size(image.getWidth(), image.getHeight());
+ } else {
+ return new Size(image.getWidth() / 2, image.getHeight());
+ }
default:
if (Log.isLoggable(IMAGEUTILS_LOG_TAG, Log.VERBOSE)) {
Log.v(IMAGEUTILS_LOG_TAG, "getEffectivePlaneSizeForImage() uses"
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 82e950365850..0bea5a98afff 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -44,6 +44,7 @@ import android.os.IHwBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
+import android.os.Trace;
import android.view.Surface;
import java.io.IOException;
@@ -3103,6 +3104,7 @@ final public class MediaCodec {
int index,
int offset, int size, long presentationTimeUs, int flags)
throws CryptoException {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueInputBuffer#java");
if ((flags & BUFFER_FLAG_DECODE_ONLY) != 0
&& (flags & BUFFER_FLAG_END_OF_STREAM) != 0) {
throw new InvalidBufferFlagsException(EOS_AND_DECODE_ONLY_ERROR_MESSAGE);
@@ -3122,6 +3124,8 @@ final public class MediaCodec {
} catch (CryptoException | IllegalStateException e) {
revalidateByteBuffer(mCachedInputBuffers, index, true /* input */);
throw e;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
}
}
@@ -3163,6 +3167,7 @@ final public class MediaCodec {
public final void queueInputBuffers(
int index,
@NonNull ArrayDeque<BufferInfo> bufferInfos) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueInputBuffers#java");
synchronized(mBufferLock) {
if (mBufferMode == BUFFER_MODE_BLOCK) {
throw new IncompatibleWithBlockModelException("queueInputBuffers() "
@@ -3178,6 +3183,8 @@ final public class MediaCodec {
} catch (CryptoException | IllegalStateException | IllegalArgumentException e) {
revalidateByteBuffer(mCachedInputBuffers, index, true /* input */);
throw e;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
}
}
@@ -3438,6 +3445,7 @@ final public class MediaCodec {
@NonNull CryptoInfo info,
long presentationTimeUs,
int flags) throws CryptoException {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueSecureInputBuffer#java");
if ((flags & BUFFER_FLAG_DECODE_ONLY) != 0
&& (flags & BUFFER_FLAG_END_OF_STREAM) != 0) {
throw new InvalidBufferFlagsException(EOS_AND_DECODE_ONLY_ERROR_MESSAGE);
@@ -3457,6 +3465,8 @@ final public class MediaCodec {
} catch (CryptoException | IllegalStateException e) {
revalidateByteBuffer(mCachedInputBuffers, index, true /* input */);
throw e;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
}
}
@@ -3487,6 +3497,7 @@ final public class MediaCodec {
int index,
@NonNull ArrayDeque<BufferInfo> bufferInfos,
@NonNull ArrayDeque<CryptoInfo> cryptoInfos) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueSecureInputBuffers#java");
synchronized(mBufferLock) {
if (mBufferMode == BUFFER_MODE_BLOCK) {
throw new IncompatibleWithBlockModelException("queueSecureInputBuffers() "
@@ -3502,6 +3513,8 @@ final public class MediaCodec {
} catch (CryptoException | IllegalStateException | IllegalArgumentException e) {
revalidateByteBuffer(mCachedInputBuffers, index, true /* input */);
throw e;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
}
}
@@ -3529,6 +3542,7 @@ final public class MediaCodec {
* @throws MediaCodec.CodecException upon codec error.
*/
public final int dequeueInputBuffer(long timeoutUs) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::dequeueInputBuffer#java");
synchronized (mBufferLock) {
if (mBufferMode == BUFFER_MODE_BLOCK) {
throw new IncompatibleWithBlockModelException("dequeueInputBuffer() "
@@ -3542,6 +3556,7 @@ final public class MediaCodec {
validateInputByteBufferLocked(mCachedInputBuffers, res);
}
}
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
return res;
}
@@ -4039,6 +4054,7 @@ final public class MediaCodec {
* Finish building a queue request and queue the buffers with tunings.
*/
public void queue() {
+ Trace.traceBegin(Trace.TRACE_TAG_VIDEO, "MediaCodec::queueRequest-queue#java");
if (!isAccessible()) {
throw new IllegalStateException("The request is stale");
}
@@ -4067,6 +4083,7 @@ final public class MediaCodec {
mTuningKeys, mTuningValues);
}
clear();
+ Trace.traceEnd(Trace.TRACE_TAG_VIDEO);
}
@NonNull QueueRequest clear() {
@@ -5866,19 +5883,31 @@ final public class MediaCodec {
@NonNull MediaCodec codec, @NonNull MediaFormat format);
/**
- * Called when the metrics for this codec have been flushed due to the
- * start of a new subsession.
+ * Called when the metrics for this codec have been flushed "mid-stream"
+ * due to the start of a new subsession during execution.
* <p>
- * This can happen when the codec is reconfigured after stop(), or
- * mid-stream e.g. if the video size changes. When this happens, the
- * metrics for the previous subsession are flushed, and
- * {@link MediaCodec#getMetrics} will return the metrics for the
- * new subsession. This happens just before the {@link Callback#onOutputFormatChanged}
+ * A new codec subsession normally starts when the codec is reconfigured
+ * after stop(), but it can also happen mid-stream e.g. if the video size
+ * changes. When this happens, the metrics for the previous subsession
+ * are flushed, and {@link MediaCodec#getMetrics} will return the metrics
+ * for the new subsession.
+ * <p>
+ * For subsessions that begin due to a reconfiguration, the metrics for
+ * the prior subsession can be retrieved via {@link MediaCodec#getMetrics}
+ * prior to calling {@link #configure}.
+ * <p>
+ * When a new subsession begins "mid-stream", the metrics for the prior
+ * subsession are flushed just before the {@link Callback#onOutputFormatChanged}
* event, so this <b>optional</b> callback is provided to be able to
* capture the final metrics for the previous subsession.
*
* @param codec The MediaCodec object.
- * @param metrics The flushed metrics for this codec.
+ * @param metrics The flushed metrics for this codec. This is a
+ * {@link PersistableBundle} containing the set of
+ * attributes and values available for the media being
+ * handled by this instance of MediaCodec. The attributes
+ * are described in {@link MetricsConstants}. Additional
+ * vendor-specific fields may also be present.
*/
@FlaggedApi(FLAG_SUBSESSION_METRICS)
public void onMetricsFlushed(
@@ -6158,11 +6187,14 @@ final public class MediaCodec {
buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
+ (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
- if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010)
+ if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
&& ix == 1) {
cbPlaneOffset = planeOffset;
} else if ((mFormat == ImageFormat.YUV_420_888
- || mFormat == ImageFormat.YCBCR_P010) && ix == 2) {
+ || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
+ && ix == 2) {
crPlaneOffset = planeOffset;
}
}
@@ -6172,7 +6204,7 @@ final public class MediaCodec {
}
// Validate chroma semiplanerness.
- if (mFormat == ImageFormat.YCBCR_P010) {
+ if (mFormat == ImageFormat.YCBCR_P010 || mFormat == ImageFormat.YCBCR_P210) {
if (crPlaneOffset != cbPlaneOffset + planeOffsetInc) {
throw new UnsupportedOperationException("Invalid plane offsets"
+ " cbPlaneOffset: " + cbPlaneOffset + " crPlaneOffset: " + crPlaneOffset);
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 302969f58ba8..9bb31d0076c9 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -908,13 +908,13 @@ public final class MediaCodecInfo {
/** @hide */
public String[] validFeatures() {
Feature[] features = getValidFeatures();
- String[] res = new String[features.length];
- for (int i = 0; i < res.length; i++) {
+ ArrayList<String> res = new ArrayList();
+ for (int i = 0; i < features.length; i++) {
if (!features[i].mInternal) {
- res[i] = features[i].mName;
+ res.add(features[i].mName);
}
}
- return res;
+ return res.toArray(new String[0]);
}
private Feature[] getValidFeatures() {
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index b11a81047bf8..4e1d472688ea 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -375,6 +375,9 @@ public final class MediaExtractor {
/**
* Extract DRM initialization data if it exists
*
+ * <p>If the media contains a PSSH box, only PSSH version 0 is supported. The result for media
+ * with other PSSH versions is undefined.
+ *
* @return DRM initialization data in the content, or {@code null}
* if no recognizable DRM format is found;
* @see DrmInitData
@@ -460,6 +463,10 @@ public final class MediaExtractor {
/**
* Get the PSSH info if present.
+ *
+ * <p>This method only supports version 0 PSSH boxes. The result for other versions is
+ * undefined.
+ *
* @return a map of uuid-to-bytes, with the uuid specifying
* the crypto scheme, and the bytes being the data specific to that scheme.
* This can be {@code null} if the source does not contain PSSH info.
diff --git a/media/java/android/media/OWNERS b/media/java/android/media/OWNERS
index 8cc42e0bd9b5..a600017119e2 100644
--- a/media/java/android/media/OWNERS
+++ b/media/java/android/media/OWNERS
@@ -1,6 +1,7 @@
# Bug component: 1344
-fgoldfain@google.com
+pshehane@google.com
elaurent@google.com
+etalvala@google.com
lajos@google.com
jmtrivi@google.com
@@ -15,4 +16,5 @@ per-file ExifInterface.java,ExifInterfaceUtils.java,IMediaHTTPConnection.aidl,IM
# Haptics team also works on Ringtone
per-file *Ringtone* = file:/services/core/java/com/android/server/vibrator/OWNERS
+per-file flags/media_better_together.aconfig = file:platform/frameworks/av:/media/janitors/better_together_OWNERS
per-file flags/projection.aconfig = file:projection/OWNERS
diff --git a/media/java/android/media/musicrecognition/OWNERS b/media/java/android/media/musicrecognition/OWNERS
index 037b04831260..820be004efd5 100644
--- a/media/java/android/media/musicrecognition/OWNERS
+++ b/media/java/android/media/musicrecognition/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 830636
oni@google.com
-volnov@google.com
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 371b47fe3421..22f4182ee37b 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -155,11 +155,6 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is
* created.
* <p>
@@ -283,16 +278,16 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
* current user.
* <p>
* Although this API can be used without any restriction, each session owners can accept or
* reject your uses of {@link MediaSession2}.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*
* @return A list of {@link Session2Token}.
*/
@@ -417,12 +412,12 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*
* @param listener The listener to add
*/
@@ -433,12 +428,12 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*
* @param listener The listener to add
* @param handler The handler to call listener on.
@@ -451,16 +446,16 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
* <p>
* The calling application needs to hold the
* {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission in order to
* add listeners for user ids that do not belong to current process.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*
* @param userHandle The userHandle to listen for changes on
* @param listener The listener to add
@@ -496,12 +491,12 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Removes the {@link OnSession2TokensChangedListener} to stop receiving session token updates.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*
* @param listener The listener to remove.
*/
@@ -1061,13 +1056,13 @@ public final class MediaSessionManager {
}
/**
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
- * Library</a> for consistent behavior across all devices.
- * <p>
* Listens for changes to the {@link #getSession2Tokens()}. This can be added
* using {@link #addOnSession2TokensChangedListener(OnSession2TokensChangedListener, Handler)}.
+ * <p>
+ * This API is not generally intended for third party application developers. Apps wanting media
+ * session functionality should use the
+ * <a href="{@docRoot}reference/androidx/media3/session/package-summary.html">AndroidX Media3
+ * Session Library</a>.
*/
public interface OnSession2TokensChangedListener {
/**
diff --git a/media/java/android/mtp/OWNERS b/media/java/android/mtp/OWNERS
index 77ed08b1f9a5..c57265a91eff 100644
--- a/media/java/android/mtp/OWNERS
+++ b/media/java/android/mtp/OWNERS
@@ -1,9 +1,9 @@
set noparent
-anothermark@google.com
+vmartensson@google.com
+nkapron@google.com
febinthattil@google.com
-aprasath@google.com
+shubhankarm@google.com
jsharkey@android.com
jameswei@google.com
rmojumder@google.com
-kumarashishg@google.com
diff --git a/media/jni/OWNERS b/media/jni/OWNERS
index e12d828733fa..84618a35cd4f 100644
--- a/media/jni/OWNERS
+++ b/media/jni/OWNERS
@@ -1,8 +1,8 @@
# extra for MTP related files
-per-file android_mtp_*.cpp=aprasath@google.com,anothermark@google.com,kumarashishg@google.com,sarup@google.com,jsharkey@android.com,jameswei@google.com,rmojumder@google.com
+per-file android_mtp_*.cpp=aprasath@google.com,anothermark@google.com,sarup@google.com,jsharkey@android.com,jameswei@google.com,rmojumder@google.com
# extra for TV related files
per-file android_media_tv_*=hgchen@google.com,quxiangfang@google.com
-per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.java=set noparent
-per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.java=file:platform/frameworks/av:/media/janitors/media_solutions_OWNERS
+per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.cpp=set noparent
+per-file android_media_JetPlayer.cpp,android_media_MediaDataSource.cpp,android_media_MediaDataSource.h,android_media_MediaPlayer.cpp=file:platform/frameworks/av:/media/janitors/media_solutions_OWNERS
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index fc184fe5c872..ae54c18eb135 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -16,7 +16,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaCodec-JNI"
+#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
+#include <utils/Trace.h>
#include <type_traits>
@@ -1149,9 +1151,9 @@ status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject names
static jobject getJavaResources(
JNIEnv *env,
- const std::vector<MediaCodec::InstanceResourceInfo>& resources) {
+ const std::vector<InstanceResourceInfo>& resources) {
jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
- for (const MediaCodec::InstanceResourceInfo& res : resources) {
+ for (const InstanceResourceInfo& res : resources) {
ScopedLocalRef<jobject> object{env, env->NewObject(
gInstanceResourceInfo.clazz, gInstanceResourceInfo.ctorId)};
ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -1169,7 +1171,7 @@ static jobject getJavaResources(
}
status_t JMediaCodec::getRequiredResources(JNIEnv *env, jobject *resourcesObj) {
- std::vector<MediaCodec::InstanceResourceInfo> resources;
+ std::vector<InstanceResourceInfo> resources;
status_t status = mCodec->getRequiredResources(resources);
if (status != OK) {
return status;
@@ -1230,63 +1232,73 @@ static void AMessageToCryptoInfo(JNIEnv * env, const jobject & obj,
sp<ABuffer> ivBuffer;
CryptoPlugin::Mode mode;
CryptoPlugin::Pattern pattern;
- CHECK(msg->findInt32("mode", (int*)&mode));
- CHECK(msg->findSize("numSubSamples", &numSubSamples));
- CHECK(msg->findBuffer("subSamples", &subSamplesBuffer));
- CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
- CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
- CHECK(msg->findBuffer("iv", &ivBuffer));
- CHECK(msg->findBuffer("key", &keyBuffer));
-
- // subsamples
+ CryptoPlugin::SubSample *samplesArray = nullptr;
+ ScopedLocalRef<jbyteArray> keyArray(env, env->NewByteArray(16));
+ ScopedLocalRef<jbyteArray> ivArray(env, env->NewByteArray(16));
+ jboolean isCopy;
+ sp<RefBase> cryptoInfosObj;
+ if (msg->findObject("cryptoInfos", &cryptoInfosObj)) {
+ sp<CryptoInfosWrapper> cryptoInfos((CryptoInfosWrapper*)cryptoInfosObj.get());
+ CHECK(!cryptoInfos->value.empty() && (cryptoInfos->value[0] != nullptr));
+ std::unique_ptr<CodecCryptoInfo> &info = cryptoInfos->value[0];
+ mode = info->mMode;
+ numSubSamples = info->mNumSubSamples;
+ samplesArray = info->mSubSamples;
+ pattern = info->mPattern;
+ if (info->mKey != nullptr) {
+ jbyte * dstKey = env->GetByteArrayElements(keyArray.get(), &isCopy);
+ memcpy(dstKey, info->mKey, 16);
+ env->ReleaseByteArrayElements(keyArray.get(), dstKey, 0);
+ }
+ if (info->mIv != nullptr) {
+ jbyte * dstIv = env->GetByteArrayElements(ivArray.get(), &isCopy);
+ memcpy(dstIv, info->mIv, 16);
+ env->ReleaseByteArrayElements(ivArray.get(), dstIv, 0);
+ }
+ } else {
+ CHECK(msg->findInt32("mode", (int*)&mode));
+ CHECK(msg->findSize("numSubSamples", &numSubSamples));
+ CHECK(msg->findBuffer("subSamples", &subSamplesBuffer));
+ CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
+ CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
+ CHECK(msg->findBuffer("iv", &ivBuffer));
+ CHECK(msg->findBuffer("key", &keyBuffer));
+ samplesArray =
+ (CryptoPlugin::SubSample*)(subSamplesBuffer.get()->data());
+ if (keyBuffer.get() != nullptr && keyBuffer->size() > 0) {
+ jbyte * dstKey = env->GetByteArrayElements(keyArray.get(), &isCopy);
+ memcpy(dstKey, keyBuffer->data(), keyBuffer->size());
+ env->ReleaseByteArrayElements(keyArray.get(), dstKey, 0);
+ }
+ if (ivBuffer.get() != nullptr && ivBuffer->size() > 0) {
+ jbyte * dstIv = env->GetByteArrayElements(ivArray.get(), &isCopy);
+ memcpy(dstIv, ivBuffer->data(), ivBuffer->size());
+ env->ReleaseByteArrayElements(ivArray.get(), dstIv, 0);
+ }
+ }
ScopedLocalRef<jintArray> samplesOfEncryptedDataArr(env, env->NewIntArray(numSubSamples));
ScopedLocalRef<jintArray> samplesOfClearDataArr(env, env->NewIntArray(numSubSamples));
- jboolean isCopy;
- jint *dstEncryptedSamples =
- env->GetIntArrayElements(samplesOfEncryptedDataArr.get(), &isCopy);
- jint * dstClearSamples =
- env->GetIntArrayElements(samplesOfClearDataArr.get(), &isCopy);
-
- CryptoPlugin::SubSample * samplesArray =
- (CryptoPlugin::SubSample*)(subSamplesBuffer.get()->data());
-
- for(int i = 0 ; i < numSubSamples ; i++) {
- dstEncryptedSamples[i] = samplesArray[i].mNumBytesOfEncryptedData;
- dstClearSamples[i] = samplesArray[i].mNumBytesOfClearData;
- }
- env->ReleaseIntArrayElements(samplesOfEncryptedDataArr.get(), dstEncryptedSamples, 0);
- env->ReleaseIntArrayElements(samplesOfClearDataArr.get(), dstClearSamples, 0);
- // key and iv
- jbyteArray keyArray = NULL;
- jbyteArray ivArray = NULL;
- if (keyBuffer.get() != nullptr && keyBuffer->size() > 0) {
- keyArray = env->NewByteArray(keyBuffer->size());
- jbyte * dstKey = env->GetByteArrayElements(keyArray, &isCopy);
- memcpy(dstKey, keyBuffer->data(), keyBuffer->size());
- env->ReleaseByteArrayElements(keyArray,dstKey,0);
- }
- if (ivBuffer.get() != nullptr && ivBuffer->size() > 0) {
- ivArray = env->NewByteArray(ivBuffer->size());
- jbyte *dstIv = env->GetByteArrayElements(ivArray, &isCopy);
- memcpy(dstIv, ivBuffer->data(), ivBuffer->size());
- env->ReleaseByteArrayElements(ivArray, dstIv,0);
- }
- // set samples, key and iv
+ if (numSubSamples > 0) {
+ jint *dstEncryptedSamples =
+ env->GetIntArrayElements(samplesOfEncryptedDataArr.get(), &isCopy);
+ jint * dstClearSamples =
+ env->GetIntArrayElements(samplesOfClearDataArr.get(), &isCopy);
+ for(int i = 0 ; i < numSubSamples ; i++) {
+ dstEncryptedSamples[i] = samplesArray[i].mNumBytesOfEncryptedData;
+ dstClearSamples[i] = samplesArray[i].mNumBytesOfClearData;
+ }
+ env->ReleaseIntArrayElements(samplesOfEncryptedDataArr.get(), dstEncryptedSamples, 0);
+ env->ReleaseIntArrayElements(samplesOfClearDataArr.get(), dstClearSamples, 0);
+ }
env->CallVoidMethod(
obj,
gFields.cryptoInfoSetID,
(jint)numSubSamples,
samplesOfClearDataArr.get(),
samplesOfEncryptedDataArr.get(),
- keyArray,
- ivArray,
+ keyArray.get(),
+ ivArray.get(),
mode);
- if (keyArray != NULL) {
- env->DeleteLocalRef(keyArray);
- }
- if (ivArray != NULL) {
- env->DeleteLocalRef(ivArray);
- }
// set pattern
env->CallVoidMethod(
obj,
@@ -2106,7 +2118,7 @@ static void android_media_MediaCodec_queueInputBuffer(
jlong timestampUs,
jint flags) {
ALOGV("android_media_MediaCodec_queueInputBuffer");
-
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueInputBuffer#jni");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
if (codec == NULL || codec->initCheck() != OK) {
@@ -2192,6 +2204,7 @@ static void android_media_MediaCodec_queueInputBuffers(
jint index,
jobjectArray objArray) {
ALOGV("android_media_MediaCodec_queueInputBuffers");
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueInputBuffers#jni");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
if (codec == NULL || codec->initCheck() != OK || objArray == NULL) {
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
@@ -2431,6 +2444,7 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
jobject cryptoInfoObj,
jlong timestampUs,
jint flags) {
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueSecureInputBuffer#jni");
ALOGV("android_media_MediaCodec_queueSecureInputBuffer");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -2641,6 +2655,7 @@ static void android_media_MediaCodec_queueSecureInputBuffers(
jint index,
jobjectArray bufferInfosObjs,
jobjectArray cryptoInfoObjs) {
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueSecureInputBuffers#jni");
ALOGV("android_media_MediaCodec_queueSecureInputBuffers");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -2685,6 +2700,7 @@ static void android_media_MediaCodec_queueSecureInputBuffers(
}
static jobject android_media_MediaCodec_mapHardwareBuffer(JNIEnv *env, jclass, jobject bufferObj) {
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::mapHardwareBuffer#jni");
ALOGV("android_media_MediaCodec_mapHardwareBuffer");
AHardwareBuffer *hardwareBuffer = android_hardware_HardwareBuffer_getNativeHardwareBuffer(
env, bufferObj);
@@ -2974,11 +2990,16 @@ static void extractMemoryFromContext(
}
*memory = context->toHidlMemory();
}
- if (context->mBlock == nullptr || context->mReadWriteMapping == nullptr) {
- ALOGW("extractMemoryFromContext: Cannot extract memory as C2Block is not created/mapped");
+ if (context->mBlock == nullptr) {
+ // this should be ok as we may only have IMemory/hidlMemory
+ // e.g. video codecs may only have IMemory and no mBlock
return;
}
- if (context->mReadWriteMapping->error() != C2_OK) {
+
+ // if we have mBlock and memory, then we will copy data from mBlock to hidlMemory
+ // e.g. audio codecs may only have mBlock and wanted to decrypt using hidlMemory
+ // and also wanted to re-use mBlock
+ if (context->mReadWriteMapping == nullptr || context->mReadWriteMapping->error() != C2_OK) {
ALOGW("extractMemoryFromContext: failed to map C2Block (%d)",
context->mReadWriteMapping->error());
return;
@@ -3028,6 +3049,7 @@ static void extractBufferFromContext(
static void android_media_MediaCodec_native_queueLinearBlock(
JNIEnv *env, jobject thiz, jint index, jobject bufferObj,
jobjectArray cryptoInfoArray, jobjectArray objArray, jobject keys, jobject values) {
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueLinearBlock#jni");
ALOGV("android_media_MediaCodec_native_queueLinearBlock");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -3145,6 +3167,7 @@ static void android_media_MediaCodec_native_queueHardwareBuffer(
JNIEnv *env, jobject thiz, jint index, jobject bufferObj,
jlong presentationTimeUs, jint flags, jobject keys, jobject values) {
ALOGV("android_media_MediaCodec_native_queueHardwareBuffer");
+ ScopedTrace trace(ATRACE_TAG, "MediaCodec::queueHardwareBuffer#jni");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -3615,9 +3638,9 @@ static void android_media_MediaCodec_unsubscribeFromVendorParameters(
static jobject getJavaResources(
JNIEnv *env,
- const std::vector<MediaCodec::GlobalResourceInfo>& resources) {
+ const std::vector<GlobalResourceInfo>& resources) {
jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
- for (const MediaCodec::GlobalResourceInfo& res : resources) {
+ for (const GlobalResourceInfo& res : resources) {
ScopedLocalRef<jobject> object{env, env->NewObject(
gGlobalResourceInfo.clazz, gGlobalResourceInfo.ctorId)};
ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
@@ -3633,7 +3656,7 @@ static jobject getJavaResources(
static jobject android_media_MediaCodec_getGloballyAvailableResources(
JNIEnv *env, jobject thiz) {
(void)thiz;
- std::vector<MediaCodec::GlobalResourceInfo> resources;
+ std::vector<GlobalResourceInfo> resources;
status_t status = MediaCodec::getGloballyAvailableResources(resources);
if (status != OK) {
if (status == ERROR_UNSUPPORTED) {
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index fbebbdcb8761..e8f8644a4503 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -17,13 +17,14 @@
// #define LOG_NDEBUG 0
#define LOG_TAG "AndroidMediaUtils"
+#include "android_media_Utils.h"
+
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/GraphicTypes.h>
#include <utils/Log.h>
-#include "android_media_Utils.h"
-
#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
// Must be in sync with the value in HeicCompositeStream.cpp
@@ -33,6 +34,8 @@ namespace android {
// -----------Utility functions used by ImageReader/Writer JNI-----------------
+using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
+
enum {
IMAGE_MAX_NUM_PLANES = 3,
};
@@ -74,6 +77,7 @@ bool isPossiblyYUV(PixelFormat format) {
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
return false;
case HAL_PIXEL_FORMAT_YV12:
@@ -105,6 +109,7 @@ bool isPossibly10BitYUV(PixelFormat format) {
return false;
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
default:
return true;
}
@@ -340,6 +345,47 @@ status_t getLockedImageInfo(LockedImage* buffer, int idx,
cb = buffer->data + ySize;
cr = cb + 2;
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
+ dataSize = (idx == 0) ? ySize : cSize;
+ rStride = buffer->stride * 2;
+ break;
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
+ if (buffer->height % 2 != 0) {
+ ALOGE("YCBCR_P210: height (%d) should be a multiple of 2", buffer->height);
+ return BAD_VALUE;
+ }
+
+ if (buffer->width <= 0) {
+ ALOGE("YCBCR_P210: width (%d) should be a > 0", buffer->width);
+ return BAD_VALUE;
+ }
+
+ if (buffer->height <= 0) {
+ ALOGE("YCBCR_210: height (%d) should be a > 0", buffer->height);
+ return BAD_VALUE;
+ }
+ if (buffer->dataCb && buffer->dataCr) {
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? buffer->dataCb : buffer->dataCr;
+ // only map until last pixel
+ if (idx == 0) {
+ pStride = 2;
+ rStride = buffer->stride;
+ dataSize = buffer->stride * (buffer->height - 1) + buffer->width * 2;
+ } else {
+ pStride = buffer->chromaStep;
+ rStride = buffer->chromaStride;
+ dataSize = buffer->chromaStride * (buffer->height - 1) +
+ buffer->chromaStep * (buffer->width / 2);
+ }
+ break;
+ }
+
+ ySize = (buffer->stride * 2) * buffer->height;
+ cSize = ySize;
+ pStride = (idx == 0) ? 2 : 4;
+ cb = buffer->data + ySize;
+ cr = cb + 2;
+
pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
dataSize = (idx == 0) ? ySize : cSize;
rStride = buffer->stride * 2;
@@ -544,6 +590,80 @@ static status_t extractP010Gralloc4PlaneLayout(
return OK;
}
+static status_t extractP210Gralloc4PlaneLayout(sp<GraphicBuffer> buffer, void *pData, int format,
+ LockedImage *outputImage) {
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t res = mapper.getPlaneLayouts(buffer->handle, &planeLayouts);
+ if (res != OK) {
+ return res;
+ }
+ constexpr int64_t Y_PLANE_COMPONENTS = int64_t(PlaneLayoutComponentType::Y);
+ constexpr int64_t CBCR_PLANE_COMPONENTS =
+ int64_t(PlaneLayoutComponentType::CB) | int64_t(PlaneLayoutComponentType::CR);
+ uint8_t *dataY = nullptr;
+ uint8_t *dataCb = nullptr;
+ uint8_t *dataCr = nullptr;
+ uint32_t strideY = 0;
+ uint32_t strideCbCr = 0;
+ for (const ui::PlaneLayout &layout : planeLayouts) {
+ ALOGV("gralloc4 plane: %s", layout.toString().c_str());
+ int64_t components = 0;
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.sizeInBits != 10) {
+ return BAD_VALUE;
+ }
+ components |= component.type.value;
+ }
+ if (components == Y_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 16) {
+ return BAD_VALUE;
+ }
+ if (layout.components[0].offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ dataY = (uint8_t *)pData + layout.offsetInBytes;
+ strideY = layout.strideInBytes;
+ } else if (components == CBCR_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 32) {
+ return BAD_VALUE;
+ }
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CB) &&
+ component.offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CR) &&
+ component.offsetInBits != 22) {
+ return BAD_VALUE;
+ }
+ }
+ dataCb = (uint8_t *)pData + layout.offsetInBytes;
+ dataCr = (uint8_t *)pData + layout.offsetInBytes + 2;
+ strideCbCr = layout.strideInBytes;
+ } else {
+ return BAD_VALUE;
+ }
+ }
+
+ outputImage->data = dataY;
+ outputImage->width = buffer->getWidth();
+ outputImage->height = buffer->getHeight();
+ outputImage->format = format;
+ outputImage->flexFormat =
+ static_cast<int>(AidlPixelFormat::YCBCR_P210);
+ outputImage->stride = strideY;
+
+ outputImage->dataCb = dataCb;
+ outputImage->dataCr = dataCr;
+ outputImage->chromaStride = strideCbCr;
+ outputImage->chromaStep = 4;
+ return OK;
+}
+
status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
const Rect& rect, int fenceFd, LockedImage* outputImage) {
ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__);
@@ -581,10 +701,17 @@ status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
ALOGE("Lock buffer failed!");
return res;
}
- if (isPossibly10BitYUV(format)
- && OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
- ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
- return OK;
+ if (isPossibly10BitYUV(format)) {
+ if (format == HAL_PIXEL_FORMAT_YCBCR_P010 &&
+ OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
+ return OK;
+ } else if ((format ==
+ static_cast<int>(AidlPixelFormat::YCBCR_P210)) &&
+ OK == extractP210Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P210 image", __FUNCTION__);
+ return OK;
+ }
}
}
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index a77bc9fe0570..a1ce495fe33d 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -910,7 +910,7 @@ MtpResponseCode MtpDatabase::getObjectInfo(MtpObjectHandle handle,
case MTP_FORMAT_TIFF:
case MTP_FORMAT_TIFF_EP:
case MTP_FORMAT_DEFINED: {
- String8 temp(path);
+ String8 temp {static_cast<std::string_view>(path)};
std::unique_ptr<FileStream> stream(new FileStream(temp));
piex::PreviewImageData image_data;
if (!GetExifFromRawImage(stream.get(), temp, image_data)) {
@@ -967,7 +967,7 @@ void* MtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
case MTP_FORMAT_TIFF:
case MTP_FORMAT_TIFF_EP:
case MTP_FORMAT_DEFINED: {
- String8 temp(path);
+ String8 temp {static_cast<std::string_view>(path)};
std::unique_ptr<FileStream> stream(new FileStream(temp));
piex::PreviewImageData image_data;
if (!GetExifFromRawImage(stream.get(), temp, image_data)) {
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index e4f88a65ed1a..e63c59d53f2a 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -9,7 +9,7 @@ package {
android_test {
name: "mediaroutertest",
- team: "trendy_team_android_media_solutions",
+ team: "trendy_team_android_media_better_together",
srcs: ["**/*.java"],
diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS
index bdb6cdbea332..c57265a91eff 100644
--- a/media/tests/MtpTests/OWNERS
+++ b/media/tests/MtpTests/OWNERS
@@ -1,9 +1,9 @@
set noparent
-anothermark@google.com
+vmartensson@google.com
+nkapron@google.com
febinthattil@google.com
-aprasath@google.com
+shubhankarm@google.com
jsharkey@android.com
jameswei@google.com
rmojumder@google.com
-kumarashishg@google.com \ No newline at end of file
diff --git a/mime/Android.bp b/mime/Android.bp
index 20110f1dfb47..b609548fcbab 100644
--- a/mime/Android.bp
+++ b/mime/Android.bp
@@ -49,6 +49,17 @@ java_library {
],
}
+java_library {
+ name: "mimemap-testing-alt",
+ defaults: ["mimemap-defaults"],
+ static_libs: ["mimemap-testing-alt-res.jar"],
+ jarjar_rules: "jarjar-rules-alt.txt",
+ visibility: [
+ "//cts/tests/tests/mimemap:__subpackages__",
+ "//frameworks/base:__subpackages__",
+ ],
+}
+
// The mimemap-res.jar and mimemap-testing-res.jar genrules produce a .jar that
// has the resource file in a subdirectory res/ and testres/, respectively.
// They need to be in different paths because one of them ends up in a
@@ -86,6 +97,19 @@ java_genrule {
cmd: "mkdir $(genDir)/testres/ && cp $(in) $(genDir)/testres/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/testres/",
}
+// The same as mimemap-testing-res.jar except that the resources are placed in a different directory.
+// They get bundled with CTS so that CTS can compare a device's MimeMap implementation vs.
+// the stock Android one from when CTS was built.
+java_genrule {
+ name: "mimemap-testing-alt-res.jar",
+ tools: [
+ "soong_zip",
+ ],
+ srcs: [":mime.types.minimized-alt"],
+ out: ["mimemap-testing-alt-res.jar"],
+ cmd: "mkdir $(genDir)/testres-alt/ && cp $(in) $(genDir)/testres-alt/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/testres-alt/",
+}
+
// Combination of all *mime.types.minimized resources.
filegroup {
name: "mime.types.minimized",
@@ -99,6 +123,19 @@ filegroup {
],
}
+// Combination of all *mime.types.minimized resources.
+filegroup {
+ name: "mime.types.minimized-alt",
+ visibility: [
+ "//visibility:private",
+ ],
+ device_common_srcs: [
+ ":debian.mime.types.minimized-alt",
+ ":android.mime.types.minimized",
+ ":vendor.mime.types.minimized",
+ ],
+}
+
java_genrule {
name: "android.mime.types.minimized",
visibility: [
diff --git a/mime/jarjar-rules-alt.txt b/mime/jarjar-rules-alt.txt
new file mode 100644
index 000000000000..9a7644325336
--- /dev/null
+++ b/mime/jarjar-rules-alt.txt
@@ -0,0 +1 @@
+rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidAltMimeMapFactory
diff --git a/mime/jarjar-rules.txt b/mime/jarjar-rules.txt
index 145d1dbf3d11..e1ea8e10314c 100644
--- a/mime/jarjar-rules.txt
+++ b/mime/jarjar-rules.txt
@@ -1 +1 @@
-rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidMimeMapFactory \ No newline at end of file
+rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidMimeMapFactory
diff --git a/native/android/OWNERS b/native/android/OWNERS
index 1fde7d268517..1e8d30d1681c 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -6,8 +6,7 @@ per-file libandroid.map.txt = jreck@google.com, zyy@google.com, mattbuckley@goog
# Networking
per-file libandroid_net.map.txt, net.c = set noparent
-per-file libandroid_net.map.txt, net.c = codewiz@google.com, jchalard@google.com, junyulai@google.com
-per-file libandroid_net.map.txt, net.c = lorenzo@google.com, reminv@google.com, satk@google.com
+per-file libandroid_net.map.txt, net.c = file:platform/packages/modules/Connectivity:main:/OWNERS_core_networking
# Fonts
per-file system_fonts.cpp = file:/graphics/java/android/graphics/fonts/OWNERS
@@ -29,6 +28,7 @@ per-file surface_texture.cpp = file:/graphics/java/android/graphics/OWNERS
# Input
per-file input.cpp = file:/INPUT_OWNERS
-# PerformanceHint
+# ADPF
per-file performance_hint.cpp = file:/ADPF_OWNERS
+per-file system_health.cpp = file:/ADPF_OWNERS
per-file thermal.cpp = file:/ADPF_OWNERS
diff --git a/native/android/tests/system_health/OWNERS b/native/android/tests/system_health/OWNERS
new file mode 100644
index 000000000000..e3bbee92057d
--- /dev/null
+++ b/native/android/tests/system_health/OWNERS
@@ -0,0 +1 @@
+include /ADPF_OWNERS
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 4180710534c3..bc273c2d0833 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -102,8 +102,13 @@ cc_defaults {
static_libs: ["libarect"],
fuzz_config: {
cc: [
+ // Alphabetical order -- assign to skia-android-triage@google.com
+ "danieldilan@google.com",
"dichenzhang@google.com",
- "scroggo@google.com",
+ "fmalita@google.com",
+ "jreck@google.com",
+ "nscobie@google.com",
+ "skia-android-triage@google.com",
],
asan_options: [
"detect_odr_violation=1",
diff --git a/nfc-extras/OWNERS b/nfc-extras/OWNERS
index 35e9713f5715..2b82bc8ad073 100644
--- a/nfc-extras/OWNERS
+++ b/nfc-extras/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
+include platform/packages/modules/Nfc:/OWNERS
diff --git a/nfc-non-updatable/Android.bp b/nfc-non-updatable/Android.bp
new file mode 100644
index 000000000000..ff987bb84b17
--- /dev/null
+++ b/nfc-non-updatable/Android.bp
@@ -0,0 +1,23 @@
+package {
+ default_team: "trendy_team_fwk_nfc",
+ // 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"],
+}
+
+filegroup {
+ name: "framework-nfc-non-updatable-sources",
+ path: "java",
+ srcs: [
+ "java/android/nfc/NfcServiceManager.java",
+ "java/android/nfc/cardemulation/ApduServiceInfo.aidl",
+ "java/android/nfc/cardemulation/ApduServiceInfo.java",
+ "java/android/nfc/cardemulation/NfcFServiceInfo.aidl",
+ "java/android/nfc/cardemulation/NfcFServiceInfo.java",
+ "java/android/nfc/cardemulation/AidGroup.aidl",
+ "java/android/nfc/cardemulation/AidGroup.java",
+ ],
+}
diff --git a/nfc-non-updatable/OWNERS b/nfc-non-updatable/OWNERS
new file mode 100644
index 000000000000..47f209ffa9fa
--- /dev/null
+++ b/nfc-non-updatable/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 48448
+include platform/packages/modules/Nfc:/OWNERS \ No newline at end of file
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc-non-updatable/flags/flags.aconfig
index ee287aba709f..eb30bbe1bfe7 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc-non-updatable/flags/flags.aconfig
@@ -189,3 +189,15 @@ flag {
description: "App can check its tag intent preference status"
bug: "335916336"
}
+
+flag {
+ name: "nfc_apdu_service_info_constructor"
+ is_exported: true
+ namespace: "nfc"
+ description: "Expose constructor for ApduServiceInfo"
+ bug: "380892385"
+}
+
+# Unless you are adding a flag for a file under nfc-non-updatable, you should
+# not add a flag here for Android 16+ targeting features. Use the flags
+# in com.android.nfc.module.flags (packages/modules/Nfc/flags) instead.
diff --git a/nfc/java/android/nfc/NfcServiceManager.java b/nfc-non-updatable/java/android/nfc/NfcServiceManager.java
index 5582f1154cad..5582f1154cad 100644
--- a/nfc/java/android/nfc/NfcServiceManager.java
+++ b/nfc-non-updatable/java/android/nfc/NfcServiceManager.java
diff --git a/nfc/java/android/nfc/cardemulation/AidGroup.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl
index 56d6fa559677..56d6fa559677 100644
--- a/nfc/java/android/nfc/cardemulation/AidGroup.aidl
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl
diff --git a/nfc/java/android/nfc/cardemulation/AidGroup.java b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java
index ae3e333051d7..ae3e333051d7 100644
--- a/nfc/java/android/nfc/cardemulation/AidGroup.java
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl
index a62fdd6a6c5c..a62fdd6a6c5c 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
index 308b5d1831a6..f2a68afbfcbe 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -70,6 +70,11 @@ import java.util.regex.Pattern;
public final class ApduServiceInfo implements Parcelable {
private static final String TAG = "ApduServiceInfo";
+ private static final Pattern PLPF_PATTERN =
+ Pattern.compile("[0-9A-Fa-f]{2,}[0-9A-Fa-f,\\?,\\*\\.]*");
+ private static final Pattern PLF_PATTERN =
+ Pattern.compile("[0-9A-Fa-f]{2,}");
+
/**
* Component level {@link android.content.pm.PackageManager.Property PackageManager
* .Property} for a system application to change its icon and label
@@ -174,16 +179,33 @@ public final class ApduServiceInfo implements Parcelable {
* Whether or not this service wants to share the same routing priority as the
* Wallet role owner.
*/
- private boolean mShareRolePriority;
+ private boolean mWantsRoleHolderPriority;
/**
+ * Constructor of {@link ApduServiceInfo}.
+ * @param info App component info
+ * @param onHost whether service is on host or not (secure element)
+ * @param description The description of service
+ * @param staticAidGroups static AID groups
+ * @param dynamicAidGroups dynamic AID groups
+ * @param requiresUnlock whether this service should only be started
+ * when the device is unlocked
+ * @param bannerResource The id of the service banner specified in XML
+ * @param uid The uid of the package the service belongs to
+ * @param settingsActivityName Settings Activity for this service
+ * @param offHost Off-host reader name
+ * @param staticOffHost Off-host reader name from manifest file
+ *
* @hide
*/
@UnsupportedAppUsage
- public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
- ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_APDU_SERVICE_INFO_CONSTRUCTOR)
+ public ApduServiceInfo(@NonNull ResolveInfo info, boolean onHost, @NonNull String description,
+ @NonNull List<AidGroup> staticAidGroups, @NonNull List<AidGroup> dynamicAidGroups,
boolean requiresUnlock, int bannerResource, int uid,
- String settingsActivityName, String offHost, String staticOffHost) {
+ @NonNull String settingsActivityName, @NonNull String offHost,
+ @NonNull String staticOffHost) {
this(info, onHost, description, staticAidGroups, dynamicAidGroups,
requiresUnlock, bannerResource, uid, settingsActivityName,
offHost, staticOffHost, false);
@@ -193,7 +215,7 @@ public final class ApduServiceInfo implements Parcelable {
* @hide
*/
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
- ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
+ List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups,
boolean requiresUnlock, int bannerResource, int uid,
String settingsActivityName, String offHost, String staticOffHost,
boolean isEnabled) {
@@ -314,8 +336,8 @@ public final class ApduServiceInfo implements Parcelable {
R.styleable.HostApduService_shouldDefaultToObserveMode,
false);
if (Flags.nfcAssociatedRoleServices()) {
- mShareRolePriority = sa.getBoolean(
- R.styleable.HostApduService_shareRolePriority,
+ mWantsRoleHolderPriority = sa.getBoolean(
+ R.styleable.HostApduService_wantsRoleHolderPriority,
false
);
}
@@ -350,8 +372,8 @@ public final class ApduServiceInfo implements Parcelable {
}
mStaticOffHostName = mOffHostName;
if (Flags.nfcAssociatedRoleServices()) {
- mShareRolePriority = sa.getBoolean(
- R.styleable.OffHostApduService_shareRolePriority,
+ mWantsRoleHolderPriority = sa.getBoolean(
+ R.styleable.OffHostApduService_wantsRoleHolderPriority,
false
);
}
@@ -455,7 +477,12 @@ public final class ApduServiceInfo implements Parcelable {
boolean autoTransact = a.getBoolean(
com.android.internal.R.styleable.PollingLoopFilter_autoTransact,
false);
- if (!mOnHost && !autoTransact) {
+ boolean isValidFilter = PLF_PATTERN.matcher(plf).matches()
+ && plf.length() % 2 == 0;
+ if (!isValidFilter) {
+ Log.e(TAG, "Ignoring polling-loop-filter " + plf
+ + " it is not a valid filter");
+ } else if (!mOnHost && !autoTransact) {
Log.e(TAG, "Ignoring polling-loop-filter " + plf
+ " for offhost service that isn't autoTransact");
} else {
@@ -472,8 +499,12 @@ public final class ApduServiceInfo implements Parcelable {
boolean autoTransact = a.getBoolean(
com.android.internal.R.styleable.PollingLoopFilter_autoTransact,
false);
- if (!mOnHost && !autoTransact) {
- Log.e(TAG, "Ignoring polling-loop-filter " + plf
+ boolean isValidFilter = PLPF_PATTERN.matcher(plf).matches();
+ if (!isValidFilter) {
+ Log.e(TAG, "Ignoring polling-loop-pattern-filter " + plf
+ + " it is not a valid pattern filter");
+ } else if (!mOnHost && !autoTransact) {
+ Log.e(TAG, "Ignoring polling-loop-pattern-filter " + plf
+ " for offhost service that isn't autoTransact");
} else {
mAutoTransactPatterns.put(Pattern.compile(plf), autoTransact);
@@ -555,8 +586,10 @@ public final class ApduServiceInfo implements Parcelable {
if (mAutoTransact.getOrDefault(plf.toUpperCase(Locale.ROOT), false)) {
return true;
}
- List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream()
- .filter(p -> p.matcher(plf).matches()).toList();
+ boolean isPattern = plf.contains("?") || plf.contains("*");
+ List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream().filter(
+ p -> isPattern ? p.toString().equals(plf) : p.matcher(plf).matches()).toList();
+
if (patternMatches == null || patternMatches.size() == 0) {
return false;
}
@@ -752,8 +785,8 @@ public final class ApduServiceInfo implements Parcelable {
* @return whether or not this service wants to share priority
*/
@FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
- public boolean shareRolePriority() {
- return mShareRolePriority;
+ public boolean wantsRoleHolderPriority() {
+ return mWantsRoleHolderPriority;
}
/**
@@ -795,10 +828,16 @@ public final class ApduServiceInfo implements Parcelable {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public void addPollingLoopFilter(@NonNull String pollingLoopFilter,
boolean autoTransact) {
+ if (!PLF_PATTERN.matcher(pollingLoopFilter).matches()
+ || pollingLoopFilter.length() % 2 != 0) {
+ throw new IllegalArgumentException(
+ "Polling loop filter must contain an even number of characters 0-9 or A-F"
+ );
+ }
if (!mOnHost && !autoTransact) {
return;
}
- mAutoTransact.put(pollingLoopFilter, autoTransact);
+ mAutoTransact.put(pollingLoopFilter.toUpperCase(Locale.ROOT), autoTransact);
}
/**
@@ -823,10 +862,16 @@ public final class ApduServiceInfo implements Parcelable {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public void addPollingLoopPatternFilter(@NonNull String pollingLoopPatternFilter,
boolean autoTransact) {
+ if (!PLPF_PATTERN.matcher(pollingLoopPatternFilter).matches()) {
+ throw new IllegalArgumentException(
+ "Polling loop pattern filter is invalid"
+ );
+ }
if (!mOnHost && !autoTransact) {
return;
}
- mAutoTransactPatterns.put(Pattern.compile(pollingLoopPatternFilter), autoTransact);
+ mAutoTransactPatterns.put(Pattern.compile(
+ pollingLoopPatternFilter.toUpperCase(Locale.ROOT)), autoTransact);
}
/**
diff --git a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
index 56b98ebd90fa..56b98ebd90fa 100644
--- a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
diff --git a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java
index 33bc16978721..33bc16978721 100644
--- a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java
+++ b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java
diff --git a/nfc/Android.bp b/nfc/Android.bp
deleted file mode 100644
index abe0ab757ba6..000000000000
--- a/nfc/Android.bp
+++ /dev/null
@@ -1,91 +0,0 @@
-package {
- default_team: "trendy_team_fwk_nfc",
- // 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"],
-}
-
-filegroup {
- name: "framework-nfc-non-updatable-sources",
- path: "java",
- srcs: [
- "java/android/nfc/NfcServiceManager.java",
- "java/android/nfc/cardemulation/ApduServiceInfo.aidl",
- "java/android/nfc/cardemulation/ApduServiceInfo.java",
- "java/android/nfc/cardemulation/NfcFServiceInfo.aidl",
- "java/android/nfc/cardemulation/NfcFServiceInfo.java",
- "java/android/nfc/cardemulation/AidGroup.aidl",
- "java/android/nfc/cardemulation/AidGroup.java",
- ],
-}
-
-filegroup {
- name: "framework-nfc-updatable-sources",
- path: "java",
- srcs: [
- "java/**/*.java",
- "java/**/*.aidl",
- ],
- exclude_srcs: [
- ":framework-nfc-non-updatable-sources",
- ],
-}
-
-java_sdk_library {
- name: "framework-nfc",
- libs: [
- "androidx.annotation_annotation",
- "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
- "framework-permission-s.stubs.module_lib",
- "framework-permission.stubs.module_lib",
- ],
- stub_only_libs: [
- // Needed for javadoc references.
- "framework-permission-s.stubs.module_lib",
- ],
- static_libs: [
- "android.nfc.flags-aconfig-java",
- "android.permission.flags-aconfig-java",
- ],
- srcs: [
- ":framework-nfc-updatable-sources",
- ":framework-nfc-javastream-protos",
- ],
- defaults: ["framework-module-defaults"],
- sdk_version: "module_current",
- min_sdk_version: "current",
- installable: true,
- optimize: {
- enabled: false,
- },
- hostdex: true, // for hiddenapi check
- permitted_packages: [
- "android.nfc",
- "com.android.nfc",
- ],
- impl_library_visibility: [
- "//frameworks/base:__subpackages__",
- "//cts/hostsidetests/multidevices/nfc:__subpackages__",
- "//cts/tests/tests/nfc",
- "//packages/apps/Nfc:__subpackages__",
- ],
- jarjar_rules: ":nfc-jarjar-rules",
- lint: {
- baseline_filename: "lint-baseline.xml",
- },
- apex_available: [
- "//apex_available:platform",
- "com.android.nfcservices",
- ],
- aconfig_declarations: [
- "android.nfc.flags-aconfig",
- ],
-}
-
-filegroup {
- name: "nfc-jarjar-rules",
- srcs: ["jarjar-rules.txt"],
-}
diff --git a/nfc/OWNERS b/nfc/OWNERS
deleted file mode 100644
index 35e9713f5715..000000000000
--- a/nfc/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING
deleted file mode 100644
index 49c778d22038..000000000000
--- a/nfc/TEST_MAPPING
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "presubmit": [
- {
- "name": "NfcManagerTests"
- },
- {
- "name": "CtsNfcTestCases"
- },
- {
- "name": "CtsNdefTestCases"
- }
- ]
-}
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
deleted file mode 100644
index 0ee81cbb7a73..000000000000
--- a/nfc/api/current.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
- public final class AvailableNfcAntenna implements android.os.Parcelable {
- ctor public AvailableNfcAntenna(int, int);
- method public int describeContents();
- method public int getLocationX();
- method public int getLocationY();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.AvailableNfcAntenna> CREATOR;
- }
-
- public class FormatException extends java.lang.Exception {
- ctor public FormatException();
- ctor public FormatException(String);
- ctor public FormatException(String, Throwable);
- }
-
- public final class NdefMessage implements android.os.Parcelable {
- ctor public NdefMessage(byte[]) throws android.nfc.FormatException;
- ctor public NdefMessage(android.nfc.NdefRecord, android.nfc.NdefRecord...);
- ctor public NdefMessage(android.nfc.NdefRecord[]);
- method public int describeContents();
- method public int getByteArrayLength();
- method public android.nfc.NdefRecord[] getRecords();
- method public byte[] toByteArray();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefMessage> CREATOR;
- }
-
- public final class NdefRecord implements android.os.Parcelable {
- ctor public NdefRecord(short, byte[], byte[], byte[]);
- ctor @Deprecated public NdefRecord(byte[]) throws android.nfc.FormatException;
- method public static android.nfc.NdefRecord createApplicationRecord(String);
- method public static android.nfc.NdefRecord createExternal(String, String, byte[]);
- method public static android.nfc.NdefRecord createMime(String, byte[]);
- method public static android.nfc.NdefRecord createTextRecord(String, String);
- method public static android.nfc.NdefRecord createUri(android.net.Uri);
- method public static android.nfc.NdefRecord createUri(String);
- method public int describeContents();
- method public byte[] getId();
- method public byte[] getPayload();
- method public short getTnf();
- method public byte[] getType();
- method @Deprecated public byte[] toByteArray();
- method public String toMimeType();
- method public android.net.Uri toUri();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NdefRecord> CREATOR;
- field public static final byte[] RTD_ALTERNATIVE_CARRIER;
- field public static final byte[] RTD_HANDOVER_CARRIER;
- field public static final byte[] RTD_HANDOVER_REQUEST;
- field public static final byte[] RTD_HANDOVER_SELECT;
- field public static final byte[] RTD_SMART_POSTER;
- field public static final byte[] RTD_TEXT;
- field public static final byte[] RTD_URI;
- field public static final short TNF_ABSOLUTE_URI = 3; // 0x3
- field public static final short TNF_EMPTY = 0; // 0x0
- field public static final short TNF_EXTERNAL_TYPE = 4; // 0x4
- field public static final short TNF_MIME_MEDIA = 2; // 0x2
- field public static final short TNF_UNCHANGED = 6; // 0x6
- field public static final short TNF_UNKNOWN = 5; // 0x5
- field public static final short TNF_WELL_KNOWN = 1; // 0x1
- }
-
- public final class NfcAdapter {
- method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable();
- method public void disableForegroundDispatch(android.app.Activity);
- method public void disableReaderMode(android.app.Activity);
- method @FlaggedApi("android.nfc.nfc_state_change") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enable();
- method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]);
- method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
- method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
- method @Nullable public android.nfc.NfcAntennaInfo getNfcAntennaInfo();
- method @FlaggedApi("android.nfc.enable_nfc_charging") @Nullable public android.nfc.WlcListenerDeviceInfo getWlcListenerDeviceInfo();
- method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
- method public boolean isEnabled();
- method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeEnabled();
- method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean isObserveModeSupported();
- method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionEnabled();
- method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
- method public boolean isSecureNfcEnabled();
- method public boolean isSecureNfcSupported();
- method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAllowed();
- method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAppPreferenceSupported();
- method @FlaggedApi("android.nfc.enable_nfc_charging") public boolean isWlcEnabled();
- method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity);
- method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int);
- method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setObserveModeEnabled(boolean);
- field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
- field @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE = "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
- field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
- field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
- field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
- field public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
- field @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT) public static final String ACTION_TRANSACTION_DETECTED = "android.nfc.action.TRANSACTION_DETECTED";
- field public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
- field public static final String EXTRA_AID = "android.nfc.extra.AID";
- field public static final String EXTRA_DATA = "android.nfc.extra.DATA";
- field public static final String EXTRA_ID = "android.nfc.extra.ID";
- field public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
- field public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON = "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
- field public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
- field public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
- field public static final String EXTRA_TAG = "android.nfc.extra.TAG";
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_DISABLE = 0; // 0x0
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_KEEP = -2147483648; // 0x80000000
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_A = 1; // 0x1
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_B = 2; // 0x2
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_LISTEN_NFC_PASSIVE_F = 4; // 0x4
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_DISABLE = 0; // 0x0
- field @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public static final int FLAG_READER_KEEP = -2147483648; // 0x80000000
- field public static final int FLAG_READER_NFC_A = 1; // 0x1
- field public static final int FLAG_READER_NFC_B = 2; // 0x2
- field public static final int FLAG_READER_NFC_BARCODE = 16; // 0x10
- field public static final int FLAG_READER_NFC_F = 4; // 0x4
- field public static final int FLAG_READER_NFC_V = 8; // 0x8
- field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
- field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
- field public static final int PREFERRED_PAYMENT_CHANGED = 2; // 0x2
- field public static final int PREFERRED_PAYMENT_LOADED = 1; // 0x1
- field public static final int PREFERRED_PAYMENT_UPDATED = 3; // 0x3
- field public static final int STATE_OFF = 1; // 0x1
- field public static final int STATE_ON = 3; // 0x3
- field public static final int STATE_TURNING_OFF = 4; // 0x4
- field public static final int STATE_TURNING_ON = 2; // 0x2
- }
-
- @Deprecated public static interface NfcAdapter.CreateBeamUrisCallback {
- method @Deprecated public android.net.Uri[] createBeamUris(android.nfc.NfcEvent);
- }
-
- @Deprecated public static interface NfcAdapter.CreateNdefMessageCallback {
- method @Deprecated public android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent);
- }
-
- @Deprecated public static interface NfcAdapter.OnNdefPushCompleteCallback {
- method @Deprecated public void onNdefPushComplete(android.nfc.NfcEvent);
- }
-
- public static interface NfcAdapter.OnTagRemovedListener {
- method public void onTagRemoved();
- }
-
- public static interface NfcAdapter.ReaderCallback {
- method public void onTagDiscovered(android.nfc.Tag);
- }
-
- public final class NfcAntennaInfo implements android.os.Parcelable {
- ctor public NfcAntennaInfo(int, int, boolean, @NonNull java.util.List<android.nfc.AvailableNfcAntenna>);
- method public int describeContents();
- method @NonNull public java.util.List<android.nfc.AvailableNfcAntenna> getAvailableNfcAntennas();
- method public int getDeviceHeight();
- method public int getDeviceWidth();
- method public boolean isDeviceFoldable();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.NfcAntennaInfo> CREATOR;
- }
-
- public final class NfcEvent {
- field public final android.nfc.NfcAdapter nfcAdapter;
- field public final int peerLlcpMajorVersion;
- field public final int peerLlcpMinorVersion;
- }
-
- public final class NfcManager {
- method public android.nfc.NfcAdapter getDefaultAdapter();
- }
-
- public final class Tag implements android.os.Parcelable {
- method public int describeContents();
- method public byte[] getId();
- method public String[] getTechList();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.Tag> CREATOR;
- }
-
- public class TagLostException extends java.io.IOException {
- ctor public TagLostException();
- ctor public TagLostException(String);
- }
-
- @FlaggedApi("android.nfc.enable_nfc_charging") public final class WlcListenerDeviceInfo implements android.os.Parcelable {
- ctor public WlcListenerDeviceInfo(int, double, double, int);
- method public int describeContents();
- method @FloatRange(from=0.0, to=100.0) public double getBatteryLevel();
- method public int getProductId();
- method public int getState();
- method public double getTemperature();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.WlcListenerDeviceInfo> CREATOR;
- field public static final int STATE_CONNECTED_CHARGING = 2; // 0x2
- field public static final int STATE_CONNECTED_DISCHARGING = 3; // 0x3
- field public static final int STATE_DISCONNECTED = 1; // 0x1
- }
-
-}
-
-package android.nfc.cardemulation {
-
- public final class CardEmulation {
- method public boolean categoryAllowsForegroundPreference(String);
- method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
- method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
- method @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();
- method public int getSelectionModeForCategory(String);
- method public boolean isDefaultServiceForAid(android.content.ComponentName, String);
- method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
- method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
- method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
- method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
- method public boolean removeAidsForService(android.content.ComponentName, String);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean removePollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String);
- method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
- method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
- method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
- method public boolean supportsAidPrefixRegistration();
- method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventListener(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
- method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
- method public boolean unsetPreferredService(android.app.Activity);
- field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
- field public static final String CATEGORY_OTHER = "other";
- field public static final String CATEGORY_PAYMENT = "payment";
- field public static final String EXTRA_CATEGORY = "category";
- field public static final String EXTRA_SERVICE_COMPONENT = "component";
- field @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_associated_role_services") public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY = "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2; // 0x2
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1; // 0xffffffff
- field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1
- field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2
- field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
- }
-
- @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 {
- ctor public HostApduService();
- method public final void notifyUnhandled();
- method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract void onDeactivated(int);
- method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
- method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
- method public final void sendResponseApdu(byte[]);
- field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
- field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
- field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
- field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
- }
-
- public abstract class HostNfcFService extends android.app.Service {
- ctor public HostNfcFService();
- method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract void onDeactivated(int);
- method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
- method public final void sendResponsePacket(byte[]);
- field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
- field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
- field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
- }
-
- public final class NfcFCardEmulation {
- method public boolean disableService(android.app.Activity) throws java.lang.RuntimeException;
- method public boolean enableService(android.app.Activity, android.content.ComponentName) throws java.lang.RuntimeException;
- method public static android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
- method public String getNfcid2ForService(android.content.ComponentName) throws java.lang.RuntimeException;
- method public String getSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
- method public boolean registerSystemCodeForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
- method public boolean setNfcid2ForService(android.content.ComponentName, String) throws java.lang.RuntimeException;
- method public boolean unregisterSystemCodeForService(android.content.ComponentName) throws java.lang.RuntimeException;
- }
-
- public abstract class OffHostApduService extends android.app.Service {
- ctor public OffHostApduService();
- field public static final String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
- field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service";
- }
-
- @FlaggedApi("android.nfc.nfc_read_polling_loop") public final class PollingFrame implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public byte[] getData();
- method public long getTimestamp();
- method public boolean getTriggeredAutoTransact();
- method public int getType();
- method public int getVendorSpecificGain();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.PollingFrame> CREATOR;
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_A = 65; // 0x41
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_B = 66; // 0x42
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_F = 70; // 0x46
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_OFF = 88; // 0x58
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_ON = 79; // 0x4f
- field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final int POLLING_LOOP_TYPE_UNKNOWN = 85; // 0x55
- }
-
-}
-
-package android.nfc.tech {
-
- public final class IsoDep implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.IsoDep get(android.nfc.Tag);
- method public byte[] getHiLayerResponse();
- method public byte[] getHistoricalBytes();
- method public int getMaxTransceiveLength();
- method public android.nfc.Tag getTag();
- method public int getTimeout();
- method public boolean isConnected();
- method public boolean isExtendedLengthApduSupported();
- method public void setTimeout(int);
- method public byte[] transceive(byte[]) throws java.io.IOException;
- }
-
- public final class MifareClassic implements android.nfc.tech.TagTechnology {
- method public boolean authenticateSectorWithKeyA(int, byte[]) throws java.io.IOException;
- method public boolean authenticateSectorWithKeyB(int, byte[]) throws java.io.IOException;
- method public int blockToSector(int);
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public void decrement(int, int) throws java.io.IOException;
- method public static android.nfc.tech.MifareClassic get(android.nfc.Tag);
- method public int getBlockCount();
- method public int getBlockCountInSector(int);
- method public int getMaxTransceiveLength();
- method public int getSectorCount();
- method public int getSize();
- method public android.nfc.Tag getTag();
- method public int getTimeout();
- method public int getType();
- method public void increment(int, int) throws java.io.IOException;
- method public boolean isConnected();
- method public byte[] readBlock(int) throws java.io.IOException;
- method public void restore(int) throws java.io.IOException;
- method public int sectorToBlock(int);
- method public void setTimeout(int);
- method public byte[] transceive(byte[]) throws java.io.IOException;
- method public void transfer(int) throws java.io.IOException;
- method public void writeBlock(int, byte[]) throws java.io.IOException;
- field public static final int BLOCK_SIZE = 16; // 0x10
- field public static final byte[] KEY_DEFAULT;
- field public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY;
- field public static final byte[] KEY_NFC_FORUM;
- field public static final int SIZE_1K = 1024; // 0x400
- field public static final int SIZE_2K = 2048; // 0x800
- field public static final int SIZE_4K = 4096; // 0x1000
- field public static final int SIZE_MINI = 320; // 0x140
- field public static final int TYPE_CLASSIC = 0; // 0x0
- field public static final int TYPE_PLUS = 1; // 0x1
- field public static final int TYPE_PRO = 2; // 0x2
- field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
- }
-
- public final class MifareUltralight implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag);
- method public int getMaxTransceiveLength();
- method public android.nfc.Tag getTag();
- method public int getTimeout();
- method public int getType();
- method public boolean isConnected();
- method public byte[] readPages(int) throws java.io.IOException;
- method public void setTimeout(int);
- method public byte[] transceive(byte[]) throws java.io.IOException;
- method public void writePage(int, byte[]) throws java.io.IOException;
- field public static final int PAGE_SIZE = 4; // 0x4
- field public static final int TYPE_ULTRALIGHT = 1; // 0x1
- field public static final int TYPE_ULTRALIGHT_C = 2; // 0x2
- field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
- }
-
- public final class Ndef implements android.nfc.tech.TagTechnology {
- method public boolean canMakeReadOnly();
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.Ndef get(android.nfc.Tag);
- method public android.nfc.NdefMessage getCachedNdefMessage();
- method public int getMaxSize();
- method public android.nfc.NdefMessage getNdefMessage() throws android.nfc.FormatException, java.io.IOException;
- method public android.nfc.Tag getTag();
- method public String getType();
- method public boolean isConnected();
- method public boolean isWritable();
- method public boolean makeReadOnly() throws java.io.IOException;
- method public void writeNdefMessage(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
- field public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
- field public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
- field public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
- field public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
- field public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
- }
-
- public final class NdefFormatable implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public void format(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
- method public void formatReadOnly(android.nfc.NdefMessage) throws android.nfc.FormatException, java.io.IOException;
- method public static android.nfc.tech.NdefFormatable get(android.nfc.Tag);
- method public android.nfc.Tag getTag();
- method public boolean isConnected();
- }
-
- public final class NfcA implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.NfcA get(android.nfc.Tag);
- method public byte[] getAtqa();
- method public int getMaxTransceiveLength();
- method public short getSak();
- method public android.nfc.Tag getTag();
- method public int getTimeout();
- method public boolean isConnected();
- method public void setTimeout(int);
- method public byte[] transceive(byte[]) throws java.io.IOException;
- }
-
- public final class NfcB implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.NfcB get(android.nfc.Tag);
- method public byte[] getApplicationData();
- method public int getMaxTransceiveLength();
- method public byte[] getProtocolInfo();
- method public android.nfc.Tag getTag();
- method public boolean isConnected();
- method public byte[] transceive(byte[]) throws java.io.IOException;
- }
-
- public final class NfcBarcode implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.NfcBarcode get(android.nfc.Tag);
- method public byte[] getBarcode();
- method public android.nfc.Tag getTag();
- method public int getType();
- method public boolean isConnected();
- field public static final int TYPE_KOVIO = 1; // 0x1
- field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
- }
-
- public final class NfcF implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.NfcF get(android.nfc.Tag);
- method public byte[] getManufacturer();
- method public int getMaxTransceiveLength();
- method public byte[] getSystemCode();
- method public android.nfc.Tag getTag();
- method public int getTimeout();
- method public boolean isConnected();
- method public void setTimeout(int);
- method public byte[] transceive(byte[]) throws java.io.IOException;
- }
-
- public final class NfcV implements android.nfc.tech.TagTechnology {
- method public void close() throws java.io.IOException;
- method public void connect() throws java.io.IOException;
- method public static android.nfc.tech.NfcV get(android.nfc.Tag);
- method public byte getDsfId();
- method public int getMaxTransceiveLength();
- method public byte getResponseFlags();
- method public android.nfc.Tag getTag();
- method public boolean isConnected();
- method public byte[] transceive(byte[]) throws java.io.IOException;
- }
-
- public interface TagTechnology extends java.io.Closeable {
- method public void connect() throws java.io.IOException;
- method public android.nfc.Tag getTag();
- method public boolean isConnected();
- }
-
-}
-
diff --git a/nfc/api/lint-baseline.txt b/nfc/api/lint-baseline.txt
deleted file mode 100644
index ef9aab6e7641..000000000000
--- a/nfc/api/lint-baseline.txt
+++ /dev/null
@@ -1,95 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
- Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
- Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
- Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
- Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
- Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
- Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
- Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
- Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
- Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
- Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
- Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
- Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
- Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
- Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
- Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
- Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
- Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
- Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
- Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
- Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
- Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
- Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
- Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
- Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
- Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
- Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
- Method 'connect' documentation mentions permissions without declaring @RequiresPermission
diff --git a/nfc/api/module-lib-current.txt b/nfc/api/module-lib-current.txt
deleted file mode 100644
index 5ebe91111ec0..000000000000
--- a/nfc/api/module-lib-current.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
- public class NfcFrameworkInitializer {
- method public static void registerServiceWrappers();
- method public static void setNfcServiceManager(@NonNull android.nfc.NfcServiceManager);
- }
-
-}
-
diff --git a/nfc/api/module-lib-lint-baseline.txt b/nfc/api/module-lib-lint-baseline.txt
deleted file mode 100644
index f7f8ee3ddda5..000000000000
--- a/nfc/api/module-lib-lint-baseline.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
- Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
- Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
- Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
- Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
- Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
- Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
- Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
- Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
- Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
- Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
- Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
- Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
- Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
- Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
- Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
- Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
- Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
- Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
- Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
- Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
- Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
- Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
- Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
- Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
- Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
- Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
- Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
- Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/module-lib-removed.txt b/nfc/api/module-lib-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/nfc/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/removed.txt b/nfc/api/removed.txt
deleted file mode 100644
index fb82b5ddbb21..000000000000
--- a/nfc/api/removed.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
- public final class NfcAdapter {
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void disableForegroundNdefPush(android.app.Activity);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean invokeBeam(android.app.Activity);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public boolean isNdefPushEnabled();
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUris(android.net.Uri[], android.app.Activity);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setBeamPushUrisCallback(android.nfc.NfcAdapter.CreateBeamUrisCallback, android.app.Activity);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, android.app.Activity...);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity, android.app.Activity...);
- method @Deprecated @android.compat.annotation.UnsupportedAppUsage public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity, android.app.Activity...);
- }
-
-}
-
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
deleted file mode 100644
index cf11ac028858..000000000000
--- a/nfc/api/system-current.txt
+++ /dev/null
@@ -1,261 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
- public final class NfcAdapter {
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean addNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler, String[]);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disable(boolean);
- method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
- method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.NfcOemExtension getNfcOemExtension();
- method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
- method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
- method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
- method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
- method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerNfcVendorNciCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
- method @FlaggedApi("android.nfc.enable_nfc_charging") public void registerWlcStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.WlcStateListener);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean removeNfcUnlockHandler(android.nfc.NfcAdapter.NfcUnlockHandler);
- method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int sendVendorNciMessage(int, @IntRange(from=0, to=15) int, @IntRange(from=0) int, @NonNull byte[]);
- method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean setControllerAlwaysOn(boolean);
- method @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setReaderModePollingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setTagIntentAppPreferenceForUser(int, @NonNull String, boolean);
- method @FlaggedApi("android.nfc.enable_nfc_charging") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setWlcEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void unregisterControllerAlwaysOnListener(@NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
- method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterNfcVendorNciCallback(@NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
- method @FlaggedApi("android.nfc.enable_nfc_charging") public void unregisterWlcStateListener(@NonNull android.nfc.NfcAdapter.WlcStateListener);
- field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC = "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
- field @FlaggedApi("android.nfc.enable_nfc_mainline") @RequiresPermission(android.Manifest.permission.SHOW_CUSTOMIZED_RESOLVER) public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
- field @FlaggedApi("android.nfc.enable_nfc_mainline") public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
- field @FlaggedApi("android.nfc.nfc_set_default_disc_tech") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final int FLAG_SET_DEFAULT_TECH = 1073741824; // 0x40000000
- field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int MESSAGE_TYPE_COMMAND = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3; // 0x3
- field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED = 2; // 0x2
- field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_vendor_cmd") public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0; // 0x0
- field public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1; // 0xffffffff
- field public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0; // 0x0
- field public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2; // 0xfffffffe
- }
-
- public static interface NfcAdapter.ControllerAlwaysOnListener {
- method public void onControllerAlwaysOnChanged(boolean);
- }
-
- public static interface NfcAdapter.NfcUnlockHandler {
- method public boolean onUnlockAttempted(android.nfc.Tag);
- }
-
- @FlaggedApi("android.nfc.nfc_vendor_cmd") public static interface NfcAdapter.NfcVendorNciCallback {
- method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciNotification(@IntRange(from=9, to=15) int, int, @NonNull byte[]);
- method @FlaggedApi("android.nfc.nfc_vendor_cmd") public void onVendorNciResponse(@IntRange(from=0, to=15) int, int, @NonNull byte[]);
- }
-
- @FlaggedApi("android.nfc.enable_nfc_charging") public static interface NfcAdapter.WlcStateListener {
- method public void onWlcStateChanged(@NonNull android.nfc.WlcListenerDeviceInfo);
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public long getMaxPausePollingTimeoutMills();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(long);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void triggerInitialization();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
- field public static final int COMMIT_ROUTING_STATUS_FAILED = 3; // 0x3
- field public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6; // 0x6
- field public static final int COMMIT_ROUTING_STATUS_OK = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int DISABLE = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_DEFAULT = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_EE = 3; // 0x3
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_TRANSPARENT = 2; // 0x2
- field public static final int HCE_ACTIVATE = 1; // 0x1
- field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
- field public static final int HCE_DEACTIVATE = 3; // 0x3
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_A = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_B = 2; // 0x2
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_F = 4; // 0x4
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int NFCEE_TECH_NONE = 0; // 0x0
- field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
- field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
- field public static final int STATUS_OK = 0; // 0x0
- field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
- }
-
- public static interface NfcOemExtension.Callback {
- method public void onApplyRouting(@NonNull java.util.function.Consumer<java.lang.Boolean>);
- method public void onBootFinished(int);
- method public void onBootStarted();
- method public void onCardEmulationActivated(boolean);
- method public void onDisableFinished(int);
- 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();
- method public void onExtractOemPackages(@NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.util.List<java.lang.String>>);
- method public void onGetOemAppSearchIntent(@NonNull java.util.List<java.lang.String>, @NonNull java.util.function.Consumer<android.content.Intent>);
- method public void onHceEventReceived(int);
- method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
- method public void onLaunchHceTapAgainDialog(@NonNull android.nfc.cardemulation.ApduServiceInfo, @NonNull String);
- method public void onLogEventNotified(@NonNull android.nfc.OemLogItems);
- method public void onNdefMessage(@NonNull android.nfc.Tag, @NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.lang.Boolean>);
- method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
- method public void onReaderOptionChanged(boolean);
- method public void onRfDiscoveryStarted(boolean);
- method public void onRfFieldActivated(boolean);
- method public void onRoutingChanged(@NonNull java.util.function.Consumer<java.lang.Boolean>);
- method public void onRoutingTableFull();
- method public void onStateUpdated(int);
- method public void onTagConnected(boolean);
- method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
- method public int getNfceeId();
- method public int getRouteType();
- 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 {
- method public int describeContents();
- method public int getAction();
- method public int getCallingPid();
- method @Nullable public byte[] getCommandApdu();
- method public int getEvent();
- method @Nullable public byte[] getResponseApdu();
- method @Nullable public java.time.Instant getRfFieldEventTimeMillis();
- method @Nullable public android.nfc.Tag getTag();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.OemLogItems> CREATOR;
- field public static final int EVENT_DISABLE = 2; // 0x2
- field public static final int EVENT_ENABLE = 1; // 0x1
- field public static final int EVENT_UNSET = 0; // 0x0
- field public static final int LOG_ACTION_HCE_DATA = 516; // 0x204
- field public static final int LOG_ACTION_NFC_TOGGLE = 513; // 0x201
- field public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 1; // 0x1
- field public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 518; // 0x206
- field public static final int LOG_ACTION_TAG_DETECTED = 3; // 0x3
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
- method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultRoute();
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableAidEntry extends android.nfc.NfcRoutingTableEntry {
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public String getAid();
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableProtocolEntry extends android.nfc.NfcRoutingTableEntry {
- method @FlaggedApi("android.nfc.nfc_oem_extension") public int getProtocol();
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_ISO_DEP = 4; // 0x4
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NDEF = 7; // 0x7
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_NFC_DEP = 5; // 0x5
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T1T = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T2T = 2; // 0x2
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T3T = 3; // 0x3
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_T5T = 6; // 0x6
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNDETERMINED = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int PROTOCOL_UNSUPPORTED = -1; // 0xffffffff
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableSystemCodeEntry extends android.nfc.NfcRoutingTableEntry {
- method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public byte[] getSystemCode();
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingTableTechnologyEntry extends android.nfc.NfcRoutingTableEntry {
- method @FlaggedApi("android.nfc.nfc_oem_extension") public int getTechnology();
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_A = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_B = 1; // 0x1
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_F = 2; // 0x2
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_UNSUPPORTED = -1; // 0xffffffff
- field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
- method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
- method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
- field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
- field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
- field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
- field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
- field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
- field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
- field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
- field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
- field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
- field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
- field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
- }
-
- @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
- method public int describeContents();
- method @IntRange(from=15, to=32767) public int getCcFileLength();
- method @IntRange(from=0xffffffff, to=65535) public int getFileId();
- method @IntRange(from=15, to=65535) public int getMaxReadLength();
- method @IntRange(from=5, to=32767) public int getMaxSize();
- method @IntRange(from=13, to=65535) public int getMaxWriteLength();
- method public int getReadAccess();
- method public int getVersion();
- method public int getWriteAccess();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
- field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
- field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
- field public static final int VERSION_2_0 = 32; // 0x20
- field public static final int VERSION_3_0 = 48; // 0x30
- field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
- field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
- field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
- }
-
-}
-
-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") @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
- field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1; // 0xffffffff
- }
-
-}
-
diff --git a/nfc/api/system-lint-baseline.txt b/nfc/api/system-lint-baseline.txt
deleted file mode 100644
index c7a618125add..000000000000
--- a/nfc/api/system-lint-baseline.txt
+++ /dev/null
@@ -1,119 +0,0 @@
-// Baseline format: 1.0
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_ADAPTER_STATE_CHANGED:
- Field 'ACTION_ADAPTER_STATE_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_PREFERRED_PAYMENT_CHANGED:
- Field 'ACTION_PREFERRED_PAYMENT_CHANGED' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
- Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @BroadcastBehavior
-BroadcastBehavior: android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED:
- Field 'ACTION_TRANSACTION_DETECTED' is missing @BroadcastBehavior
-
-
-CallbackMethodName: android.nfc.NfcOemExtension.Callback#shouldSkipRoutingChange():
- Callback method names must follow the on<Something> style: shouldSkipRoutingChange
-
-
-MethodNameTense: android.nfc.NfcOemExtension.Callback#onEnable():
- Unexpected tense; probably meant `enabled`, was `onEnable`
-
-
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #1:
- Missing nullability on parameter `protocol` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.CardEmulation#overrideRoutingTable(android.app.Activity, String, String) parameter #2:
- Missing nullability on parameter `technology` in method `overrideRoutingTable`
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent):
- Missing nullability on method `onBind` return
-MissingNullability: android.nfc.cardemulation.OffHostApduService#onBind(android.content.Intent) parameter #0:
- Missing nullability on parameter `intent` in method `onBind`
-
-
-RequiresPermission: android.nfc.NfcAdapter#disableForegroundDispatch(android.app.Activity):
- Method 'disableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.NfcAdapter#enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], String[][]):
- Method 'enableForegroundDispatch' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForAid(android.content.ComponentName, String):
- Method 'isDefaultServiceForAid' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String):
- Method 'isDefaultServiceForCategory' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.cardemulation.CardEmulation#setOffHostForService(android.content.ComponentName, String):
- Method 'setOffHostForService' documentation mentions permissions already declared by @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.IsoDep#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyA(int, byte[]):
- Method 'authenticateSectorWithKeyA' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#authenticateSectorWithKeyB(int, byte[]):
- Method 'authenticateSectorWithKeyB' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#decrement(int, int):
- Method 'decrement' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#increment(int, int):
- Method 'increment' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#readBlock(int):
- Method 'readBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#restore(int):
- Method 'restore' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#transfer(int):
- Method 'transfer' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareClassic#writeBlock(int, byte[]):
- Method 'writeBlock' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#readPages(int):
- Method 'readPages' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.MifareUltralight#writePage(int, byte[]):
- Method 'writePage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#getNdefMessage():
- Method 'getNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#isWritable():
- Method 'isWritable' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#makeReadOnly():
- Method 'makeReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.Ndef#writeNdefMessage(android.nfc.NdefMessage):
- Method 'writeNdefMessage' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#format(android.nfc.NdefMessage):
- Method 'format' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NdefFormatable#formatReadOnly(android.nfc.NdefMessage):
- Method 'formatReadOnly' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcA#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcB#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#getTimeout():
- Method 'getTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#setTimeout(int):
- Method 'setTimeout' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcF#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.NfcV#transceive(byte[]):
- Method 'transceive' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#close():
- Method 'close' documentation mentions permissions without declaring @RequiresPermission
-RequiresPermission: android.nfc.tech.TagTechnology#connect():
- Method 'connect' documentation mentions permissions without declaring @RequiresPermission
-
-
-SamShouldBeLast: android.nfc.NfcAdapter#enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle):
- SAM-compatible parameters (such as parameter 2, "callback", in android.nfc.NfcAdapter.enableReaderMode) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-SamShouldBeLast: android.nfc.NfcAdapter#ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler):
- SAM-compatible parameters (such as parameter 3, "tagRemovedListener", in android.nfc.NfcAdapter.ignore) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
-
-
-SdkConstant: android.nfc.NfcAdapter#ACTION_REQUIRE_UNLOCK_FOR_NFC:
- Field 'ACTION_REQUIRE_UNLOCK_FOR_NFC' is missing @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/nfc/api/system-removed.txt b/nfc/api/system-removed.txt
deleted file mode 100644
index c6eaa57b6b06..000000000000
--- a/nfc/api/system-removed.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-// Signature format: 2.0
-package android.nfc {
-
- public final class NfcAdapter {
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean disableNdefPush();
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableNdefPush();
- method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity, int);
- field public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 1; // 0x1
- }
-
-}
-
diff --git a/nfc/api/test-current.txt b/nfc/api/test-current.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/nfc/api/test-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/api/test-removed.txt b/nfc/api/test-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/nfc/api/test-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/nfc/jarjar-rules.txt b/nfc/jarjar-rules.txt
deleted file mode 100644
index 63a6a58d8ce2..000000000000
--- a/nfc/jarjar-rules.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Used by framework-nfc for proto debug dumping
-rule android.app.PendingIntentProto* com.android.nfc.x.@0
-rule android.content.ComponentNameProto* com.android.nfc.x.@0
-rule android.content.IntentProto* com.android.nfc.x.@0
-rule android.content.IntentFilterProto* com.android.nfc.x.@0
-rule android.content.AuthorityEntryProto* com.android.nfc.x.@0
-rule android.content.UriRelativeFilter* com.android.nfc.x.@0
-rule android.nfc.cardemulation.AidGroupProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.ApduServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.cardemulation.NfcFServiceInfoProto* com.android.nfc.x.@0
-rule android.nfc.NdefMessageProto* com.android.nfc.x.@0
-rule android.nfc.NdefRecordProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.CardEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredNfcFServicesCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.PreferredServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.EnabledNfcFServicesProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredAidCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.AidRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.RegisteredT3tIdentifiersCacheProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.SystemCodeRoutingManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.cardemulation.HostNfcFEmulationManagerProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcServiceDumpProto* com.android.nfc.x.@0
-rule com.android.nfc.DiscoveryParamsProto* com.android.nfc.x.@0
-rule com.android.nfc.NfcDispatcherProto* com.android.nfc.x.@0
-rule android.os.PersistableBundleProto* com.android.nfc.x.@0
-
-# Used by framework-nfc for reading trunk stable flags
-rule android.nfc.*Flags* com.android.nfc.x.@0
-rule android.nfc.Flags com.android.nfc.x.@0
-rule android.permission.flags.** com.android.nfc.x.@0
-
-# Used by framework-nfc for misc utilities
-rule android.os.PatternMatcher* com.android.nfc.x.@0
-
-rule com.android.incident.Privacy* com.android.nfc.x.@0
-rule com.android.incident.PrivacyFlags* com.android.nfc.x.@0
diff --git a/nfc/java/android/nfc/ApduList.aidl b/nfc/java/android/nfc/ApduList.aidl
deleted file mode 100644
index f6236b2bfb3b..000000000000
--- a/nfc/java/android/nfc/ApduList.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable ApduList; \ No newline at end of file
diff --git a/nfc/java/android/nfc/ApduList.java b/nfc/java/android/nfc/ApduList.java
deleted file mode 100644
index 027141d99c30..000000000000
--- a/nfc/java/android/nfc/ApduList.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @hide
- */
-public class ApduList implements Parcelable {
-
- private ArrayList<byte[]> commands = new ArrayList<byte[]>();
-
- public ApduList() {
- }
-
- public void add(byte[] command) {
- commands.add(command);
- }
-
- public List<byte[]> get() {
- return commands;
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<ApduList> CREATOR =
- new Parcelable.Creator<ApduList>() {
- @Override
- public ApduList createFromParcel(Parcel in) {
- return new ApduList(in);
- }
-
- @Override
- public ApduList[] newArray(int size) {
- return new ApduList[size];
- }
- };
-
- private ApduList(Parcel in) {
- int count = in.readInt();
-
- for (int i = 0 ; i < count ; i++) {
-
- int length = in.readInt();
- byte[] cmd = new byte[length];
- in.readByteArray(cmd);
- commands.add(cmd);
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(commands.size());
-
- for (byte[] cmd : commands) {
- dest.writeInt(cmd.length);
- dest.writeByteArray(cmd);
- }
- }
-}
-
-
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.aidl b/nfc/java/android/nfc/AvailableNfcAntenna.aidl
deleted file mode 100644
index 9d06e2d7d5eb..000000000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable AvailableNfcAntenna;
diff --git a/nfc/java/android/nfc/AvailableNfcAntenna.java b/nfc/java/android/nfc/AvailableNfcAntenna.java
deleted file mode 100644
index e76aeb07f106..000000000000
--- a/nfc/java/android/nfc/AvailableNfcAntenna.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents a single available Nfc antenna
- * on an Android device.
- */
-public final class AvailableNfcAntenna implements Parcelable {
- /**
- * Location of the antenna on the Y axis in millimeters.
- * 0 is the top-left when the user is facing the screen
- * and the device orientation is Portrait.
- */
- private final int mLocationX;
- /**
- * Location of the antenna on the Y axis in millimeters.
- * 0 is the top-left when the user is facing the screen
- * and the device orientation is Portrait.
- */
- private final int mLocationY;
-
- public AvailableNfcAntenna(int locationX, int locationY) {
- this.mLocationX = locationX;
- this.mLocationY = locationY;
- }
-
- /**
- * Location of the antenna on the X axis in millimeters.
- * 0 is the top-left when the user is facing the screen
- * and the device orientation is Portrait.
- */
- public int getLocationX() {
- return mLocationX;
- }
-
- /**
- * Location of the antenna on the Y axis in millimeters.
- * 0 is the top-left when the user is facing the screen
- * and the device orientation is Portrait.
- */
- public int getLocationY() {
- return mLocationY;
- }
-
- private AvailableNfcAntenna(Parcel in) {
- this.mLocationX = in.readInt();
- this.mLocationY = in.readInt();
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<AvailableNfcAntenna>
- CREATOR = new Parcelable.Creator<AvailableNfcAntenna>() {
- @Override
- public AvailableNfcAntenna createFromParcel(Parcel in) {
- return new AvailableNfcAntenna(in);
- }
-
- @Override
- public AvailableNfcAntenna[] newArray(int size) {
- return new AvailableNfcAntenna[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mLocationX);
- dest.writeInt(mLocationY);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + mLocationX;
- result = prime * result + mLocationY;
- return result;
- }
-
- /**
- * Returns true if the specified AvailableNfcAntenna contains
- * identical specifications.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- AvailableNfcAntenna other = (AvailableNfcAntenna) obj;
- if (this.mLocationX != other.mLocationX) return false;
- return this.mLocationY == other.mLocationY;
- }
-
- @Override
- public String toString() {
- return "AvailableNfcAntenna " + "x: " + mLocationX + " y: " + mLocationY;
- }
-}
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.aidl b/nfc/java/android/nfc/ComponentNameAndUser.aidl
deleted file mode 100644
index e677998a7970..000000000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable ComponentNameAndUser; \ No newline at end of file
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.java b/nfc/java/android/nfc/ComponentNameAndUser.java
deleted file mode 100644
index 59e6c62926c9..000000000000
--- a/nfc/java/android/nfc/ComponentNameAndUser.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.UserIdInt;
-import android.content.ComponentName;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Objects;
-
-/**
- * @hide
- */
-public class ComponentNameAndUser implements Parcelable {
- @UserIdInt private final int mUserId;
- private ComponentName mComponentName;
-
- public ComponentNameAndUser(@UserIdInt int userId, ComponentName componentName) {
- mUserId = userId;
- mComponentName = componentName;
- }
-
- /**
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * @hide
- */
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mUserId);
- out.writeParcelable(mComponentName, flags);
- }
-
- public static final Parcelable.Creator<ComponentNameAndUser> CREATOR =
- new Parcelable.Creator<ComponentNameAndUser>() {
- public ComponentNameAndUser createFromParcel(Parcel in) {
- return new ComponentNameAndUser(in);
- }
-
- public ComponentNameAndUser[] newArray(int size) {
- return new ComponentNameAndUser[size];
- }
- };
-
- private ComponentNameAndUser(Parcel in) {
- mUserId = in.readInt();
- mComponentName = in.readParcelable(null, ComponentName.class);
- }
-
- @UserIdInt
- public int getUserId() {
- return mUserId;
- }
-
- public ComponentName getComponentName() {
- return mComponentName;
- }
-
- @Override
- public String toString() {
- return mComponentName + " for user id: " + mUserId;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj != null && obj instanceof ComponentNameAndUser) {
- ComponentNameAndUser other = (ComponentNameAndUser) obj;
- return other.getUserId() == mUserId
- && Objects.equals(other.getComponentName(), mComponentName);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- if (mComponentName == null) {
- return mUserId;
- }
- return mComponentName.hashCode() + mUserId;
- }
-}
diff --git a/nfc/java/android/nfc/Constants.java b/nfc/java/android/nfc/Constants.java
deleted file mode 100644
index 9b11e2d30ed8..000000000000
--- a/nfc/java/android/nfc/Constants.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.provider.Settings;
-
-/**
- * @hide
- * TODO(b/303286040): Holds @hide API constants. Formalize these APIs.
- */
-public final class Constants {
- private Constants() { }
-
- public static final String SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND = "nfc_payment_foreground";
- public static final String SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT = "nfc_payment_default_component";
- public static final String FEATURE_NFC_ANY = "android.hardware.nfc.any";
-
- /**
- * @hide constant copied from {@link Settings.Global}
- * TODO(b/274636414): Migrate to official API in Android V.
- */
- public static final String SETTINGS_SATELLITE_MODE_RADIOS = "satellite_mode_radios";
- /**
- * @hide constant copied from {@link Settings.Global}
- * TODO(b/274636414): Migrate to official API in Android V.
- */
- public static final String SETTINGS_SATELLITE_MODE_ENABLED = "satellite_mode_enabled";
-}
diff --git a/nfc/java/android/nfc/Entry.aidl b/nfc/java/android/nfc/Entry.aidl
deleted file mode 100644
index 148c4ec86845..000000000000
--- a/nfc/java/android/nfc/Entry.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-parcelable Entry; \ No newline at end of file
diff --git a/nfc/java/android/nfc/Entry.java b/nfc/java/android/nfc/Entry.java
deleted file mode 100644
index aa5ba58e7179..000000000000
--- a/nfc/java/android/nfc/Entry.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-
-/** @hide */
-public final class Entry implements Parcelable {
- private final byte mType;
- private final byte mNfceeId;
- private final String mEntry;
- private final String mRoutingType;
-
- public Entry(String entry, byte type, byte nfceeId, String routingType) {
- mEntry = entry;
- mType = type;
- mNfceeId = nfceeId;
- mRoutingType = routingType;
- }
-
- public byte getType() {
- return mType;
- }
-
- public byte getNfceeId() {
- return mNfceeId;
- }
-
- public String getEntry() {
- return mEntry;
- }
-
- public String getRoutingType() {
- return mRoutingType;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- private Entry(Parcel in) {
- this.mEntry = in.readString();
- this.mNfceeId = in.readByte();
- this.mType = in.readByte();
- this.mRoutingType = in.readString();
- }
-
- public static final @NonNull Parcelable.Creator<Entry> CREATOR =
- new Parcelable.Creator<Entry>() {
- @Override
- public Entry createFromParcel(Parcel in) {
- return new Entry(in);
- }
-
- @Override
- public Entry[] newArray(int size) {
- return new Entry[size];
- }
- };
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(mEntry);
- dest.writeByte(mNfceeId);
- dest.writeByte(mType);
- dest.writeString(mRoutingType);
- }
-}
diff --git a/nfc/java/android/nfc/ErrorCodes.java b/nfc/java/android/nfc/ErrorCodes.java
deleted file mode 100644
index d2c81cd27d90..000000000000
--- a/nfc/java/android/nfc/ErrorCodes.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-
-/**
- * This class defines all the error codes that can be returned by the service
- * and producing an exception on the application level. These are needed since
- * binders does not support exceptions.
- *
- * @hide
- */
-public class ErrorCodes {
-
- @UnsupportedAppUsage
- public static boolean isError(int code) {
- if (code < 0) {
- return true;
- } else {
- return false;
- }
- }
-
- public static String asString(int code) {
- switch (code) {
- case SUCCESS: return "SUCCESS";
- case ERROR_IO: return "IO";
- case ERROR_CANCELLED: return "CANCELLED";
- case ERROR_TIMEOUT: return "TIMEOUT";
- case ERROR_BUSY: return "BUSY";
- case ERROR_CONNECT: return "CONNECT/DISCONNECT";
-// case ERROR_DISCONNECT: return "DISCONNECT";
- case ERROR_READ: return "READ";
- case ERROR_WRITE: return "WRITE";
- case ERROR_INVALID_PARAM: return "INVALID_PARAM";
- case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES";
- case ERROR_SOCKET_CREATION: return "SOCKET_CREATION";
- case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED";
- case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL";
- case ERROR_SAP_USED: return "SAP_USED";
- case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED";
- case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS";
- case ERROR_NFC_ON: return "NFC_ON";
- case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED";
- case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED";
- case ERROR_SE_CONNECTED: return "SE_CONNECTED";
- case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED";
- case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED";
- default: return "UNKNOWN ERROR";
- }
- }
-
- public static final int SUCCESS = 0;
-
- public static final int ERROR_IO = -1;
-
- public static final int ERROR_CANCELLED = -2;
-
- public static final int ERROR_TIMEOUT = -3;
-
- public static final int ERROR_BUSY = -4;
-
- public static final int ERROR_CONNECT = -5;
-
- public static final int ERROR_DISCONNECT = -5;
-
- public static final int ERROR_READ = -6;
-
- public static final int ERROR_WRITE = -7;
-
- public static final int ERROR_INVALID_PARAM = -8;
-
- public static final int ERROR_INSUFFICIENT_RESOURCES = -9;
-
- public static final int ERROR_SOCKET_CREATION = -10;
-
- public static final int ERROR_SOCKET_NOT_CONNECTED = -11;
-
- public static final int ERROR_BUFFER_TO_SMALL = -12;
-
- public static final int ERROR_SAP_USED = -13;
-
- public static final int ERROR_SERVICE_NAME_USED = -14;
-
- public static final int ERROR_SOCKET_OPTIONS = -15;
-
- public static final int ERROR_NFC_ON = -16;
-
- public static final int ERROR_NOT_INITIALIZED = -17;
-
- public static final int ERROR_SE_ALREADY_SELECTED = -18;
-
- public static final int ERROR_SE_CONNECTED = -19;
-
- public static final int ERROR_NO_SE_CONNECTED = -20;
-
- public static final int ERROR_NOT_SUPPORTED = -21;
-
-}
diff --git a/nfc/java/android/nfc/FormatException.java b/nfc/java/android/nfc/FormatException.java
deleted file mode 100644
index a57de1e0e21a..000000000000
--- a/nfc/java/android/nfc/FormatException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-public class FormatException extends Exception {
- public FormatException() {
- super();
- }
-
- public FormatException(String message) {
- super(message);
- }
-
- public FormatException(String message, Throwable e) {
- super(message, e);
- }
-}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
deleted file mode 100644
index ac0a5aaaa195..000000000000
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.app.PendingIntent;
-import android.content.IntentFilter;
-import android.nfc.Entry;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TechListParcel;
-import android.nfc.IAppCallback;
-import android.nfc.INfcAdapterExtras;
-import android.nfc.INfcControllerAlwaysOnListener;
-import android.nfc.INfcVendorNciCallback;
-import android.nfc.INfcTag;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.INfcOemExtensionCallback;
-import android.nfc.INfcUnlockHandler;
-import android.nfc.IT4tNdefNfcee;
-import android.nfc.ITagRemovedCallback;
-import android.nfc.INfcDta;
-import android.nfc.INfcWlcStateListener;
-import android.nfc.NfcAntennaInfo;
-import android.nfc.WlcListenerDeviceInfo;
-import android.nfc.cardemulation.PollingFrame;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-interface INfcAdapter
-{
- INfcTag getNfcTagInterface();
- INfcCardEmulation getNfcCardEmulationInterface();
- INfcFCardEmulation getNfcFCardEmulationInterface();
- INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
- INfcDta getNfcDtaInterface(in String pkg);
- int getState();
- boolean disable(boolean saveState, in String pkg);
- boolean enable(in String pkg);
- int pausePolling(long timeoutInMs);
- int resumePolling();
-
- void setForegroundDispatch(in PendingIntent intent,
- in IntentFilter[] filters, in TechListParcel techLists);
- void setAppCallback(in IAppCallback callback);
-
- boolean ignore(int nativeHandle, int debounceMs, ITagRemovedCallback callback);
-
- void dispatch(in Tag tag);
-
- void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras, String pkg);
-
- void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
- void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
-
- void verifyNfcPermission();
- boolean isNfcSecureEnabled();
- boolean deviceSupportsNfcSecure();
- boolean setNfcSecure(boolean enable);
- NfcAntennaInfo getNfcAntennaInfo();
-
- void setControllerAlwaysOn(int mode);
- boolean isControllerAlwaysOn();
- boolean isControllerAlwaysOnSupported();
- void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
- void unregisterControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
- boolean isTagIntentAppPreferenceSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
- Map getTagIntentAppPreferenceForUser(int userId);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
- int setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow);
-
- boolean isReaderOptionEnabled();
- boolean isReaderOptionSupported();
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
- boolean enableReaderOption(boolean enable, in String pkg);
- boolean isObserveModeSupported();
- boolean isObserveModeEnabled();
- boolean setObserveMode(boolean enabled, String pkg);
-
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)")
- boolean setWlcEnabled(boolean enable);
- boolean isWlcEnabled();
- void registerWlcStateListener(in INfcWlcStateListener listener);
- void unregisterWlcStateListener(in INfcWlcStateListener listener);
- WlcListenerDeviceInfo getWlcListenerDeviceInfo();
-
- void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags, String pkg);
-
- void notifyPollingLoop(in PollingFrame frame);
- void notifyHceDeactivated();
- void notifyTestHceData(in int technology, in byte[] data);
- int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
- void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
- void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
- void registerOemExtensionCallback(INfcOemExtensionCallback callbacks);
- void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks);
- void clearPreference();
- void setScreenState();
- void checkFirmware();
- Map fetchActiveNfceeList();
- void triggerInitialization();
- boolean getSettingStatus();
- boolean isTagPresent();
- List<Entry> getRoutingTableEntryList();
- void indicateDataMigration(boolean inProgress, String pkg);
- int commitRouting();
- boolean isTagIntentAllowed(in String pkg, in int Userid);
- IT4tNdefNfcee getT4tNdefNfceeInterface();
- long getMaxPausePollingTimeoutMs();
-}
diff --git a/nfc/java/android/nfc/INfcAdapterExtras.aidl b/nfc/java/android/nfc/INfcAdapterExtras.aidl
deleted file mode 100644
index cde57c58ca1f..000000000000
--- a/nfc/java/android/nfc/INfcAdapterExtras.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.os.Bundle;
-
-
-/**
- * {@hide}
- */
-interface INfcAdapterExtras {
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- Bundle open(in String pkg, IBinder b);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- Bundle close(in String pkg, IBinder b);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- Bundle transceive(in String pkg, in byte[] data_in);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- int getCardEmulationRoute(in String pkg);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- void setCardEmulationRoute(in String pkg, int route);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- void authenticate(in String pkg, in byte[] token);
- @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
- String getDriverName(in String pkg);
-}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
deleted file mode 100644
index bb9fe959dc06..000000000000
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.INfcEventListener;
-
-import android.nfc.cardemulation.AidGroup;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.os.RemoteCallback;
-
-/**
- * @hide
- */
-interface INfcCardEmulation
-{
- boolean isDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
- boolean isDefaultServiceForAid(int userHandle, in ComponentName service, String aid);
- boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
- boolean setDefaultForNextTap(int userHandle, in ComponentName service);
- boolean setShouldDefaultToObserveModeForService(int userId, in android.content.ComponentName service, boolean enable);
- boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
- boolean registerPollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter, boolean autoTransact);
- boolean registerPollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter, boolean autoTransact);
- boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
- boolean unsetOffHostForService(int userHandle, in ComponentName service);
- AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
- boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
- boolean removePollingLoopFilterForService(int userHandle, in ComponentName service, in String pollingLoopFilter);
- boolean removePollingLoopPatternFilterForService(int userHandle, in ComponentName service, in String pollingLoopPatternFilter);
- List<ApduServiceInfo> getServices(int userHandle, in String category);
- boolean setPreferredService(in ComponentName service);
- boolean unsetPreferredService();
- boolean supportsAidPrefixRegistration();
- ApduServiceInfo getPreferredPaymentService(int userHandle);
- int setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
- boolean isDefaultPaymentRegistered();
-
- 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();
- void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);
-
- void registerNfcEventListener(in INfcEventListener listener);
- void unregisterNfcEventListener(in INfcEventListener listener);
-}
diff --git a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl b/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
deleted file mode 100644
index 1bb7680d2fed..000000000000
--- a/nfc/java/android/nfc/INfcControllerAlwaysOnListener.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcControllerAlwaysOnListener {
- /**
- * Called whenever the controller always on state changes
- *
- * @param isEnabled true if the state is enabled, false otherwise
- */
- void onControllerAlwaysOnChanged(boolean isEnabled);
-}
diff --git a/nfc/java/android/nfc/INfcDta.aidl b/nfc/java/android/nfc/INfcDta.aidl
deleted file mode 100644
index 4cc59271362b..000000000000
--- a/nfc/java/android/nfc/INfcDta.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
- /*
- * Copyright (C) 2017 NXP Semiconductors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-interface INfcDta {
-
- void enableDta();
- void disableDta();
- boolean enableServer(String serviceName, int serviceSap, int miu,
- int rwSize,int testCaseId);
- void disableServer();
- boolean enableClient(String serviceName, int miu, int rwSize,
- int testCaseId);
- void disableClient();
- boolean registerMessageService(String msgServiceName);
-}
diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl
deleted file mode 100644
index 774d8f875192..000000000000
--- a/nfc/java/android/nfc/INfcEventListener.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package android.nfc;
-
-import android.nfc.ComponentNameAndUser;
-
-/**
- * @hide
- */
-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/INfcFCardEmulation.aidl b/nfc/java/android/nfc/INfcFCardEmulation.aidl
deleted file mode 100644
index 124bfac4f0d0..000000000000
--- a/nfc/java/android/nfc/INfcFCardEmulation.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.NfcFServiceInfo;
-
-/**
- * @hide
- */
-interface INfcFCardEmulation
-{
- String getSystemCodeForService(int userHandle, in ComponentName service);
- boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode);
- boolean removeSystemCodeForService(int userHandle, in ComponentName service);
- String getNfcid2ForService(int userHandle, in ComponentName service);
- boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2);
- boolean enableNfcFForegroundService(in ComponentName service);
- boolean disableNfcFForegroundService();
- List<NfcFServiceInfo> getNfcFServices(int userHandle);
- int getMaxNumOfRegisterableSystemCodes();
-}
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
deleted file mode 100644
index e5eac0b4d6fd..000000000000
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.content.ComponentName;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.NdefMessage;
-import android.nfc.OemLogItems;
-import android.nfc.Tag;
-import android.os.ResultReceiver;
-
-import java.util.List;
-
-/**
- * @hide
- */
-interface INfcOemExtensionCallback {
- void onTagConnected(boolean connected);
- void onStateUpdated(int state);
- void onApplyRouting(in ResultReceiver isSkipped);
- void onNdefRead(in ResultReceiver isSkipped);
- void onEnable(in ResultReceiver isAllowed);
- void onDisable(in ResultReceiver isAllowed);
- void onBootStarted();
- void onEnableStarted();
- void onDisableStarted();
- void onBootFinished(int status);
- void onEnableFinished(int status);
- void onDisableFinished(int status);
- void onTagDispatch(in ResultReceiver isSkipped);
- void onRoutingChanged(in ResultReceiver isSkipped);
- void onHceEventReceived(int action);
- void onReaderOptionChanged(boolean enabled);
- void onCardEmulationActivated(boolean isActivated);
- 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);
- void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
- void onRoutingTableFull();
- void onLogEventNotified(in OemLogItems item);
- void onExtractOemPackages(in NdefMessage message, in ResultReceiver packageReceiver);
-}
diff --git a/nfc/java/android/nfc/INfcTag.aidl b/nfc/java/android/nfc/INfcTag.aidl
deleted file mode 100644
index 170df71385bb..000000000000
--- a/nfc/java/android/nfc/INfcTag.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-
-/**
- * @hide
- */
-interface INfcTag
-{
- int connect(int nativeHandle, int technology);
- int reconnect(int nativeHandle);
- int[] getTechList(int nativeHandle);
- boolean isNdef(int nativeHandle);
- boolean isPresent(int nativeHandle);
- TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
-
- NdefMessage ndefRead(int nativeHandle);
- int ndefWrite(int nativeHandle, in NdefMessage msg);
- int ndefMakeReadOnly(int nativeHandle);
- boolean ndefIsWritable(int nativeHandle);
- int formatNdef(int nativeHandle, in byte[] key);
- Tag rediscover(int nativehandle);
-
- int setTimeout(int technology, int timeout);
- int getTimeout(int technology);
- void resetTimeouts();
- boolean canMakeReadOnly(int ndefType);
- int getMaxTransceiveLength(int technology);
- boolean getExtendedLengthApdusSupported();
-
- boolean isTagUpToDate(long cookie);
-}
diff --git a/nfc/java/android/nfc/INfcUnlockHandler.aidl b/nfc/java/android/nfc/INfcUnlockHandler.aidl
deleted file mode 100644
index e1cace987dc3..000000000000
--- a/nfc/java/android/nfc/INfcUnlockHandler.aidl
+++ /dev/null
@@ -1,12 +0,0 @@
-package android.nfc;
-
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface INfcUnlockHandler {
-
- boolean onUnlockAttempted(in Tag tag);
-
-}
diff --git a/nfc/java/android/nfc/INfcVendorNciCallback.aidl b/nfc/java/android/nfc/INfcVendorNciCallback.aidl
deleted file mode 100644
index 821dc6f6c868..000000000000
--- a/nfc/java/android/nfc/INfcVendorNciCallback.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface INfcVendorNciCallback {
- void onVendorResponseReceived(int gid, int oid, in byte[] payload);
- void onVendorNotificationReceived(int gid, int oid, in byte[] payload);
-}
diff --git a/nfc/java/android/nfc/INfcWlcStateListener.aidl b/nfc/java/android/nfc/INfcWlcStateListener.aidl
deleted file mode 100644
index 584eb9a128b4..000000000000
--- a/nfc/java/android/nfc/INfcWlcStateListener.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.nfc.WlcListenerDeviceInfo;
-/**
- * @hide
- */
-oneway interface INfcWlcStateListener {
- /**
- * Called whenever NFC WLC state changes
- *
- * @param wlcListenerDeviceInfo NFC wlc listener information
- */
- void onWlcStateChanged(in WlcListenerDeviceInfo wlcListenerDeviceInfo);
-}
diff --git a/nfc/java/android/nfc/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
deleted file mode 100644
index b4cda5b022fb..000000000000
--- a/nfc/java/android/nfc/IT4tNdefNfcee.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/******************************************************************************
- *
- * Copyright (C) 2024 The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
-
-package android.nfc;
-
-import android.nfc.T4tNdefNfceeCcFileInfo;
-
-/**
- * @hide
- */
-interface IT4tNdefNfcee {
- int writeData(in int fileId, in byte[] data);
- byte[] readData(in int fileId);
- int clearNdefData();
- boolean isNdefOperationOngoing();
- boolean isNdefNfceeEmulationSupported();
- T4tNdefNfceeCcFileInfo readCcfile();
-}
diff --git a/nfc/java/android/nfc/ITagRemovedCallback.aidl b/nfc/java/android/nfc/ITagRemovedCallback.aidl
deleted file mode 100644
index 2a06ff314b22..000000000000
--- a/nfc/java/android/nfc/ITagRemovedCallback.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.nfc;
-
-/**
- * @hide
- */
-oneway interface ITagRemovedCallback {
- void onTagRemoved();
-}
diff --git a/nfc/java/android/nfc/NdefMessage.aidl b/nfc/java/android/nfc/NdefMessage.aidl
deleted file mode 100644
index 378b9d05b385..000000000000
--- a/nfc/java/android/nfc/NdefMessage.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NdefMessage;
diff --git a/nfc/java/android/nfc/NdefMessage.java b/nfc/java/android/nfc/NdefMessage.java
deleted file mode 100644
index 553f6c01b016..000000000000
--- a/nfc/java/android/nfc/NdefMessage.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * Represents an immutable NDEF Message.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * When an Android device receives an NDEF Message
- * (for example by reading an NFC tag) it processes it through
- * a dispatch mechanism to determine an activity to launch.
- * The type of the <em>first</em> record in the message has
- * special importance for message dispatch, so design this record
- * carefully.
- * <p>
- * Use {@link #NdefMessage(byte[])} to construct an NDEF Message from
- * binary data, or {@link #NdefMessage(NdefRecord[])} to
- * construct from one or more {@link NdefRecord}s.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefRecord
- */
-public final class NdefMessage implements Parcelable {
- private final NdefRecord[] mRecords;
-
- /**
- * Construct an NDEF Message by parsing raw bytes.<p>
- * Strict validation of the NDEF binary structure is performed:
- * there must be at least one record, every record flag must
- * be correct, and the total length of the message must match
- * the length of the input data.<p>
- * This parser can handle chunked records, and converts them
- * into logical {@link NdefRecord}s within the message.<p>
- * Once the input data has been parsed to one or more logical
- * records, basic validation of the tnf, type, id, and payload fields
- * of each record is performed, as per the documentation on
- * on {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])}<p>
- * If either strict validation of the binary format fails, or
- * basic validation during record construction fails, a
- * {@link FormatException} is thrown<p>
- * Deep inspection of the type, id and payload fields of
- * each record is not performed, so it is possible to parse input
- * that has a valid binary format and confirms to the basic
- * validation requirements of
- * {@link NdefRecord#NdefRecord(short, byte[], byte[], byte[])},
- * but fails more strict requirements as specified by the
- * NFC Forum.
- *
- * <p class="note">
- * It is safe to re-use the data byte array after construction:
- * this constructor will make an internal copy of all necessary fields.
- *
- * @param data raw bytes to parse
- * @throws FormatException if the data cannot be parsed
- */
- public NdefMessage(byte[] data) throws FormatException {
- if (data == null) throw new NullPointerException("data is null");
- ByteBuffer buffer = ByteBuffer.wrap(data);
-
- mRecords = NdefRecord.parse(buffer, false);
-
- if (buffer.remaining() > 0) {
- throw new FormatException("trailing data");
- }
- }
-
- /**
- * Construct an NDEF Message from one or more NDEF Records.
- *
- * @param record first record (mandatory)
- * @param records additional records (optional)
- */
- public NdefMessage(NdefRecord record, NdefRecord ... records) {
- // validate
- if (record == null) throw new NullPointerException("record cannot be null");
-
- for (NdefRecord r : records) {
- if (r == null) {
- throw new NullPointerException("record cannot be null");
- }
- }
-
- mRecords = new NdefRecord[1 + records.length];
- mRecords[0] = record;
- System.arraycopy(records, 0, mRecords, 1, records.length);
- }
-
- /**
- * Construct an NDEF Message from one or more NDEF Records.
- *
- * @param records one or more records
- */
- public NdefMessage(NdefRecord[] records) {
- // validate
- if (records.length < 1) {
- throw new IllegalArgumentException("must have at least one record");
- }
- for (NdefRecord r : records) {
- if (r == null) {
- throw new NullPointerException("records cannot contain null");
- }
- }
-
- mRecords = records;
- }
-
- /**
- * Get the NDEF Records inside this NDEF Message.<p>
- * An {@link NdefMessage} always has one or more NDEF Records: so the
- * following code to retrieve the first record is always safe
- * (no need to check for null or array length >= 1):
- * <pre>
- * NdefRecord firstRecord = ndefMessage.getRecords()[0];
- * </pre>
- *
- * @return array of one or more NDEF records.
- */
- public NdefRecord[] getRecords() {
- return mRecords;
- }
-
- /**
- * Return the length of this NDEF Message if it is written to a byte array
- * with {@link #toByteArray}.<p>
- * An NDEF Message can be formatted to bytes in different ways
- * depending on chunking, SR, and ID flags, so the length returned
- * by this method may not be equal to the length of the original
- * byte array used to construct this NDEF Message. However it will
- * always be equal to the length of the byte array produced by
- * {@link #toByteArray}.
- *
- * @return length of this NDEF Message when written to bytes with {@link #toByteArray}
- * @see #toByteArray
- */
- public int getByteArrayLength() {
- int length = 0;
- for (NdefRecord r : mRecords) {
- length += r.getByteLength();
- }
- return length;
- }
-
- /**
- * Return this NDEF Message as raw bytes.<p>
- * The NDEF Message is formatted as per the NDEF 1.0 specification,
- * and the byte array is suitable for network transmission or storage
- * in an NFC Forum NDEF compatible tag.<p>
- * This method will not chunk any records, and will always use the
- * short record (SR) format and omit the identifier field when possible.
- *
- * @return NDEF Message in binary format
- * @see #getByteArrayLength()
- */
- public byte[] toByteArray() {
- int length = getByteArrayLength();
- ByteBuffer buffer = ByteBuffer.allocate(length);
-
- for (int i=0; i<mRecords.length; i++) {
- boolean mb = (i == 0); // first record
- boolean me = (i == mRecords.length - 1); // last record
- mRecords[i].writeToByteBuffer(buffer, mb, me);
- }
-
- return buffer.array();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mRecords.length);
- dest.writeTypedArray(mRecords, flags);
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<NdefMessage> CREATOR =
- new Parcelable.Creator<NdefMessage>() {
- @Override
- public NdefMessage createFromParcel(Parcel in) {
- int recordsLength = in.readInt();
- NdefRecord[] records = new NdefRecord[recordsLength];
- in.readTypedArray(records, NdefRecord.CREATOR);
- return new NdefMessage(records);
- }
- @Override
- public NdefMessage[] newArray(int size) {
- return new NdefMessage[size];
- }
- };
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(mRecords);
- }
-
- /**
- * Returns true if the specified NDEF Message contains
- * identical NDEF Records.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- NdefMessage other = (NdefMessage) obj;
- return Arrays.equals(mRecords, other.mRecords);
- }
-
- @Override
- public String toString() {
- return "NdefMessage " + Arrays.toString(mRecords);
- }
-
- /**
- * Dump debugging information as a NdefMessageProto
- * @hide
- *
- * Note:
- * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
- * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
- * {@link ProtoOutputStream#end(long)} after.
- * Never reuse a proto field number. When removing a field, mark it as reserved.
- */
- public void dumpDebug(ProtoOutputStream proto) {
- for (NdefRecord record : mRecords) {
- long token = proto.start(NdefMessageProto.NDEF_RECORDS);
- record.dumpDebug(proto);
- proto.end(token);
- }
- }
-} \ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.aidl b/nfc/java/android/nfc/NdefRecord.aidl
deleted file mode 100644
index 10f89d0936e4..000000000000
--- a/nfc/java/android/nfc/NdefRecord.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NdefRecord; \ No newline at end of file
diff --git a/nfc/java/android/nfc/NdefRecord.java b/nfc/java/android/nfc/NdefRecord.java
deleted file mode 100644
index 7bf4355d5b35..000000000000
--- a/nfc/java/android/nfc/NdefRecord.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Represents an immutable NDEF Record.
- * <p>
- * NDEF (NFC Data Exchange Format) is a light-weight binary format,
- * used to encapsulate typed data. It is specified by the NFC Forum,
- * for transmission and storage with NFC, however it is transport agnostic.
- * <p>
- * NDEF defines messages and records. An NDEF Record contains
- * typed data, such as MIME-type media, a URI, or a custom
- * application payload. An NDEF Message is a container for
- * one or more NDEF Records.
- * <p>
- * This class represents logical (complete) NDEF Records, and can not be
- * used to represent chunked (partial) NDEF Records. However
- * {@link NdefMessage#NdefMessage(byte[])} can be used to parse a message
- * containing chunked records, and will return a message with unchunked
- * (complete) records.
- * <p>
- * A logical NDEF Record always contains a 3-bit TNF (Type Name Field)
- * that provides high level typing for the rest of the record. The
- * remaining fields are variable length and not always present:
- * <ul>
- * <li><em>type</em>: detailed typing for the payload</li>
- * <li><em>id</em>: identifier meta-data, not commonly used</li>
- * <li><em>payload</em>: the actual payload</li>
- * </ul>
- * <p>
- * Helpers such as {@link NdefRecord#createUri}, {@link NdefRecord#createMime}
- * and {@link NdefRecord#createExternal} are included to create well-formatted
- * NDEF Records with correctly set tnf, type, id and payload fields, please
- * use these helpers whenever possible.
- * <p>
- * Use the constructor {@link #NdefRecord(short, byte[], byte[], byte[])}
- * if you know what you are doing and what to set the fields individually.
- * Only basic validation is performed with this constructor, so it is possible
- * to create records that do not confirm to the strict NFC Forum
- * specifications.
- * <p>
- * The binary representation of an NDEF Record includes additional flags to
- * indicate location with an NDEF message, provide support for chunking of
- * NDEF records, and to pack optional fields. This class does not expose
- * those details. To write an NDEF Record as binary you must first put it
- * into an {@link NdefMessage}, then call {@link NdefMessage#toByteArray()}.
- * <p class="note">
- * {@link NdefMessage} and {@link NdefRecord} implementations are
- * always available, even on Android devices that do not have NFC hardware.
- * <p class="note">
- * {@link NdefRecord}s are intended to be immutable (and thread-safe),
- * however they may contain mutable fields. So take care not to modify
- * mutable fields passed into constructors, or modify mutable fields
- * obtained by getter methods, unless such modification is explicitly
- * marked as safe.
- *
- * @see NfcAdapter#ACTION_NDEF_DISCOVERED
- * @see NdefMessage
- */
-public final class NdefRecord implements Parcelable {
- /**
- * Indicates the record is empty.<p>
- * Type, id and payload fields are empty in a {@literal TNF_EMPTY} record.
- */
- public static final short TNF_EMPTY = 0x00;
-
- /**
- * Indicates the type field contains a well-known RTD type name.<p>
- * Use this tnf with RTD types such as {@link #RTD_TEXT}, {@link #RTD_URI}.
- * <p>
- * The RTD type name format is specified in NFCForum-TS-RTD_1.0.
- *
- * @see #RTD_URI
- * @see #RTD_TEXT
- * @see #RTD_SMART_POSTER
- * @see #createUri
- */
- public static final short TNF_WELL_KNOWN = 0x01;
-
- /**
- * Indicates the type field contains a media-type BNF
- * construct, defined by RFC 2046.<p>
- * Use this with MIME type names such as {@literal "image/jpeg"}, or
- * using the helper {@link #createMime}.
- *
- * @see #createMime
- */
- public static final short TNF_MIME_MEDIA = 0x02;
-
- /**
- * Indicates the type field contains an absolute-URI
- * BNF construct defined by RFC 3986.<p>
- * When creating new records prefer {@link #createUri},
- * since it offers more compact URI encoding
- * ({@literal #RTD_URI} allows compression of common URI prefixes).
- *
- * @see #createUri
- */
- public static final short TNF_ABSOLUTE_URI = 0x03;
-
- /**
- * Indicates the type field contains an external type name.<p>
- * Used to encode custom payloads. When creating new records
- * use the helper {@link #createExternal}.<p>
- * The external-type RTD format is specified in NFCForum-TS-RTD_1.0.<p>
- * <p>
- * Note this TNF should not be used with RTD_TEXT or RTD_URI constants.
- * Those are well known RTD constants, not external RTD constants.
- *
- * @see #createExternal
- */
- public static final short TNF_EXTERNAL_TYPE = 0x04;
-
- /**
- * Indicates the payload type is unknown.<p>
- * NFC Forum explains this should be treated similarly to the
- * "application/octet-stream" MIME type. The payload
- * type is not explicitly encoded within the record.
- * <p>
- * The type field is empty in an {@literal TNF_UNKNOWN} record.
- */
- public static final short TNF_UNKNOWN = 0x05;
-
- /**
- * Indicates the payload is an intermediate or final chunk of a chunked
- * NDEF Record.<p>
- * {@literal TNF_UNCHANGED} can not be used with this class
- * since all {@link NdefRecord}s are already unchunked, however they
- * may appear in the binary format.
- */
- public static final short TNF_UNCHANGED = 0x06;
-
- /**
- * Reserved TNF type.
- * <p>
- * The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this
- * value like TNF_UNKNOWN.
- * @hide
- */
- public static final short TNF_RESERVED = 0x07;
-
- /**
- * RTD Text type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_TEXT = {0x54}; // "T"
-
- /**
- * RTD URI type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_URI = {0x55}; // "U"
-
- /**
- * RTD Smart Poster type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_SMART_POSTER = {0x53, 0x70}; // "Sp"
-
- /**
- * RTD Alternative Carrier type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_ALTERNATIVE_CARRIER = {0x61, 0x63}; // "ac"
-
- /**
- * RTD Handover Carrier type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_HANDOVER_CARRIER = {0x48, 0x63}; // "Hc"
-
- /**
- * RTD Handover Request type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_HANDOVER_REQUEST = {0x48, 0x72}; // "Hr"
-
- /**
- * RTD Handover Select type. For use with {@literal TNF_WELL_KNOWN}.
- * @see #TNF_WELL_KNOWN
- */
- public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
-
- /**
- * RTD Android app type. For use with {@literal TNF_EXTERNAL}.
- * <p>
- * The payload of a record with type RTD_ANDROID_APP
- * should be the package name identifying an application.
- * Multiple RTD_ANDROID_APP records may be included
- * in a single {@link NdefMessage}.
- * <p>
- * Use {@link #createApplicationRecord(String)} to create
- * RTD_ANDROID_APP records.
- * @hide
- */
- public static final byte[] RTD_ANDROID_APP = "android.com:pkg".getBytes();
-
- private static final byte FLAG_MB = (byte) 0x80;
- private static final byte FLAG_ME = (byte) 0x40;
- private static final byte FLAG_CF = (byte) 0x20;
- private static final byte FLAG_SR = (byte) 0x10;
- private static final byte FLAG_IL = (byte) 0x08;
-
- /**
- * NFC Forum "URI Record Type Definition"<p>
- * This is a mapping of "URI Identifier Codes" to URI string prefixes,
- * per section 3.2.2 of the NFC Forum URI Record Type Definition document.
- */
- private static final String[] URI_PREFIX_MAP = new String[] {
- "", // 0x00
- "http://www.", // 0x01
- "https://www.", // 0x02
- "http://", // 0x03
- "https://", // 0x04
- "tel:", // 0x05
- "mailto:", // 0x06
- "ftp://anonymous:anonymous@", // 0x07
- "ftp://ftp.", // 0x08
- "ftps://", // 0x09
- "sftp://", // 0x0A
- "smb://", // 0x0B
- "nfs://", // 0x0C
- "ftp://", // 0x0D
- "dav://", // 0x0E
- "news:", // 0x0F
- "telnet://", // 0x10
- "imap:", // 0x11
- "rtsp://", // 0x12
- "urn:", // 0x13
- "pop:", // 0x14
- "sip:", // 0x15
- "sips:", // 0x16
- "tftp:", // 0x17
- "btspp://", // 0x18
- "btl2cap://", // 0x19
- "btgoep://", // 0x1A
- "tcpobex://", // 0x1B
- "irdaobex://", // 0x1C
- "file://", // 0x1D
- "urn:epc:id:", // 0x1E
- "urn:epc:tag:", // 0x1F
- "urn:epc:pat:", // 0x20
- "urn:epc:raw:", // 0x21
- "urn:epc:", // 0x22
- "urn:nfc:", // 0x23
- };
-
- private static final int MAX_PAYLOAD_SIZE = 10 * (1 << 20); // 10 MB payload limit
-
- private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
- private final short mTnf;
- private final byte[] mType;
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private final byte[] mId;
- private final byte[] mPayload;
-
- /**
- * Create a new Android Application Record (AAR).
- * <p>
- * This record indicates to other Android devices the package
- * that should be used to handle the entire NDEF message.
- * You can embed this record anywhere into your message
- * to ensure that the intended package receives the message.
- * <p>
- * When an Android device dispatches an {@link NdefMessage}
- * containing one or more Android application records,
- * the applications contained in those records will be the
- * preferred target for the {@link NfcAdapter#ACTION_NDEF_DISCOVERED}
- * intent, in the order in which they appear in the message.
- * This dispatch behavior was first added to Android in
- * Ice Cream Sandwich.
- * <p>
- * If none of the applications have a are installed on the device,
- * a Market link will be opened to the first application.
- * <p>
- * Note that Android application records do not overrule
- * applications that have called
- * {@link NfcAdapter#enableForegroundDispatch}.
- *
- * @param packageName Android package name
- * @return Android application NDEF record
- */
- public static NdefRecord createApplicationRecord(String packageName) {
- if (packageName == null) throw new NullPointerException("packageName is null");
- if (packageName.length() == 0) throw new IllegalArgumentException("packageName is empty");
-
- return new NdefRecord(TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, null,
- packageName.getBytes(StandardCharsets.UTF_8));
- }
-
- /**
- * Create a new NDEF Record containing a URI.<p>
- * Use this method to encode a URI (or URL) into an NDEF Record.<p>
- * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
- * and {@link #RTD_URI}. This is the most efficient encoding
- * of a URI into NDEF.<p>
- * The uri parameter will be normalized with
- * {@link Uri#normalizeScheme} to set the scheme to lower case to
- * follow Android best practices for intent filtering.
- * However the unchecked exception
- * {@link IllegalArgumentException} may be thrown if the uri
- * parameter has serious problems, for example if it is empty, so always
- * catch this exception if you are passing user-generated data into this
- * method.<p>
- *
- * Reference specification: NFCForum-TS-RTD_URI_1.0
- *
- * @param uri URI to encode.
- * @return an NDEF Record containing the URI
- * @throws IllegalArugmentException if the uri is empty or invalid
- */
- public static NdefRecord createUri(Uri uri) {
- if (uri == null) throw new NullPointerException("uri is null");
-
- uri = uri.normalizeScheme();
- String uriString = uri.toString();
- if (uriString.length() == 0) throw new IllegalArgumentException("uri is empty");
-
- byte prefix = 0;
- for (int i = 1; i < URI_PREFIX_MAP.length; i++) {
- if (uriString.startsWith(URI_PREFIX_MAP[i])) {
- prefix = (byte) i;
- uriString = uriString.substring(URI_PREFIX_MAP[i].length());
- break;
- }
- }
- byte[] uriBytes = uriString.getBytes(StandardCharsets.UTF_8);
- byte[] recordBytes = new byte[uriBytes.length + 1];
- recordBytes[0] = prefix;
- System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.length);
- return new NdefRecord(TNF_WELL_KNOWN, RTD_URI, null, recordBytes);
- }
-
- /**
- * Create a new NDEF Record containing a URI.<p>
- * Use this method to encode a URI (or URL) into an NDEF Record.<p>
- * Uses the well known URI type representation: {@link #TNF_WELL_KNOWN}
- * and {@link #RTD_URI}. This is the most efficient encoding
- * of a URI into NDEF.<p>
- * The uriString parameter will be normalized with
- * {@link Uri#normalizeScheme} to set the scheme to lower case to
- * follow Android best practices for intent filtering.
- * However the unchecked exception
- * {@link IllegalArgumentException} may be thrown if the uriString
- * parameter has serious problems, for example if it is empty, so always
- * catch this exception if you are passing user-generated data into this
- * method.<p>
- *
- * Reference specification: NFCForum-TS-RTD_URI_1.0
- *
- * @param uriString string URI to encode.
- * @return an NDEF Record containing the URI
- * @throws IllegalArugmentException if the uriString is empty or invalid
- */
- public static NdefRecord createUri(String uriString) {
- return createUri(Uri.parse(uriString));
- }
-
- /**
- * Create a new NDEF Record containing MIME data.<p>
- * Use this method to encode MIME-typed data into an NDEF Record,
- * such as "text/plain", or "image/jpeg".<p>
- * The mimeType parameter will be normalized with
- * {@link Intent#normalizeMimeType} to follow Android best
- * practices for intent filtering, for example to force lower-case.
- * However the unchecked exception
- * {@link IllegalArgumentException} may be thrown
- * if the mimeType parameter has serious problems,
- * for example if it is empty, so always catch this
- * exception if you are passing user-generated data into this method.
- * <p>
- * For efficiency, This method might not make an internal copy of the
- * mimeData byte array, so take care not
- * to modify the mimeData byte array while still using the returned
- * NdefRecord.
- *
- * @param mimeType a valid MIME type
- * @param mimeData MIME data as bytes
- * @return an NDEF Record containing the MIME-typed data
- * @throws IllegalArugmentException if the mimeType is empty or invalid
- *
- */
- public static NdefRecord createMime(String mimeType, byte[] mimeData) {
- if (mimeType == null) throw new NullPointerException("mimeType is null");
-
- // We only do basic MIME type validation: trying to follow the
- // RFCs strictly only ends in tears, since there are lots of MIME
- // types in common use that are not strictly valid as per RFC rules
- mimeType = Intent.normalizeMimeType(mimeType);
- if (mimeType.length() == 0) throw new IllegalArgumentException("mimeType is empty");
- int slashIndex = mimeType.indexOf('/');
- if (slashIndex == 0) throw new IllegalArgumentException("mimeType must have major type");
- if (slashIndex == mimeType.length() - 1) {
- throw new IllegalArgumentException("mimeType must have minor type");
- }
- // missing '/' is allowed
-
- // MIME RFCs suggest ASCII encoding for content-type
- byte[] typeBytes = mimeType.getBytes(StandardCharsets.US_ASCII);
- return new NdefRecord(TNF_MIME_MEDIA, typeBytes, null, mimeData);
- }
-
- /**
- * Create a new NDEF Record containing external (application-specific) data.<p>
- * Use this method to encode application specific data into an NDEF Record.
- * The data is typed by a domain name (usually your Android package name) and
- * a domain-specific type. This data is packaged into a "NFC Forum External
- * Type" NDEF Record.<p>
- * NFC Forum requires that the domain and type used in an external record
- * are treated as case insensitive, however Android intent filtering is
- * always case sensitive. So this method will force the domain and type to
- * lower-case before creating the NDEF Record.<p>
- * The unchecked exception {@link IllegalArgumentException} will be thrown
- * if the domain and type have serious problems, for example if either field
- * is empty, so always catch this
- * exception if you are passing user-generated data into this method.<p>
- * There are no such restrictions on the payload data.<p>
- * For efficiency, This method might not make an internal copy of the
- * data byte array, so take care not
- * to modify the data byte array while still using the returned
- * NdefRecord.
- *
- * Reference specification: NFCForum-TS-RTD_1.0
- * @param domain domain-name of issuing organization
- * @param type domain-specific type of data
- * @param data payload as bytes
- * @throws IllegalArugmentException if either domain or type are empty or invalid
- */
- public static NdefRecord createExternal(String domain, String type, byte[] data) {
- if (domain == null) throw new NullPointerException("domain is null");
- if (type == null) throw new NullPointerException("type is null");
-
- domain = domain.trim().toLowerCase(Locale.ROOT);
- type = type.trim().toLowerCase(Locale.ROOT);
-
- if (domain.length() == 0) throw new IllegalArgumentException("domain is empty");
- if (type.length() == 0) throw new IllegalArgumentException("type is empty");
-
- byte[] byteDomain = domain.getBytes(StandardCharsets.UTF_8);
- byte[] byteType = type.getBytes(StandardCharsets.UTF_8);
- byte[] b = new byte[byteDomain.length + 1 + byteType.length];
- System.arraycopy(byteDomain, 0, b, 0, byteDomain.length);
- b[byteDomain.length] = ':';
- System.arraycopy(byteType, 0, b, byteDomain.length + 1, byteType.length);
-
- return new NdefRecord(TNF_EXTERNAL_TYPE, b, null, data);
- }
-
- /**
- * Create a new NDEF record containing UTF-8 text data.<p>
- *
- * The caller can either specify the language code for the provided text,
- * or otherwise the language code corresponding to the current default
- * locale will be used.
- *
- * Reference specification: NFCForum-TS-RTD_Text_1.0
- * @param languageCode The languageCode for the record. If locale is empty or null,
- * the language code of the current default locale will be used.
- * @param text The text to be encoded in the record. Will be represented in UTF-8 format.
- * @throws IllegalArgumentException if text is null
- */
- public static NdefRecord createTextRecord(String languageCode, String text) {
- if (text == null) throw new NullPointerException("text is null");
-
- byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
-
- byte[] languageCodeBytes = null;
- if (languageCode != null && !languageCode.isEmpty()) {
- languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
- } else {
- languageCodeBytes = Locale.getDefault().getLanguage().
- getBytes(StandardCharsets.US_ASCII);
- }
- // We only have 6 bits to indicate ISO/IANA language code.
- if (languageCodeBytes.length >= 64) {
- throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
- }
- ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
-
- byte status = (byte) (languageCodeBytes.length & 0xFF);
- buffer.put(status);
- buffer.put(languageCodeBytes);
- buffer.put(textBytes);
-
- return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
- }
-
- /**
- * Construct an NDEF Record from its component fields.<p>
- * Recommend to use helpers such as {#createUri} or
- * {{@link #createExternal} where possible, since they perform
- * stricter validation that the record is correctly formatted
- * as per NDEF specifications. However if you know what you are
- * doing then this constructor offers the most flexibility.<p>
- * An {@link NdefRecord} represents a logical (complete)
- * record, and cannot represent NDEF Record chunks.<p>
- * Basic validation of the tnf, type, id and payload is performed
- * as per the following rules:
- * <ul>
- * <li>The tnf paramter must be a 3-bit value.</li>
- * <li>Records with a tnf of {@link #TNF_EMPTY} cannot have a type,
- * id or payload.</li>
- * <li>Records with a tnf of {@link #TNF_UNKNOWN} or {@literal 0x07}
- * cannot have a type.</li>
- * <li>Records with a tnf of {@link #TNF_UNCHANGED} are not allowed
- * since this class only represents complete (unchunked) records.</li>
- * </ul>
- * This minimal validation is specified by
- * NFCForum-TS-NDEF_1.0 section 3.2.6 (Type Name Format).<p>
- * If any of the above validation
- * steps fail then {@link IllegalArgumentException} is thrown.<p>
- * Deep inspection of the type, id and payload fields is not
- * performed, so it is possible to create NDEF Records
- * that conform to section 3.2.6
- * but fail other more strict NDEF specification requirements. For
- * example, the payload may be invalid given the tnf and type.
- * <p>
- * To omit a type, id or payload field, set the parameter to an
- * empty byte array or null.
- *
- * @param tnf a 3-bit TNF constant
- * @param type byte array, containing zero to 255 bytes, or null
- * @param id byte array, containing zero to 255 bytes, or null
- * @param payload byte array, containing zero to (2 ** 32 - 1) bytes,
- * or null
- * @throws IllegalArugmentException if a valid record cannot be created
- */
- public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
- /* convert nulls */
- if (type == null) type = EMPTY_BYTE_ARRAY;
- if (id == null) id = EMPTY_BYTE_ARRAY;
- if (payload == null) payload = EMPTY_BYTE_ARRAY;
-
- String message = validateTnf(tnf, type, id, payload);
- if (message != null) {
- throw new IllegalArgumentException(message);
- }
-
- mTnf = tnf;
- mType = type;
- mId = id;
- mPayload = payload;
- }
-
- /**
- * Construct an NDEF Record from raw bytes.<p>
- * This method is deprecated, use {@link NdefMessage#NdefMessage(byte[])}
- * instead. This is because it does not make sense to parse a record:
- * the NDEF binary format is only defined for a message, and the
- * record flags MB and ME do not make sense outside of the context of
- * an entire message.<p>
- * This implementation will attempt to parse a single record by ignoring
- * the MB and ME flags, and otherwise following the rules of
- * {@link NdefMessage#NdefMessage(byte[])}.<p>
- *
- * @param data raw bytes to parse
- * @throws FormatException if the data cannot be parsed into a valid record
- * @deprecated use {@link NdefMessage#NdefMessage(byte[])} instead.
- */
- @Deprecated
- public NdefRecord(byte[] data) throws FormatException {
- ByteBuffer buffer = ByteBuffer.wrap(data);
- NdefRecord[] rs = parse(buffer, true);
-
- if (buffer.remaining() > 0) {
- throw new FormatException("data too long");
- }
-
- mTnf = rs[0].mTnf;
- mType = rs[0].mType;
- mId = rs[0].mId;
- mPayload = rs[0].mPayload;
- }
-
- /**
- * Returns the 3-bit TNF.
- * <p>
- * TNF is the top-level type.
- */
- public short getTnf() {
- return mTnf;
- }
-
- /**
- * Returns the variable length Type field.
- * <p>
- * This should be used in conjunction with the TNF field to determine the
- * payload format.
- * <p>
- * Returns an empty byte array if this record
- * does not have a type field.
- */
- public byte[] getType() {
- return mType.clone();
- }
-
- /**
- * Returns the variable length ID.
- * <p>
- * Returns an empty byte array if this record
- * does not have an id field.
- */
- public byte[] getId() {
- return mId.clone();
- }
-
- /**
- * Returns the variable length payload.
- * <p>
- * Returns an empty byte array if this record
- * does not have a payload field.
- */
- public byte[] getPayload() {
- return mPayload.clone();
- }
-
- /**
- * Return this NDEF Record as a byte array.<p>
- * This method is deprecated, use {@link NdefMessage#toByteArray}
- * instead. This is because the NDEF binary format is not defined for
- * a record outside of the context of a message: the MB and ME flags
- * cannot be set without knowing the location inside a message.<p>
- * This implementation will attempt to serialize a single record by
- * always setting the MB and ME flags (in other words, assume this
- * is a single-record NDEF Message).<p>
- *
- * @deprecated use {@link NdefMessage#toByteArray()} instead
- */
- @Deprecated
- public byte[] toByteArray() {
- ByteBuffer buffer = ByteBuffer.allocate(getByteLength());
- writeToByteBuffer(buffer, true, true);
- return buffer.array();
- }
-
- /**
- * Map this record to a MIME type, or return null if it cannot be mapped.<p>
- * Currently this method considers all {@link #TNF_MIME_MEDIA} records to
- * be MIME records, as well as some {@link #TNF_WELL_KNOWN} records such as
- * {@link #RTD_TEXT}. If this is a MIME record then the MIME type as string
- * is returned, otherwise null is returned.<p>
- * This method does not perform validation that the MIME type is
- * actually valid. It always attempts to
- * return a string containing the type if this is a MIME record.<p>
- * The returned MIME type will by normalized to lower-case using
- * {@link Intent#normalizeMimeType}.<p>
- * The MIME payload can be obtained using {@link #getPayload}.
- *
- * @return MIME type as a string, or null if this is not a MIME record
- */
- public String toMimeType() {
- switch (mTnf) {
- case NdefRecord.TNF_WELL_KNOWN:
- if (Arrays.equals(mType, NdefRecord.RTD_TEXT)) {
- return "text/plain";
- }
- break;
- case NdefRecord.TNF_MIME_MEDIA:
- String mimeType = new String(mType, StandardCharsets.US_ASCII);
- return Intent.normalizeMimeType(mimeType);
- }
- return null;
- }
-
- /**
- * Map this record to a URI, or return null if it cannot be mapped.<p>
- * Currently this method considers the following to be URI records:
- * <ul>
- * <li>{@link #TNF_ABSOLUTE_URI} records.</li>
- * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_URI}.</li>
- * <li>{@link #TNF_WELL_KNOWN} with a type of {@link #RTD_SMART_POSTER}
- * and containing a URI record in the NDEF message nested in the payload.
- * </li>
- * <li>{@link #TNF_EXTERNAL_TYPE} records.</li>
- * </ul>
- * If this is not a URI record by the above rules, then null is returned.<p>
- * This method does not perform validation that the URI is
- * actually valid: it always attempts to create and return a URI if
- * this record appears to be a URI record by the above rules.<p>
- * The returned URI will be normalized to have a lower case scheme
- * using {@link Uri#normalizeScheme}.<p>
- *
- * @return URI, or null if this is not a URI record
- */
- public Uri toUri() {
- return toUri(false);
- }
-
- private Uri toUri(boolean inSmartPoster) {
- switch (mTnf) {
- case TNF_WELL_KNOWN:
- if (Arrays.equals(mType, RTD_SMART_POSTER) && !inSmartPoster) {
- try {
- // check payload for a nested NDEF Message containing a URI
- NdefMessage nestedMessage = new NdefMessage(mPayload);
- for (NdefRecord nestedRecord : nestedMessage.getRecords()) {
- Uri uri = nestedRecord.toUri(true);
- if (uri != null) {
- return uri;
- }
- }
- } catch (FormatException e) { }
- } else if (Arrays.equals(mType, RTD_URI)) {
- Uri wktUri = parseWktUri();
- return (wktUri != null ? wktUri.normalizeScheme() : null);
- }
- break;
-
- case TNF_ABSOLUTE_URI:
- Uri uri = Uri.parse(new String(mType, StandardCharsets.UTF_8));
- return uri.normalizeScheme();
-
- case TNF_EXTERNAL_TYPE:
- if (inSmartPoster) {
- break;
- }
- return Uri.parse("vnd.android.nfc://ext/" + new String(mType, StandardCharsets.US_ASCII));
- }
- return null;
- }
-
- /**
- * Return complete URI of {@link #TNF_WELL_KNOWN}, {@link #RTD_URI} records.
- * @return complete URI, or null if invalid
- */
- private Uri parseWktUri() {
- if (mPayload.length < 2) {
- return null;
- }
-
- // payload[0] contains the URI Identifier Code, as per
- // NFC Forum "URI Record Type Definition" section 3.2.2.
- int prefixIndex = (mPayload[0] & (byte)0xFF);
- if (prefixIndex < 0 || prefixIndex >= URI_PREFIX_MAP.length) {
- return null;
- }
- String prefix = URI_PREFIX_MAP[prefixIndex];
- String suffix = new String(Arrays.copyOfRange(mPayload, 1, mPayload.length),
- StandardCharsets.UTF_8);
- return Uri.parse(prefix + suffix);
- }
-
- /**
- * Main record parsing method.<p>
- * Expects NdefMessage to begin immediately, allows trailing data.<p>
- * Currently has strict validation of all fields as per NDEF 1.0
- * specification section 2.5. We will attempt to keep this as strict as
- * possible to encourage well-formatted NDEF.<p>
- * Always returns 1 or more NdefRecord's, or throws FormatException.
- *
- * @param buffer ByteBuffer to read from
- * @param ignoreMbMe ignore MB and ME flags, and read only 1 complete record
- * @return one or more records
- * @throws FormatException on any parsing error
- */
- static NdefRecord[] parse(ByteBuffer buffer, boolean ignoreMbMe) throws FormatException {
- List<NdefRecord> records = new ArrayList<NdefRecord>();
-
- try {
- byte[] type = null;
- byte[] id = null;
- byte[] payload = null;
- ArrayList<byte[]> chunks = new ArrayList<byte[]>();
- boolean inChunk = false;
- short chunkTnf = -1;
- boolean me = false;
-
- while (!me) {
- byte flag = buffer.get();
-
- boolean mb = (flag & NdefRecord.FLAG_MB) != 0;
- me = (flag & NdefRecord.FLAG_ME) != 0;
- boolean cf = (flag & NdefRecord.FLAG_CF) != 0;
- boolean sr = (flag & NdefRecord.FLAG_SR) != 0;
- boolean il = (flag & NdefRecord.FLAG_IL) != 0;
- short tnf = (short)(flag & 0x07);
-
- if (!mb && records.size() == 0 && !inChunk && !ignoreMbMe) {
- throw new FormatException("expected MB flag");
- } else if (mb && (records.size() != 0 || inChunk) && !ignoreMbMe) {
- throw new FormatException("unexpected MB flag");
- } else if (inChunk && il) {
- throw new FormatException("unexpected IL flag in non-leading chunk");
- } else if (cf && me) {
- throw new FormatException("unexpected ME flag in non-trailing chunk");
- } else if (inChunk && tnf != NdefRecord.TNF_UNCHANGED) {
- throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
- } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
- throw new FormatException("" +
- "unexpected TNF_UNCHANGED in first chunk or unchunked record");
- }
-
- int typeLength = buffer.get() & 0xFF;
- long payloadLength = sr ? (buffer.get() & 0xFF) : (buffer.getInt() & 0xFFFFFFFFL);
- int idLength = il ? (buffer.get() & 0xFF) : 0;
-
- if (inChunk && typeLength != 0) {
- throw new FormatException("expected zero-length type in non-leading chunk");
- }
-
- if (!inChunk) {
- type = (typeLength > 0 ? new byte[typeLength] : EMPTY_BYTE_ARRAY);
- id = (idLength > 0 ? new byte[idLength] : EMPTY_BYTE_ARRAY);
- buffer.get(type);
- buffer.get(id);
- }
-
- ensureSanePayloadSize(payloadLength);
- payload = (payloadLength > 0 ? new byte[(int)payloadLength] : EMPTY_BYTE_ARRAY);
- buffer.get(payload);
-
- if (cf && !inChunk) {
- // first chunk
- if (typeLength == 0 && tnf != NdefRecord.TNF_UNKNOWN) {
- throw new FormatException("expected non-zero type length in first chunk");
- }
- chunks.clear();
- chunkTnf = tnf;
- }
- if (cf || inChunk) {
- // any chunk
- chunks.add(payload);
- }
- if (!cf && inChunk) {
- // last chunk, flatten the payload
- payloadLength = 0;
- for (byte[] p : chunks) {
- payloadLength += p.length;
- }
- ensureSanePayloadSize(payloadLength);
- payload = new byte[(int)payloadLength];
- int i = 0;
- for (byte[] p : chunks) {
- System.arraycopy(p, 0, payload, i, p.length);
- i += p.length;
- }
- tnf = chunkTnf;
- }
- if (cf) {
- // more chunks to come
- inChunk = true;
- continue;
- } else {
- inChunk = false;
- }
-
- String error = validateTnf(tnf, type, id, payload);
- if (error != null) {
- throw new FormatException(error);
- }
- records.add(new NdefRecord(tnf, type, id, payload));
- if (ignoreMbMe) { // for parsing a single NdefRecord
- break;
- }
- }
- } catch (BufferUnderflowException e) {
- throw new FormatException("expected more data", e);
- }
- return records.toArray(new NdefRecord[records.size()]);
- }
-
- private static void ensureSanePayloadSize(long size) throws FormatException {
- if (size > MAX_PAYLOAD_SIZE) {
- throw new FormatException(
- "payload above max limit: " + size + " > " + MAX_PAYLOAD_SIZE);
- }
- }
-
- /**
- * Perform simple validation that the tnf is valid.<p>
- * Validates the requirements of NFCForum-TS-NDEF_1.0 section
- * 3.2.6 (Type Name Format). This just validates that the tnf
- * is valid, and that the relevant type, id and payload
- * fields are present (or empty) for this tnf. It does not
- * perform any deep inspection of the type, id and payload fields.<p>
- * Also does not allow TNF_UNCHANGED since this class is only used
- * to present logical (unchunked) records.
- *
- * @return null if valid, or a string error if invalid.
- */
- static String validateTnf(short tnf, byte[] type, byte[] id, byte[] payload) {
- switch (tnf) {
- case TNF_EMPTY:
- if (type.length != 0 || id.length != 0 || payload.length != 0) {
- return "unexpected data in TNF_EMPTY record";
- }
- return null;
- case TNF_WELL_KNOWN:
- case TNF_MIME_MEDIA:
- case TNF_ABSOLUTE_URI:
- case TNF_EXTERNAL_TYPE:
- return null;
- case TNF_UNKNOWN:
- case TNF_RESERVED:
- if (type.length != 0) {
- return "unexpected type field in TNF_UNKNOWN or TNF_RESERVEd record";
- }
- return null;
- case TNF_UNCHANGED:
- return "unexpected TNF_UNCHANGED in first chunk or logical record";
- default:
- return String.format("unexpected tnf value: 0x%02x", tnf);
- }
- }
-
- /**
- * Serialize record for network transmission.<p>
- * Uses specified MB and ME flags.<p>
- * Does not chunk records.
- */
- void writeToByteBuffer(ByteBuffer buffer, boolean mb, boolean me) {
- boolean sr = mPayload.length < 256;
- boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
- byte flags = (byte)((mb ? FLAG_MB : 0) | (me ? FLAG_ME : 0) |
- (sr ? FLAG_SR : 0) | (il ? FLAG_IL : 0) | mTnf);
- buffer.put(flags);
-
- buffer.put((byte)mType.length);
- if (sr) {
- buffer.put((byte)mPayload.length);
- } else {
- buffer.putInt(mPayload.length);
- }
- if (il) {
- buffer.put((byte)mId.length);
- }
-
- buffer.put(mType);
- buffer.put(mId);
- buffer.put(mPayload);
- }
-
- /**
- * Get byte length of serialized record.
- */
- int getByteLength() {
- int length = 3 + mType.length + mId.length + mPayload.length;
-
- boolean sr = mPayload.length < 256;
- boolean il = mTnf == TNF_EMPTY ? true : mId.length > 0;
-
- if (!sr) length += 3;
- if (il) length += 1;
-
- return length;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mTnf);
- dest.writeInt(mType.length);
- dest.writeByteArray(mType);
- dest.writeInt(mId.length);
- dest.writeByteArray(mId);
- dest.writeInt(mPayload.length);
- dest.writeByteArray(mPayload);
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<NdefRecord> CREATOR =
- new Parcelable.Creator<NdefRecord>() {
- @Override
- public NdefRecord createFromParcel(Parcel in) {
- short tnf = (short)in.readInt();
- int typeLength = in.readInt();
- byte[] type = new byte[typeLength];
- in.readByteArray(type);
- int idLength = in.readInt();
- byte[] id = new byte[idLength];
- in.readByteArray(id);
- int payloadLength = in.readInt();
- byte[] payload = new byte[payloadLength];
- in.readByteArray(payload);
-
- return new NdefRecord(tnf, type, id, payload);
- }
- @Override
- public NdefRecord[] newArray(int size) {
- return new NdefRecord[size];
- }
- };
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Arrays.hashCode(mId);
- result = prime * result + Arrays.hashCode(mPayload);
- result = prime * result + mTnf;
- result = prime * result + Arrays.hashCode(mType);
- return result;
- }
-
- /**
- * Returns true if the specified NDEF Record contains
- * identical tnf, type, id and payload fields.
- */
- @Override
- public boolean equals(@Nullable Object obj) {
- if (this == obj) return true;
- if (obj == null) return false;
- if (getClass() != obj.getClass()) return false;
- NdefRecord other = (NdefRecord) obj;
- if (!Arrays.equals(mId, other.mId)) return false;
- if (!Arrays.equals(mPayload, other.mPayload)) return false;
- if (mTnf != other.mTnf) return false;
- return Arrays.equals(mType, other.mType);
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder(String.format("NdefRecord tnf=%X", mTnf));
- if (mType.length > 0) b.append(" type=").append(bytesToString(mType));
- if (mId.length > 0) b.append(" id=").append(bytesToString(mId));
- if (mPayload.length > 0) b.append(" payload=").append(bytesToString(mPayload));
- return b.toString();
- }
-
- /**
- * Dump debugging information as a NdefRecordProto
- * @hide
- *
- * Note:
- * See proto definition in frameworks/base/core/proto/android/nfc/ndef.proto
- * When writing a nested message, must call {@link ProtoOutputStream#start(long)} before and
- * {@link ProtoOutputStream#end(long)} after.
- * Never reuse a proto field number. When removing a field, mark it as reserved.
- */
- public void dumpDebug(ProtoOutputStream proto) {
- proto.write(NdefRecordProto.TYPE, mType);
- proto.write(NdefRecordProto.ID, mId);
- proto.write(NdefRecordProto.PAYLOAD_BYTES, mPayload.length);
- }
-
- private static StringBuilder bytesToString(byte[] bs) {
- StringBuilder s = new StringBuilder();
- for (byte b : bs) {
- s.append(String.format("%02X", b));
- }
- return s;
- }
-}
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
deleted file mode 100644
index 909eca7b0c9d..000000000000
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.app.Activity;
-import android.app.Application;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.nfc.NfcAdapter.ReaderCallback;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Manages NFC API's that are coupled to the life-cycle of an Activity.
- *
- * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
- * into activity life-cycle events such as onPause() and onResume().
- *
- * @hide
- */
-public final class NfcActivityManager extends IAppCallback.Stub
- implements Application.ActivityLifecycleCallbacks {
- static final String TAG = NfcAdapter.TAG;
- static final Boolean DBG = false;
-
- @UnsupportedAppUsage
- final NfcAdapter mAdapter;
-
- // All objects in the lists are protected by this
- final List<NfcApplicationState> mApps; // Application(s) that have NFC state. Usually one
- final List<NfcActivityState> mActivities; // Activities that have NFC state
-
- /**
- * NFC State associated with an {@link Application}.
- */
- class NfcApplicationState {
- int refCount = 0;
- final Application app;
- public NfcApplicationState(Application app) {
- this.app = app;
- }
- public void register() {
- refCount++;
- if (refCount == 1) {
- this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
- }
- }
- public void unregister() {
- refCount--;
- if (refCount == 0) {
- this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
- } else if (refCount < 0) {
- Log.e(TAG, "-ve refcount for " + app);
- }
- }
- }
-
- NfcApplicationState findAppState(Application app) {
- for (NfcApplicationState appState : mApps) {
- if (appState.app == app) {
- return appState;
- }
- }
- return null;
- }
-
- void registerApplication(Application app) {
- NfcApplicationState appState = findAppState(app);
- if (appState == null) {
- appState = new NfcApplicationState(app);
- mApps.add(appState);
- }
- appState.register();
- }
-
- void unregisterApplication(Application app) {
- NfcApplicationState appState = findAppState(app);
- if (appState == null) {
- Log.e(TAG, "app was not registered " + app);
- return;
- }
- appState.unregister();
- }
-
- /**
- * NFC state associated with an {@link Activity}
- */
- class NfcActivityState {
- boolean resumed = false;
- Activity activity;
- NfcAdapter.ReaderCallback readerCallback = null;
- int readerModeFlags = 0;
- Bundle readerModeExtras = null;
- Binder token;
-
- int mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
- int mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
-
- public NfcActivityState(Activity activity) {
- if (activity.isDestroyed()) {
- throw new IllegalStateException("activity is already destroyed");
- }
- // Check if activity is resumed right now, as we will not
- // immediately get a callback for that.
- resumed = activity.isResumed();
-
- this.activity = activity;
- this.token = new Binder();
- registerApplication(activity.getApplication());
- }
- public void destroy() {
- unregisterApplication(activity.getApplication());
- resumed = false;
- activity = null;
- readerCallback = null;
- readerModeFlags = 0;
- readerModeExtras = null;
- token = null;
-
- mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
- mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
- }
- @Override
- public String toString() {
- StringBuilder s = new StringBuilder("[");
- s.append(readerCallback);
- s.append("]");
- return s.toString();
- }
- }
-
- /** find activity state from mActivities */
- synchronized NfcActivityState findActivityState(Activity activity) {
- for (NfcActivityState state : mActivities) {
- if (state.activity == activity) {
- return state;
- }
- }
- return null;
- }
-
- /** find or create activity state from mActivities */
- synchronized NfcActivityState getActivityState(Activity activity) {
- NfcActivityState state = findActivityState(activity);
- if (state == null) {
- state = new NfcActivityState(activity);
- mActivities.add(state);
- }
- return state;
- }
-
- synchronized NfcActivityState findResumedActivityState() {
- for (NfcActivityState state : mActivities) {
- if (state.resumed) {
- return state;
- }
- }
- return null;
- }
-
- synchronized void destroyActivityState(Activity activity) {
- NfcActivityState activityState = findActivityState(activity);
- if (activityState != null) {
- activityState.destroy();
- mActivities.remove(activityState);
- }
- }
-
- public NfcActivityManager(NfcAdapter adapter) {
- mAdapter = adapter;
- mActivities = new LinkedList<NfcActivityState>();
- mApps = new ArrayList<NfcApplicationState>(1); // Android VM usually has 1 app
- }
-
- public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
- Bundle extras) {
- boolean isResumed;
- Binder token;
- int pollTech, listenTech;
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = getActivityState(activity);
- state.readerCallback = callback;
- state.readerModeFlags = flags;
- state.readerModeExtras = extras;
- pollTech = state.mPollTech;
- listenTech = state.mListenTech;
- token = state.token;
- isResumed = state.resumed;
- }
- if (isResumed) {
- if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
- || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
- throw new IllegalStateException(
- "Cannot be used when alternative DiscoveryTechnology is set");
- } else {
- setReaderMode(token, flags, extras);
- }
- }
- }
-
- public void disableReaderMode(Activity activity) {
- boolean isResumed;
- Binder token;
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = getActivityState(activity);
- state.readerCallback = null;
- state.readerModeFlags = 0;
- state.readerModeExtras = null;
- token = state.token;
- isResumed = state.resumed;
- }
- if (isResumed) {
- setReaderMode(token, 0, null);
- }
-
- }
-
- public void setReaderMode(Binder token, int flags, Bundle extras) {
- if (DBG) Log.d(TAG, "Setting reader mode");
- NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(
- token, this, flags, extras, mAdapter.getContext().getPackageName()));
- }
-
- /**
- * Request or unrequest NFC service callbacks.
- * Makes IPC call - do not hold lock.
- */
- void requestNfcServiceCallback() {
- NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this));
- }
-
- void verifyNfcPermission() {
- NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission());
- }
-
- @Override
- public void onTagDiscovered(Tag tag) throws RemoteException {
- NfcAdapter.ReaderCallback callback;
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = findResumedActivityState();
- if (state == null) return;
-
- callback = state.readerCallback;
- }
-
- // Make callback without lock
- if (callback != null) {
- callback.onTagDiscovered(tag);
- }
-
- }
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityStarted(Activity activity) { /* NO-OP */ }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityResumed(Activity activity) {
- int readerModeFlags = 0;
- Bundle readerModeExtras = null;
- Binder token;
- int pollTech;
- int listenTech;
-
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = findActivityState(activity);
- if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
- if (state == null) return;
- state.resumed = true;
- token = state.token;
- readerModeFlags = state.readerModeFlags;
- readerModeExtras = state.readerModeExtras;
-
- pollTech = state.mPollTech;
- listenTech = state.mListenTech;
- }
- if (readerModeFlags != 0) {
- setReaderMode(token, readerModeFlags, readerModeExtras);
- } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
- || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
- changeDiscoveryTech(token, pollTech, listenTech);
- }
- requestNfcServiceCallback();
- }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityPaused(Activity activity) {
- boolean readerModeFlagsSet;
- Binder token;
- int pollTech;
- int listenTech;
-
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = findActivityState(activity);
- if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
- if (state == null) return;
- state.resumed = false;
- token = state.token;
- readerModeFlagsSet = state.readerModeFlags != 0;
-
- pollTech = state.mPollTech;
- listenTech = state.mListenTech;
- }
- if (readerModeFlagsSet) {
- // Restore default p2p modes
- setReaderMode(token, 0, null);
- } else if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
- || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
- changeDiscoveryTech(token,
- NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
- }
- }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityStopped(Activity activity) { /* NO-OP */ }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
-
- /** Callback from Activity life-cycle, on main thread */
- @Override
- public void onActivityDestroyed(Activity activity) {
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = findActivityState(activity);
- if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
- if (state != null) {
- // release all associated references
- destroyActivityState(activity);
- }
- }
- }
-
- /** setDiscoveryTechnology() implementation */
- public void setDiscoveryTech(Activity activity, int pollTech, int listenTech) {
- boolean isResumed;
- Binder token;
- boolean readerModeFlagsSet;
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = getActivityState(activity);
- readerModeFlagsSet = state.readerModeFlags != 0;
- state.mListenTech = listenTech;
- state.mPollTech = pollTech;
- token = state.token;
- isResumed = state.resumed;
- }
- if (!readerModeFlagsSet && isResumed) {
- changeDiscoveryTech(token, pollTech, listenTech);
- } else if (readerModeFlagsSet) {
- throw new IllegalStateException("Cannot be used when the Reader Mode is enabled");
- }
- }
-
- /** resetDiscoveryTechnology() implementation */
- public void resetDiscoveryTech(Activity activity) {
- boolean isResumed;
- Binder token;
- boolean readerModeFlagsSet;
- synchronized (NfcActivityManager.this) {
- NfcActivityState state = getActivityState(activity);
- state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
- state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
- token = state.token;
- isResumed = state.resumed;
- }
- if (isResumed) {
- changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
- }
-
- }
-
- private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
- NfcAdapter.callService(
- () -> NfcAdapter.sService.updateDiscoveryTechnology(
- token, pollTech, listenTech, mAdapter.getContext().getPackageName()));
- }
-
-}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
deleted file mode 100644
index 89ce4239cd4d..000000000000
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ /dev/null
@@ -1,2944 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.Uri;
-import android.nfc.cardemulation.PollingFrame;
-import android.nfc.tech.MifareClassic;
-import android.nfc.tech.Ndef;
-import android.nfc.tech.NfcA;
-import android.nfc.tech.NfcF;
-import android.os.Binder;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-/**
- * Represents the local NFC adapter.
- * <p>
- * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC
- * adapter for this Android device.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * <p>To perform basic file sharing between devices, read
- * <a href="{@docRoot}training/beam-files/index.html">Sharing Files with NFC</a>.
- * </div>
- */
-public final class NfcAdapter {
- static final String TAG = "NFC";
-
- private final NfcControllerAlwaysOnListener mControllerAlwaysOnListener;
- private final NfcWlcStateListener mNfcWlcStateListener;
- private final NfcVendorNciCallbackListener mNfcVendorNciCallbackListener;
-
- /**
- * Intent to start an activity when a tag with NDEF payload is discovered.
- *
- * <p>The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and
- * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the
- * intent will contain the URI in its data field. If a MIME record is found the intent will
- * contain the MIME type in its type field. This allows activities to register
- * {@link IntentFilter}s targeting specific content on tags. Activities should register the
- * most specific intent filters possible to avoid the activity chooser dialog, which can
- * disrupt the interaction with the tag as the user interacts with the screen.
- *
- * <p>If the tag has an NDEF payload this intent is started before
- * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither
- * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
- *
- * <p>The MIME type or data URI of this intent are normalized before dispatch -
- * so that MIME, URI scheme and URI host are always lower-case.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
-
- /**
- * Intent to start an activity when a tag is discovered and activities are registered for the
- * specific technologies on the tag.
- *
- * <p>To receive this intent an activity must include an intent filter
- * for this action and specify the desired tech types in a
- * manifest <code>meta-data</code> entry. Here is an example manfiest entry:
- * <pre>
- * &lt;activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"&gt;
- * &lt;!-- Add a technology filter --&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.action.TECH_DISCOVERED" /&gt;
- * &lt;/intent-filter&gt;
- *
- * &lt;meta-data android:name="android.nfc.action.TECH_DISCOVERED"
- * android:resource="@xml/filter_nfc"
- * /&gt;
- * &lt;/activity&gt;</pre>
- *
- * <p>The meta-data XML file should contain one or more <code>tech-list</code> entries
- * each consisting or one or more <code>tech</code> entries. The <code>tech</code> entries refer
- * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA".
- *
- * <p>A tag matches if any of the
- * <code>tech-list</code> sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each
- * of the <code>tech-list</code>s is considered independently and the
- * activity is considered a match is any single <code>tech-list</code> matches the tag that was
- * discovered. This provides AND and OR semantics for filtering desired techs. Here is an
- * example that will match any tag using {@link NfcF} or any tag using {@link NfcA},
- * {@link MifareClassic}, and {@link Ndef}:
- *
- * <pre>
- * &lt;resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"&gt;
- * &lt;!-- capture anything using NfcF --&gt;
- * &lt;tech-list&gt;
- * &lt;tech&gt;android.nfc.tech.NfcF&lt;/tech&gt;
- * &lt;/tech-list&gt;
- *
- * &lt;!-- OR --&gt;
- *
- * &lt;!-- capture all MIFARE Classics with NDEF payloads --&gt;
- * &lt;tech-list&gt;
- * &lt;tech&gt;android.nfc.tech.NfcA&lt;/tech&gt;
- * &lt;tech&gt;android.nfc.tech.MifareClassic&lt;/tech&gt;
- * &lt;tech&gt;android.nfc.tech.Ndef&lt;/tech&gt;
- * &lt;/tech-list&gt;
- * &lt;/resources&gt;</pre>
- *
- * <p>This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
- * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED}
- * this intent will not be started. If any activities respond to this intent
- * {@link #ACTION_TAG_DISCOVERED} will not be started.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
-
- /**
- * Intent to start an activity when a tag is discovered.
- *
- * <p>This intent will not be started when a tag is discovered if any activities respond to
- * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
-
- /**
- * Broadcast Action: Intent to notify an application that a transaction event has occurred
- * on the Secure Element.
- *
- * <p>This intent will only be sent if the application has requested permission for
- * {@link android.Manifest.permission#NFC_TRANSACTION_EVENT} and if the application has the
- * necessary access to Secure Element which witnessed the particular event.
- */
- @RequiresPermission(android.Manifest.permission.NFC_TRANSACTION_EVENT)
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TRANSACTION_DETECTED =
- "android.nfc.action.TRANSACTION_DETECTED";
-
- /**
- * Broadcast Action: Intent to notify if the preferred payment service changed.
- *
- * <p>This intent will only be sent to the application has requested permission for
- * {@link android.Manifest.permission#NFC_PREFERRED_PAYMENT_INFO} and if the application
- * has the necessary access to Secure Element which witnessed the particular event.
- */
- @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PREFERRED_PAYMENT_CHANGED =
- "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
-
- /**
- * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
- * @hide
- */
- public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST";
-
- /**
- * Mandatory extra containing the {@link Tag} that was discovered for the
- * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
- * {@link #ACTION_TAG_DISCOVERED} intents.
- */
- public static final String EXTRA_TAG = "android.nfc.extra.TAG";
-
- /**
- * Extra containing an array of {@link NdefMessage} present on the discovered tag.<p>
- * This extra is mandatory for {@link #ACTION_NDEF_DISCOVERED} intents,
- * and optional for {@link #ACTION_TECH_DISCOVERED}, and
- * {@link #ACTION_TAG_DISCOVERED} intents.<p>
- * When this extra is present there will always be at least one
- * {@link NdefMessage} element. Most NDEF tags have only one NDEF message,
- * but we use an array for future compatibility.
- */
- public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
-
- /**
- * Optional extra containing a byte array containing the ID of the discovered tag for
- * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and
- * {@link #ACTION_TAG_DISCOVERED} intents.
- */
- public static final String EXTRA_ID = "android.nfc.extra.ID";
-
- /**
- * Broadcast Action: The state of the local NFC adapter has been
- * changed.
- * <p>For example, NFC has been turned on or off.
- * <p>Always contains the extra field {@link #EXTRA_ADAPTER_STATE}
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_ADAPTER_STATE_CHANGED =
- "android.nfc.action.ADAPTER_STATE_CHANGED";
-
- /**
- * Used as an int extra field in {@link #ACTION_ADAPTER_STATE_CHANGED}
- * intents to request the current power state. Possible values are:
- * {@link #STATE_OFF},
- * {@link #STATE_TURNING_ON},
- * {@link #STATE_ON},
- * {@link #STATE_TURNING_OFF},
- */
- public static final String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
-
- /**
- * Mandatory byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
- */
- public static final String EXTRA_AID = "android.nfc.extra.AID";
-
- /**
- * Optional byte[] extra field in {@link #ACTION_TRANSACTION_DETECTED}
- */
- public static final String EXTRA_DATA = "android.nfc.extra.DATA";
-
- /**
- * Mandatory String extra field in {@link #ACTION_TRANSACTION_DETECTED}
- * Indicates the Secure Element on which the transaction occurred.
- * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC/EUICC, etc.
- */
- public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME";
-
- /**
- * Mandatory String extra field in {@link #ACTION_PREFERRED_PAYMENT_CHANGED}
- * Indicates the condition when trigger this event. Possible values are:
- * {@link #PREFERRED_PAYMENT_LOADED},
- * {@link #PREFERRED_PAYMENT_CHANGED},
- * {@link #PREFERRED_PAYMENT_UPDATED},
- */
- public static final String EXTRA_PREFERRED_PAYMENT_CHANGED_REASON =
- "android.nfc.extra.PREFERRED_PAYMENT_CHANGED_REASON";
- /**
- * Nfc is enabled and the preferred payment aids are registered.
- */
- public static final int PREFERRED_PAYMENT_LOADED = 1;
- /**
- * User selected another payment application as the preferred payment.
- */
- public static final int PREFERRED_PAYMENT_CHANGED = 2;
- /**
- * Current preferred payment has issued an update (registered/unregistered new aids or has been
- * updated itself).
- */
- public static final int PREFERRED_PAYMENT_UPDATED = 3;
-
- public static final int STATE_OFF = 1;
- public static final int STATE_TURNING_ON = 2;
- public static final int STATE_ON = 3;
- public static final int STATE_TURNING_OFF = 4;
-
- /**
- * Possible states from {@link #getAdapterState}.
- *
- * @hide
- */
- @IntDef(prefix = { "STATE_" }, value = {
- STATE_OFF,
- STATE_TURNING_ON,
- STATE_ON,
- STATE_TURNING_OFF
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface AdapterState{}
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag enables polling for Nfc-A technology.
- */
- public static final int FLAG_READER_NFC_A = 0x1;
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag enables polling for Nfc-B technology.
- */
- public static final int FLAG_READER_NFC_B = 0x2;
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag enables polling for Nfc-F technology.
- */
- public static final int FLAG_READER_NFC_F = 0x4;
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag enables polling for Nfc-V (ISO15693) technology.
- */
- public static final int FLAG_READER_NFC_V = 0x8;
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag enables polling for NfcBarcode technology.
- */
- public static final int FLAG_READER_NFC_BARCODE = 0x10;
-
- /** @hide */
- @IntDef(flag = true, value = {
- FLAG_SET_DEFAULT_TECH,
- FLAG_READER_KEEP,
- FLAG_READER_DISABLE,
- FLAG_READER_NFC_A,
- FLAG_READER_NFC_B,
- FLAG_READER_NFC_F,
- FLAG_READER_NFC_V,
- FLAG_READER_NFC_BARCODE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface PollTechnology {}
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag allows the caller to prevent the
- * platform from performing an NDEF check on the tags it
- * finds.
- */
- public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
-
- /**
- * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this flag allows the caller to prevent the
- * platform from playing sounds when it discovers a tag.
- */
- public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
-
- /**
- * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
- * <p>
- * Setting this integer extra allows the calling application to specify
- * the delay that the platform will use for performing presence checks
- * on any discovered tag.
- */
- public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
-
- /**
- * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag enables listening for Nfc-A technology.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_LISTEN_NFC_PASSIVE_A = 0x1;
-
- /**
- * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag enables listening for Nfc-B technology.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_LISTEN_NFC_PASSIVE_B = 1 << 1;
-
- /**
- * Flag for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag enables listening for Nfc-F technology.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_LISTEN_NFC_PASSIVE_F = 1 << 2;
-
- /**
- * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag disables listening.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_LISTEN_DISABLE = 0x0;
-
- /**
- * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag disables polling.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_READER_DISABLE = 0x0;
-
- /**
- * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag makes listening to keep the current technology configuration.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_LISTEN_KEEP = 0x80000000;
-
- /**
- * Flags for use with {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag makes polling to keep the current technology configuration.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public static final int FLAG_READER_KEEP = 0x80000000;
-
- /** @hide */
- public static final int FLAG_USE_ALL_TECH = 0xff;
-
- /** @hide */
- @IntDef(flag = true, value = {
- FLAG_SET_DEFAULT_TECH,
- FLAG_LISTEN_KEEP,
- FLAG_LISTEN_DISABLE,
- FLAG_LISTEN_NFC_PASSIVE_A,
- FLAG_LISTEN_NFC_PASSIVE_B,
- FLAG_LISTEN_NFC_PASSIVE_F
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ListenTechnology {}
-
- /**
- * Flag used in {@link #setDiscoveryTechnology(Activity, int, int)}.
- * <p>
- * Setting this flag changes the default listen or poll tech.
- * Only available to privileged apps.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH)
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public static final int FLAG_SET_DEFAULT_TECH = 0x40000000;
-
- /**
- * @hide
- * @removed
- */
- @SystemApi
- @UnsupportedAppUsage
- public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
-
- /** @hide */
- public static final String ACTION_HANDOVER_TRANSFER_STARTED =
- "android.nfc.action.HANDOVER_TRANSFER_STARTED";
-
- /** @hide */
- public static final String ACTION_HANDOVER_TRANSFER_DONE =
- "android.nfc.action.HANDOVER_TRANSFER_DONE";
-
- /** @hide */
- public static final String EXTRA_HANDOVER_TRANSFER_STATUS =
- "android.nfc.extra.HANDOVER_TRANSFER_STATUS";
-
- /** @hide */
- public static final int HANDOVER_TRANSFER_STATUS_SUCCESS = 0;
- /** @hide */
- public static final int HANDOVER_TRANSFER_STATUS_FAILURE = 1;
-
- /** @hide */
- public static final String EXTRA_HANDOVER_TRANSFER_URI =
- "android.nfc.extra.HANDOVER_TRANSFER_URI";
-
- /**
- * Broadcast Action: Notify possible NFC transaction blocked because device is locked.
- * <p>An external NFC field detected when device locked and SecureNfc enabled.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- public static final String ACTION_REQUIRE_UNLOCK_FOR_NFC =
- "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC";
-
- /**
- * Intent action to start a NFC resolver activity in a customized share session with list of
- * {@link ResolveInfo}.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- @RequiresPermission(Manifest.permission.SHOW_CUSTOMIZED_RESOLVER)
- public static final String ACTION_SHOW_NFC_RESOLVER = "android.nfc.action.SHOW_NFC_RESOLVER";
-
- /**
- * "Extras" key for an ArrayList of {@link ResolveInfo} records which are to be shown as the
- * targets in the customized share session.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- public static final String EXTRA_RESOLVE_INFOS = "android.nfc.extra.RESOLVE_INFOS";
-
- /**
- * The requested app is correctly added to the Tag intent app preference.
- *
- * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
- * @hide
- */
- @SystemApi
- public static final int TAG_INTENT_APP_PREF_RESULT_SUCCESS = 0;
-
- /**
- * The requested app is not installed on the device.
- *
- * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
- * @hide
- */
- @SystemApi
- public static final int TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND = -1;
-
- /**
- * The NfcService is not available.
- *
- * @see #setTagIntentAppPreferenceForUser(int userId, String pkg, boolean allow)
- * @hide
- */
- @SystemApi
- public static final int TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE = -2;
-
- /**
- * Possible response codes from {@link #setTagIntentAppPreferenceForUser}.
- *
- * @hide
- */
- @IntDef(prefix = { "TAG_INTENT_APP_PREF_RESULT" }, value = {
- TAG_INTENT_APP_PREF_RESULT_SUCCESS,
- TAG_INTENT_APP_PREF_RESULT_PACKAGE_NOT_FOUND,
- TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface TagIntentAppPreferenceResult {}
-
- /**
- * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
- * @hide
- */
- public static final int CONTROLLER_ALWAYS_ON_MODE_DEFAULT = 1;
-
- /**
- * Mode Type for {@link NfcOemExtension#setControllerAlwaysOnMode(int)}.
- * @hide
- */
- public static final int CONTROLLER_ALWAYS_ON_DISABLE = 0;
-
- // Guarded by sLock
- static boolean sIsInitialized = false;
- static boolean sHasNfcFeature;
- static boolean sHasCeFeature;
- static boolean sHasNfcWlcFeature;
-
- static Object sLock = new Object();
-
- // Final after first constructor, except for
- // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
- // recovery
- @UnsupportedAppUsage
- static INfcAdapter sService;
- static NfcServiceManager.ServiceRegisterer sServiceRegisterer;
- static INfcTag sTagService;
- static INfcCardEmulation sCardEmulationService;
- static INfcFCardEmulation sNfcFCardEmulationService;
- static IT4tNdefNfcee sNdefNfceeService;
-
- /**
- * The NfcAdapter object for each application context.
- * There is a 1-1 relationship between application context and
- * NfcAdapter object.
- */
- static HashMap<Context, NfcAdapter> sNfcAdapters = new HashMap(); //guard by NfcAdapter.class
-
- /**
- * NfcAdapter used with a null context. This ctor was deprecated but we have
- * to support it for backwards compatibility. New methods that require context
- * might throw when called on the null-context NfcAdapter.
- */
- static NfcAdapter sNullContextNfcAdapter; // protected by NfcAdapter.class
-
- final NfcActivityManager mNfcActivityManager;
- final Context mContext;
- final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers;
- final Object mLock;
- final NfcOemExtension mNfcOemExtension;
-
- ITagRemovedCallback mTagRemovedListener; // protected by mLock
-
- /**
- * A callback to be invoked when the system finds a tag while the foreground activity is
- * operating in reader mode.
- * <p>Register your {@code ReaderCallback} implementation with {@link
- * NfcAdapter#enableReaderMode} and disable it with {@link
- * NfcAdapter#disableReaderMode}.
- * @see NfcAdapter#enableReaderMode
- */
- public interface ReaderCallback {
- public void onTagDiscovered(Tag tag);
- }
-
- /**
- * A listener to be invoked when NFC controller always on state changes.
- * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
- * NfcAdapter#registerControllerAlwaysOnListener} and disable it with {@link
- * NfcAdapter#unregisterControllerAlwaysOnListener}.
- * @see #registerControllerAlwaysOnListener
- * @hide
- */
- @SystemApi
- public interface ControllerAlwaysOnListener {
- /**
- * Called on NFC controller always on state changes
- */
- void onControllerAlwaysOnChanged(boolean isEnabled);
- }
-
- /**
- * A callback to be invoked when the system successfully delivers your {@link NdefMessage}
- * to another device.
- * @deprecated this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- public interface OnNdefPushCompleteCallback {
- /**
- * Called on successful NDEF push.
- *
- * <p>This callback is usually made on a binder thread (not the UI thread).
- *
- * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
- */
- public void onNdefPushComplete(NfcEvent event);
- }
-
- /**
- * A callback to be invoked when another NFC device capable of NDEF push (Android Beam)
- * is within range.
- * <p>Implement this interface and pass it to {@code
- * NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()} in order to create an
- * {@link NdefMessage} at the moment that another device is within range for NFC. Using this
- * callback allows you to create a message with data that might vary based on the
- * content currently visible to the user. Alternatively, you can call {@code
- * #setNdefPushMessage setNdefPushMessage()} if the {@link NdefMessage} always contains the
- * same data.
- * @deprecated this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- public interface CreateNdefMessageCallback {
- /**
- * Called to provide a {@link NdefMessage} to push.
- *
- * <p>This callback is usually made on a binder thread (not the UI thread).
- *
- * <p>Called when this device is in range of another device
- * that might support NDEF push. It allows the application to
- * create the NDEF message only when it is required.
- *
- * <p>NDEF push cannot occur until this method returns, so do not
- * block for too long.
- *
- * <p>The Android operating system will usually show a system UI
- * on top of your activity during this time, so do not try to request
- * input from the user to complete the callback, or provide custom NDEF
- * push UI. The user probably will not see it.
- *
- * @param event {@link NfcEvent} with the {@link NfcEvent#nfcAdapter} field set
- * @return NDEF message to push, or null to not provide a message
- */
- public NdefMessage createNdefMessage(NfcEvent event);
- }
-
-
- /**
- * @deprecated this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- public interface CreateBeamUrisCallback {
- public Uri[] createBeamUris(NfcEvent event);
- }
-
- /**
- * A callback that is invoked when a tag is removed from the field.
- * @see NfcAdapter#ignore
- */
- public interface OnTagRemovedListener {
- void onTagRemoved();
- }
-
- /**
- * A callback to be invoked when an application has registered as a
- * handler to unlock the device given an NFC tag at the lockscreen.
- * @hide
- */
- @SystemApi
- public interface NfcUnlockHandler {
- /**
- * Called at the lock screen to attempt to unlock the device with the given tag.
- * @param tag the detected tag, to be used to unlock the device
- * @return true if the device was successfully unlocked
- */
- public boolean onUnlockAttempted(Tag tag);
- }
-
- /**
- * Return list of Secure Elements which support off host card emulation.
- *
- * @return List<String> containing secure elements on the device which supports
- * off host card emulation. eSE for Embedded secure element,
- * SIM for UICC/EUICC and so on.
- * @hide
- */
- public @NonNull List<String> getSupportedOffHostSecureElements() {
- if (mContext == null) {
- throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
- + " getSupportedOffHostSecureElements APIs");
- }
- List<String> offHostSE = new ArrayList<String>();
- PackageManager pm = mContext.getPackageManager();
- if (pm == null) {
- Log.e(TAG, "Cannot get package manager, assuming no off-host CE feature");
- return offHostSE;
- }
- if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)) {
- offHostSE.add("SIM");
- }
- if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)) {
- offHostSE.add("eSE");
- }
- return offHostSE;
- }
-
- private static void retrieveServiceRegisterer() {
- if (sServiceRegisterer == null) {
- NfcServiceManager manager = NfcFrameworkInitializer.getNfcServiceManager();
- if (manager == null) {
- Log.e(TAG, "NfcServiceManager is null");
- throw new UnsupportedOperationException();
- }
- sServiceRegisterer = manager.getNfcManagerServiceRegisterer();
- }
- }
-
- /**
- * Returns the NfcAdapter for application context,
- * or throws if NFC is not available.
- * @hide
- */
- @UnsupportedAppUsage
- public static synchronized NfcAdapter getNfcAdapter(Context context) {
- if (context == null) {
- if (sNullContextNfcAdapter == null) {
- sNullContextNfcAdapter = new NfcAdapter(null);
- }
- return sNullContextNfcAdapter;
- }
- if (!sIsInitialized) {
- PackageManager pm;
- pm = context.getPackageManager();
- sHasNfcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC);
- sHasCeFeature =
- pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
- || pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)
- || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC)
- || pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE);
- sHasNfcWlcFeature = pm.hasSystemFeature(PackageManager.FEATURE_NFC_CHARGING);
- /* is this device meant to have NFC */
- if (!sHasNfcFeature && !sHasCeFeature && !sHasNfcWlcFeature) {
- Log.v(TAG, "this device does not have NFC support");
- throw new UnsupportedOperationException();
- }
- retrieveServiceRegisterer();
- sService = getServiceInterface();
- if (sService == null) {
- Log.e(TAG, "could not retrieve NFC service");
- throw new UnsupportedOperationException();
- }
- if (sHasNfcFeature) {
- try {
- sTagService = sService.getNfcTagInterface();
- } catch (RemoteException e) {
- sTagService = null;
- Log.e(TAG, "could not retrieve NFC Tag service");
- throw new UnsupportedOperationException();
- }
- }
- if (sHasCeFeature) {
- try {
- sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
- } catch (RemoteException e) {
- sNfcFCardEmulationService = null;
- Log.e(TAG, "could not retrieve NFC-F card emulation service");
- throw new UnsupportedOperationException();
- }
- try {
- sCardEmulationService = sService.getNfcCardEmulationInterface();
- } catch (RemoteException e) {
- sCardEmulationService = null;
- Log.e(TAG, "could not retrieve card emulation service");
- throw new UnsupportedOperationException();
- }
- }
- try {
- sNdefNfceeService = sService.getT4tNdefNfceeInterface();
- } catch (RemoteException e) {
- sNdefNfceeService = null;
- Log.e(TAG, "could not retrieve NDEF NFCEE service");
- throw new UnsupportedOperationException();
- }
- sIsInitialized = true;
- }
- NfcAdapter adapter = sNfcAdapters.get(context);
- if (adapter == null) {
- adapter = new NfcAdapter(context);
- sNfcAdapters.put(context, adapter);
- }
- return adapter;
- }
-
- /** get handle to NFC service interface */
- private static INfcAdapter getServiceInterface() {
- /* get a handle to NFC service */
- IBinder b = sServiceRegisterer.get();
- if (b == null) {
- return null;
- }
- return INfcAdapter.Stub.asInterface(b);
- }
-
- /**
- * Helper to get the default NFC Adapter.
- * <p>
- * Most Android devices will only have one NFC Adapter (NFC Controller).
- * <p>
- * This helper is the equivalent of:
- * <pre>
- * NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
- * NfcAdapter adapter = manager.getDefaultAdapter();</pre>
- * @param context the calling application's context
- *
- * @return the default NFC adapter, or null if no NFC adapter exists
- */
- public static NfcAdapter getDefaultAdapter(Context context) {
- if (context == null) {
- throw new IllegalArgumentException("context cannot be null");
- }
- context = context.getApplicationContext();
- if (context == null) {
- throw new IllegalArgumentException(
- "context not associated with any application (using a mock context?)");
- }
- retrieveServiceRegisterer();
- if (sServiceRegisterer.tryGet() == null) {
- if (sIsInitialized) {
- synchronized (NfcAdapter.class) {
- /* Stale sService pointer */
- if (sIsInitialized) sIsInitialized = false;
- }
- }
- return null;
- }
- /* Try to initialize the service */
- NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
- if (manager == null) {
- // NFC not available
- return null;
- }
- return manager.getDefaultAdapter();
- }
-
- /**
- * Legacy NfcAdapter getter, always use {@link #getDefaultAdapter(Context)} instead.<p>
- * This method was deprecated at API level 10 (Gingerbread MR1) because a context is required
- * for many NFC API methods. Those methods will fail when called on an NfcAdapter
- * object created from this method.<p>
- * @deprecated use {@link #getDefaultAdapter(Context)}
- * @hide
- */
- @Deprecated
- @UnsupportedAppUsage
- public static NfcAdapter getDefaultAdapter() {
- // introduced in API version 9 (GB 2.3)
- // deprecated in API version 10 (GB 2.3.3)
- // removed from public API in version 16 (ICS MR2)
- // should maintain as a hidden API for binary compatibility for a little longer
- Log.w(TAG, "WARNING: NfcAdapter.getDefaultAdapter() is deprecated, use " +
- "NfcAdapter.getDefaultAdapter(Context) instead", new Exception());
-
- return NfcAdapter.getNfcAdapter(null);
- }
-
- NfcAdapter(Context context) {
- mContext = context;
- mNfcActivityManager = new NfcActivityManager(this);
- mNfcUnlockHandlers = new HashMap<NfcUnlockHandler, INfcUnlockHandler>();
- mTagRemovedListener = null;
- mLock = new Object();
- mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
- mNfcWlcStateListener = new NfcWlcStateListener(getService());
- mNfcVendorNciCallbackListener = new NfcVendorNciCallbackListener(getService());
- mNfcOemExtension = new NfcOemExtension(mContext, this);
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage
- public Context getContext() {
- return mContext;
- }
-
- /**
- * Returns the binder interface to the service.
- * @hide
- */
- @UnsupportedAppUsage
- public static INfcAdapter getService() {
- isEnabledStatic(); // NOP call to recover sService if it is stale
- return sService;
- }
-
- /**
- * Returns the binder interface to the tag service.
- * @hide
- */
- public static INfcTag getTagService() {
- isEnabledStatic(); // NOP call to recover sTagService if it is stale
- return sTagService;
- }
-
- /**
- * Returns the binder interface to the card emulation service.
- * @hide
- */
- public static INfcCardEmulation getCardEmulationService() {
- isEnabledStatic();
- return sCardEmulationService;
- }
-
- /**
- * Returns the binder interface to the NFC-F card emulation service.
- * @hide
- */
- public static INfcFCardEmulation getNfcFCardEmulationService() {
- isEnabledStatic();
- return sNfcFCardEmulationService;
- }
-
- /**
- * Returns the binder interface to the NFC-DTA test interface.
- * @hide
- */
- public INfcDta getNfcDtaInterface() {
- if (mContext == null) {
- throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
- + " NFC extras APIs");
- }
- return callServiceReturn(() -> sService.getNfcDtaInterface(mContext.getPackageName()),
- null);
-
- }
-
- /**
- * NFC service dead - attempt best effort recovery
- * @hide
- */
- @UnsupportedAppUsage
- public static void attemptDeadServiceRecovery(RemoteException e) {
- Log.e(TAG, "NFC service dead - attempting to recover", e);
- INfcAdapter service = getServiceInterface();
- if (service == null) {
- Log.e(TAG, "could not retrieve NFC service during service recovery");
- // nothing more can be done now, sService is still stale, we'll hit
- // this recovery path again later
- e.rethrowAsRuntimeException();
- }
- // assigning to sService is not thread-safe, but this is best-effort code
- // and on a well-behaved system should never happen
- sService = service;
- if (sHasNfcFeature) {
- try {
- sTagService = service.getNfcTagInterface();
- } catch (RemoteException ee) {
- sTagService = null;
- Log.e(TAG, "could not retrieve NFC tag service during service recovery");
- // nothing more can be done now, sService is still stale, we'll hit
- // this recovery path again later
- ee.rethrowAsRuntimeException();
- }
- }
-
- if (sHasCeFeature) {
- try {
- sCardEmulationService = service.getNfcCardEmulationInterface();
- } catch (RemoteException ee) {
- sCardEmulationService = null;
- Log.e(TAG,
- "could not retrieve NFC card emulation service during service recovery");
- }
-
- try {
- sNfcFCardEmulationService = service.getNfcFCardEmulationInterface();
- } catch (RemoteException ee) {
- sNfcFCardEmulationService = null;
- Log.e(TAG,
- "could not retrieve NFC-F card emulation service during service recovery");
- }
- }
- }
-
- private static boolean isCardEmulationEnabled() {
- if (sHasCeFeature) {
- return (sCardEmulationService != null || sNfcFCardEmulationService != null);
- }
- return false;
- }
-
- private static boolean isTagReadingEnabled() {
- if (sHasNfcFeature) {
- return sTagService != null;
- }
- return false;
- }
-
- private static boolean isEnabledStatic() {
- boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false);
- return serviceState
- && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
- }
-
- /**
- * Return true if this NFC Adapter has any features enabled.
- *
- * <p>If this method returns false, the NFC hardware is guaranteed not to
- * generate or respond to any NFC communication over its NFC radio.
- * <p>Applications can use this to check if NFC is enabled. Applications
- * can request Settings UI allowing the user to toggle NFC using:
- * <p><pre>startActivity(new Intent(Settings.ACTION_NFC_SETTINGS))</pre>
- *
- * @see android.provider.Settings#ACTION_NFC_SETTINGS
- * @return true if this NFC Adapter has any features enabled
- */
- public boolean isEnabled() {
- return isEnabledStatic();
- }
-
- /**
- * Return the state of this NFC Adapter.
- *
- * <p>Returns one of {@link #STATE_ON}, {@link #STATE_TURNING_ON},
- * {@link #STATE_OFF}, {@link #STATE_TURNING_OFF}.
- *
- * <p>{@link #isEnabled()} is equivalent to
- * <code>{@link #getAdapterState()} == {@link #STATE_ON}</code>
- *
- * @return the current state of this NFC adapter
- *
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- public @AdapterState int getAdapterState() {
- return callServiceReturn(() -> sService.getState(), NfcAdapter.STATE_OFF);
-
- }
-
- /**
- * Enable NFC hardware.
- *
- * <p>This call is asynchronous. Listen for
- * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
- * operation is complete.
- *
- * <p>This API is only allowed to be called by system apps
- * or apps which are Device Owner or Profile Owner.
- *
- * <p>If this returns true, then either NFC is already on, or
- * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
- * to indicate a state transition. If this returns false, then
- * there is some problem that prevents an attempt to turn
- * NFC on (for example we are in airplane mode and NFC is not
- * toggleable in airplane mode on this platform).
- *
- */
- @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean enable() {
- return callServiceReturn(() -> sService.enable(mContext.getPackageName()), false);
-
- }
-
- /**
- * Disable NFC hardware.
- *
- * <p>No NFC features will work after this call, and the hardware
- * will not perform or respond to any NFC communication.
- *
- * <p>This call is asynchronous. Listen for
- * {@link #ACTION_ADAPTER_STATE_CHANGED} broadcasts to find out when the
- * operation is complete.
- *
- * <p>This API is only allowed to be called by system apps
- * or apps which are Device Owner or Profile Owner.
- *
- * <p>If this returns true, then either NFC is already off, or
- * a {@link #ACTION_ADAPTER_STATE_CHANGED} broadcast will be sent
- * to indicate a state transition. If this returns false, then
- * there is some problem that prevents an attempt to turn
- * NFC off.
- *
- */
- @FlaggedApi(Flags.FLAG_NFC_STATE_CHANGE)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean disable() {
- return callServiceReturn(() -> sService.disable(true, mContext.getPackageName()),
- false);
-
- }
-
- /**
- * Disable NFC hardware.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean disable(boolean persist) {
- return callServiceReturn(() -> sService.disable(persist, mContext.getPackageName()),
- false);
-
- }
-
- /**
- * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
- * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
- * use {@link #resumePolling() to resume the polling.
- * @hide
- */
- public void pausePolling(int timeoutInMs) {
- callService(() -> sService.pausePolling(timeoutInMs));
- }
-
-
- /**
- * Returns whether the device supports observe mode or not. When observe mode is enabled, the
- * NFC hardware will listen to NFC readers, but not respond to them. While enabled, observed
- * polling frames will be sent to the APDU service (see {@link #setObserveModeEnabled(boolean)}.
- * When observe mode is disabled (or if it's not supported), the NFC hardware will automatically
- * respond to the reader and proceed with the transaction.
- * @return true if the mode is supported, false otherwise.
- */
- @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
- public boolean isObserveModeSupported() {
- return callServiceReturn(() -> sService.isObserveModeSupported(), false);
- }
-
- /**
- * Returns whether Observe Mode is currently enabled or not.
- *
- * @return true if observe mode is enabled, false otherwise.
- */
-
- @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
- public boolean isObserveModeEnabled() {
- return callServiceReturn(() -> sService.isObserveModeEnabled(), false);
- }
-
- /**
- * Controls whether the NFC adapter will allow transactions to proceed or be in observe mode
- * and simply observe and notify the APDU service of polling loop frames. See
- * {@link #isObserveModeSupported()} for a description of observe mode. Only the package of the
- * currently preferred service (the service set as preferred by the current foreground
- * application via {@link android.nfc.cardemulation.CardEmulation#setPreferredService(Activity,
- * android.content.ComponentName)} or the current Default Wallet Role Holder
- * {@link android.app.role.RoleManager#ROLE_WALLET}), otherwise a call to this method will fail
- * and return false.
- *
- * @param enabled false disables observe mode to allow the transaction to proceed while true
- * enables observe mode and does not allow transactions to proceed.
- *
- * @return boolean indicating success or failure.
- */
-
- @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
- public boolean setObserveModeEnabled(boolean enabled) {
- if (mContext == null) {
- throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
- + " observe mode APIs");
- }
- return callServiceReturn(() -> sService.setObserveMode(enabled, mContext.getPackageName()),
- false);
- }
-
- /**
- * Resumes default NFC tag reader mode polling for the current device state if polling is
- * paused. Calling this while already in polling is a no-op.
- * @hide
- */
- public void resumePolling() {
- callService(() -> sService.resumePolling());
- }
-
- /**
- * Set one or more {@link Uri}s to send using Android Beam (TM). Every
- * Uri you provide must have either scheme 'file' or scheme 'content'.
- *
- * <p>For the data provided through this method, Android Beam tries to
- * switch to alternate transports such as Bluetooth to achieve a fast
- * transfer speed. Hence this method is very suitable
- * for transferring large files such as pictures or songs.
- *
- * <p>The receiving side will store the content of each Uri in
- * a file and present a notification to the user to open the file
- * with a {@link android.content.Intent} with action
- * {@link android.content.Intent#ACTION_VIEW}.
- * If multiple URIs are sent, the {@link android.content.Intent} will refer
- * to the first of the stored files.
- *
- * <p>This method may be called at any time before {@link Activity#onDestroy},
- * but the URI(s) are only made available for Android Beam when the
- * specified activity(s) are in resumed (foreground) state. The recommended
- * approach is to call this method during your Activity's
- * {@link Activity#onCreate} - see sample
- * code below. This method does not immediately perform any I/O or blocking work,
- * so is safe to call on your main thread.
- *
- * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
- * have priority over both {@link #setNdefPushMessage} and
- * {@link #setNdefPushMessageCallback}.
- *
- * <p>If {@link #setBeamPushUris} is called with a null Uri array,
- * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
- * then the Uri push will be completely disabled for the specified activity(s).
- *
- * <p>Code example:
- * <pre>
- * protected void onCreate(Bundle savedInstanceState) {
- * super.onCreate(savedInstanceState);
- * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- * if (nfcAdapter == null) return; // NFC not available on this device
- * nfcAdapter.setBeamPushUris(new Uri[] {uri1, uri2}, this);
- * }</pre>
- * And that is it. Only one call per activity is necessary. The Android
- * OS will automatically release its references to the Uri(s) and the
- * Activity object when it is destroyed if you follow this pattern.
- *
- * <p>If your Activity wants to dynamically supply Uri(s),
- * then set a callback using {@link #setBeamPushUrisCallback} instead
- * of using this method.
- *
- * <p class="note">Do not pass in an Activity that has already been through
- * {@link Activity#onDestroy}. This is guaranteed if you call this API
- * during {@link Activity#onCreate}.
- *
- * <p class="note">If this device does not support alternate transports
- * such as Bluetooth or WiFI, calling this method does nothing.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param uris an array of Uri(s) to push over Android Beam
- * @param activity activity for which the Uri(s) will be pushed
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public void setBeamPushUris(Uri[] uris, Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Set a callback that will dynamically generate one or more {@link Uri}s
- * to send using Android Beam (TM). Every Uri the callback provides
- * must have either scheme 'file' or scheme 'content'.
- *
- * <p>For the data provided through this callback, Android Beam tries to
- * switch to alternate transports such as Bluetooth to achieve a fast
- * transfer speed. Hence this method is very suitable
- * for transferring large files such as pictures or songs.
- *
- * <p>The receiving side will store the content of each Uri in
- * a file and present a notification to the user to open the file
- * with a {@link android.content.Intent} with action
- * {@link android.content.Intent#ACTION_VIEW}.
- * If multiple URIs are sent, the {@link android.content.Intent} will refer
- * to the first of the stored files.
- *
- * <p>This method may be called at any time before {@link Activity#onDestroy},
- * but the URI(s) are only made available for Android Beam when the
- * specified activity(s) are in resumed (foreground) state. The recommended
- * approach is to call this method during your Activity's
- * {@link Activity#onCreate} - see sample
- * code below. This method does not immediately perform any I/O or blocking work,
- * so is safe to call on your main thread.
- *
- * <p>{@link #setBeamPushUris} and {@link #setBeamPushUrisCallback}
- * have priority over both {@link #setNdefPushMessage} and
- * {@link #setNdefPushMessageCallback}.
- *
- * <p>If {@link #setBeamPushUris} is called with a null Uri array,
- * and/or {@link #setBeamPushUrisCallback} is called with a null callback,
- * then the Uri push will be completely disabled for the specified activity(s).
- *
- * <p>Code example:
- * <pre>
- * protected void onCreate(Bundle savedInstanceState) {
- * super.onCreate(savedInstanceState);
- * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- * if (nfcAdapter == null) return; // NFC not available on this device
- * nfcAdapter.setBeamPushUrisCallback(callback, this);
- * }</pre>
- * And that is it. Only one call per activity is necessary. The Android
- * OS will automatically release its references to the Uri(s) and the
- * Activity object when it is destroyed if you follow this pattern.
- *
- * <p class="note">Do not pass in an Activity that has already been through
- * {@link Activity#onDestroy}. This is guaranteed if you call this API
- * during {@link Activity#onCreate}.
- *
- * <p class="note">If this device does not support alternate transports
- * such as Bluetooth or WiFI, calling this method does nothing.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param callback callback, or null to disable
- * @param activity activity for which the Uri(s) will be pushed
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public void setBeamPushUrisCallback(CreateBeamUrisCallback callback, Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Set a static {@link NdefMessage} to send using Android Beam (TM).
- *
- * <p>This method may be called at any time before {@link Activity#onDestroy},
- * but the NDEF message is only made available for NDEF push when the
- * specified activity(s) are in resumed (foreground) state. The recommended
- * approach is to call this method during your Activity's
- * {@link Activity#onCreate} - see sample
- * code below. This method does not immediately perform any I/O or blocking work,
- * so is safe to call on your main thread.
- *
- * <p>Only one NDEF message can be pushed by the currently resumed activity.
- * If both {@link #setNdefPushMessage} and
- * {@link #setNdefPushMessageCallback} are set, then
- * the callback will take priority.
- *
- * <p>If neither {@link #setNdefPushMessage} or
- * {@link #setNdefPushMessageCallback} have been called for your activity, then
- * the Android OS may choose to send a default NDEF message on your behalf,
- * such as a URI for your application.
- *
- * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
- * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
- * then NDEF push will be completely disabled for the specified activity(s).
- * This also disables any default NDEF message the Android OS would have
- * otherwise sent on your behalf for those activity(s).
- *
- * <p>If you want to prevent the Android OS from sending default NDEF
- * messages completely (for all activities), you can include a
- * {@code <meta-data>} element inside the {@code <application>}
- * element of your AndroidManifest.xml file, like this:
- * <pre>
- * &lt;application ...>
- * &lt;meta-data android:name="android.nfc.disable_beam_default"
- * android:value="true" />
- * &lt;/application></pre>
- *
- * <p>The API allows for multiple activities to be specified at a time,
- * but it is strongly recommended to just register one at a time,
- * and to do so during the activity's {@link Activity#onCreate}. For example:
- * <pre>
- * protected void onCreate(Bundle savedInstanceState) {
- * super.onCreate(savedInstanceState);
- * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- * if (nfcAdapter == null) return; // NFC not available on this device
- * nfcAdapter.setNdefPushMessage(ndefMessage, this);
- * }</pre>
- * And that is it. Only one call per activity is necessary. The Android
- * OS will automatically release its references to the NDEF message and the
- * Activity object when it is destroyed if you follow this pattern.
- *
- * <p>If your Activity wants to dynamically generate an NDEF message,
- * then set a callback using {@link #setNdefPushMessageCallback} instead
- * of a static message.
- *
- * <p class="note">Do not pass in an Activity that has already been through
- * {@link Activity#onDestroy}. This is guaranteed if you call this API
- * during {@link Activity#onCreate}.
- *
- * <p class="note">For sending large content such as pictures and songs,
- * consider using {@link #setBeamPushUris}, which switches to alternate transports
- * such as Bluetooth to achieve a fast transfer rate.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param message NDEF message to push over NFC, or null to disable
- * @param activity activity for which the NDEF message will be pushed
- * @param activities optional additional activities, however we strongly recommend
- * to only register one at a time, and to do so in that activity's
- * {@link Activity#onCreate}
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public void setNdefPushMessage(NdefMessage message, Activity activity,
- Activity ... activities) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * @hide
- * @removed
- */
- @SystemApi
- @UnsupportedAppUsage
- public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Set a callback that dynamically generates NDEF messages to send using Android Beam (TM).
- *
- * <p>This method may be called at any time before {@link Activity#onDestroy},
- * but the NDEF message callback can only occur when the
- * specified activity(s) are in resumed (foreground) state. The recommended
- * approach is to call this method during your Activity's
- * {@link Activity#onCreate} - see sample
- * code below. This method does not immediately perform any I/O or blocking work,
- * so is safe to call on your main thread.
- *
- * <p>Only one NDEF message can be pushed by the currently resumed activity.
- * If both {@link #setNdefPushMessage} and
- * {@link #setNdefPushMessageCallback} are set, then
- * the callback will take priority.
- *
- * <p>If neither {@link #setNdefPushMessage} or
- * {@link #setNdefPushMessageCallback} have been called for your activity, then
- * the Android OS may choose to send a default NDEF message on your behalf,
- * such as a URI for your application.
- *
- * <p>If {@link #setNdefPushMessage} is called with a null NDEF message,
- * and/or {@link #setNdefPushMessageCallback} is called with a null callback,
- * then NDEF push will be completely disabled for the specified activity(s).
- * This also disables any default NDEF message the Android OS would have
- * otherwise sent on your behalf for those activity(s).
- *
- * <p>If you want to prevent the Android OS from sending default NDEF
- * messages completely (for all activities), you can include a
- * {@code <meta-data>} element inside the {@code <application>}
- * element of your AndroidManifest.xml file, like this:
- * <pre>
- * &lt;application ...>
- * &lt;meta-data android:name="android.nfc.disable_beam_default"
- * android:value="true" />
- * &lt;/application></pre>
- *
- * <p>The API allows for multiple activities to be specified at a time,
- * but it is strongly recommended to just register one at a time,
- * and to do so during the activity's {@link Activity#onCreate}. For example:
- * <pre>
- * protected void onCreate(Bundle savedInstanceState) {
- * super.onCreate(savedInstanceState);
- * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- * if (nfcAdapter == null) return; // NFC not available on this device
- * nfcAdapter.setNdefPushMessageCallback(callback, this);
- * }</pre>
- * And that is it. Only one call per activity is necessary. The Android
- * OS will automatically release its references to the callback and the
- * Activity object when it is destroyed if you follow this pattern.
- *
- * <p class="note">Do not pass in an Activity that has already been through
- * {@link Activity#onDestroy}. This is guaranteed if you call this API
- * during {@link Activity#onCreate}.
- * <p class="note">For sending large content such as pictures and songs,
- * consider using {@link #setBeamPushUris}, which switches to alternate transports
- * such as Bluetooth to achieve a fast transfer rate.
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param callback callback, or null to disable
- * @param activity activity for which the NDEF message will be pushed
- * @param activities optional additional activities, however we strongly recommend
- * to only register one at a time, and to do so in that activity's
- * {@link Activity#onCreate}
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
- Activity ... activities) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Set a callback on successful Android Beam (TM).
- *
- * <p>This method may be called at any time before {@link Activity#onDestroy},
- * but the callback can only occur when the
- * specified activity(s) are in resumed (foreground) state. The recommended
- * approach is to call this method during your Activity's
- * {@link Activity#onCreate} - see sample
- * code below. This method does not immediately perform any I/O or blocking work,
- * so is safe to call on your main thread.
- *
- * <p>The API allows for multiple activities to be specified at a time,
- * but it is strongly recommended to just register one at a time,
- * and to do so during the activity's {@link Activity#onCreate}. For example:
- * <pre>
- * protected void onCreate(Bundle savedInstanceState) {
- * super.onCreate(savedInstanceState);
- * NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
- * if (nfcAdapter == null) return; // NFC not available on this device
- * nfcAdapter.setOnNdefPushCompleteCallback(callback, this);
- * }</pre>
- * And that is it. Only one call per activity is necessary. The Android
- * OS will automatically release its references to the callback and the
- * Activity object when it is destroyed if you follow this pattern.
- *
- * <p class="note">Do not pass in an Activity that has already been through
- * {@link Activity#onDestroy}. This is guaranteed if you call this API
- * during {@link Activity#onCreate}.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param callback callback, or null to disable
- * @param activity activity for which the NDEF message will be pushed
- * @param activities optional additional activities, however we strongly recommend
- * to only register one at a time, and to do so in that activity's
- * {@link Activity#onCreate}
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public void setOnNdefPushCompleteCallback(OnNdefPushCompleteCallback callback,
- Activity activity, Activity ... activities) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Enable foreground dispatch to the given Activity.
- *
- * <p>This will give priority to the foreground activity when
- * dispatching a discovered {@link Tag} to an application.
- *
- * <p>If any IntentFilters are provided to this method they are used to match dispatch Intents
- * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and
- * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED}
- * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled
- * by passing in the tech lists separately. Each first level entry in the tech list represents
- * an array of technologies that must all be present to match. If any of the first level sets
- * match then the dispatch is routed through the given PendingIntent. In other words, the second
- * level is ANDed together and the first level entries are ORed together.
- *
- * <p>If you pass {@code null} for both the {@code filters} and {@code techLists} parameters
- * that acts a wild card and will cause the foreground activity to receive all tags via the
- * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent.
- *
- * <p>This method must be called from the main thread, and only when the activity is in the
- * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before
- * the completion of their {@link Activity#onPause} callback to disable foreground dispatch
- * after it has been enabled.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param activity the Activity to dispatch to
- * @param intent the PendingIntent to start for the dispatch
- * @param filters the IntentFilters to override dispatching for, or null to always dispatch
- * @param techLists the tech lists used to perform matching for dispatching of the
- * {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent
- * @throws IllegalStateException if the Activity is not currently in the foreground
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- public void enableForegroundDispatch(Activity activity, PendingIntent intent,
- IntentFilter[] filters, String[][] techLists) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- if (activity == null || intent == null) {
- throw new NullPointerException();
- }
- final TechListParcel parcel = (techLists != null && techLists.length > 0)
- ? new TechListParcel(techLists)
- : null;
- callService(() -> sService.setForegroundDispatch(intent, filters, parcel));
- }
-
- /**
- * Disable foreground dispatch to the given activity.
- *
- * <p>After calling {@link #enableForegroundDispatch}, an activity
- * must call this method before its {@link Activity#onPause} callback
- * completes.
- *
- * <p>This method must be called from the main thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param activity the Activity to disable dispatch to
- * @throws IllegalStateException if the Activity has already been paused
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- public void disableForegroundDispatch(Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- callService(() -> sService.setForegroundDispatch(null, null, null));
- }
-
- /**
- * Limit the NFC controller to reader mode while this Activity is in the foreground.
- *
- * <p>In this mode the NFC controller will only act as an NFC tag reader/writer,
- * thus disabling any peer-to-peer (Android Beam) and card-emulation modes of
- * the NFC adapter on this device.
- *
- * <p>Use {@link #FLAG_READER_SKIP_NDEF_CHECK} to prevent the platform from
- * performing any NDEF checks in reader mode. Note that this will prevent the
- * {@link Ndef} tag technology from being enumerated on the tag, and that
- * NDEF-based tag dispatch will not be functional.
- *
- * <p>For interacting with tags that are emulated on another Android device
- * using Android's host-based card-emulation, the recommended flags are
- * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
- *
- * @param activity the Activity that requests the adapter to be in reader mode
- * @param callback the callback to be called when a tag is discovered
- * @param flags Flags indicating poll technologies and other optional parameters
- * @param extras Additional extras for configuring reader mode.
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
- Bundle extras) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
- }
-
- /**
- * Restore the NFC adapter to normal mode of operation: supporting
- * peer-to-peer (Android Beam), card emulation, and polling for
- * all supported tag technologies.
- *
- * @param activity the Activity that currently has reader mode enabled
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- public void disableReaderMode(Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- mNfcActivityManager.disableReaderMode(activity);
- }
-
- // Flags arguments to NFC adapter to enable/disable NFC
- private static final int DISABLE_POLLING_FLAGS = 0x1000;
- private static final int ENABLE_POLLING_FLAGS = 0x0000;
-
- /**
- * Privileged API to enable or disable reader polling.
- * Unlike {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}, this API does not
- * need a foreground activity to control reader mode parameters
- * Note: Use with caution! The app is responsible for ensuring that the polling state is
- * returned to normal.
- *
- * @see #enableReaderMode(Activity, ReaderCallback, int, Bundle) for more detailed
- * documentation.
- *
- * @param enablePolling whether to enable or disable polling.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- @SuppressLint("VisiblySynchronized")
- public void setReaderModePollingEnabled(boolean enable) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- Binder token = new Binder();
- int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
- callService(() -> sService.setReaderMode(
- token, null, flags, null, mContext.getPackageName()));
- }
-
- /**
- * Set the NFC controller to enable specific poll/listen technologies,
- * as specified in parameters, while this Activity is in the foreground.
- *
- * Use {@link #FLAG_READER_KEEP} to keep current polling technology.
- * Use {@link #FLAG_LISTEN_KEEP} to keep current listenig technology.
- * (if the _KEEP flag is specified the other technology flags shouldn't be set
- * and are quietly ignored otherwise).
- * Use {@link #FLAG_READER_DISABLE} to disable polling.
- * Use {@link #FLAG_LISTEN_DISABLE} to disable listening.
- * Also refer to {@link #resetDiscoveryTechnology(Activity)} to restore these changes.
- * </p>
- * The pollTechnology, listenTechnology parameters can be one or several of below list.
- * <pre>
- * Poll Listen
- * Passive A 0x01 (NFC_A) 0x01 (NFC_PASSIVE_A)
- * Passive B 0x02 (NFC_B) 0x02 (NFC_PASSIVE_B)
- * Passive F 0x04 (NFC_F) 0x04 (NFC_PASSIVE_F)
- * ISO 15693 0x08 (NFC_V) -
- * Kovio 0x10 (NFC_BARCODE) -
- * </pre>
- * <p>Example usage in an Activity that requires to disable poll,
- * keep current listen technologies:
- * <pre>
- * protected void onResume() {
- * mNfcAdapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
- * mNfcAdapter.setDiscoveryTechnology(this,
- * NfcAdapter.FLAG_READER_DISABLE, NfcAdapter.FLAG_LISTEN_KEEP);
- * }</pre></p>
- * @param activity The Activity that requests NFC controller to enable specific technologies.
- * @param pollTechnology Flags indicating poll technologies.
- * @param listenTechnology Flags indicating listen technologies.
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF are unavailable.
- */
-
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public void setDiscoveryTechnology(@NonNull Activity activity,
- @PollTechnology int pollTechnology, @ListenTechnology int listenTechnology) {
-
- if (listenTechnology == FLAG_LISTEN_DISABLE) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- } else if (pollTechnology == FLAG_READER_DISABLE) {
- synchronized (sLock) {
- if (!sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- }
- } else {
- synchronized (sLock) {
- if (!sHasNfcFeature || !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
- /*
- * Privileged FLAG to set technology mask for all data processed by NFC controller
- * Note: Use with caution! The app is responsible for ensuring that the discovery
- * technology mask is returned to default.
- * Note: FLAG_USE_ALL_TECH used with _KEEP flags will reset the technolody to android default
- */
- if (Flags.nfcSetDefaultDiscTech()
- && ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH
- || (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
- Binder token = new Binder();
- callService( () ->
- sService.updateDiscoveryTechnology(
- token, pollTechnology, listenTechnology, mContext.getPackageName()));
- } else {
- mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
- }
- }
-
- /**
- * Restore the poll/listen technologies of NFC controller to its default state,
- * which were changed by {@link #setDiscoveryTechnology(Activity , int , int)}
- *
- * @param activity The Activity that requested to change technologies.
- */
-
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
- public void resetDiscoveryTechnology(@NonNull Activity activity) {
- mNfcActivityManager.resetDiscoveryTech(activity);
- }
-
- /**
- * Manually invoke Android Beam to share data.
- *
- * <p>The Android Beam animation is normally only shown when two NFC-capable
- * devices come into range.
- * By calling this method, an Activity can invoke the Beam animation directly
- * even if no other NFC device is in range yet. The Beam animation will then
- * prompt the user to tap another NFC-capable device to complete the data
- * transfer.
- *
- * <p>The main advantage of using this method is that it avoids the need for the
- * user to tap the screen to complete the transfer, as this method already
- * establishes the direction of the transfer and the consent of the user to
- * share data. Callers are responsible for making sure that the user has
- * consented to sharing data on NFC tap.
- *
- * <p>Note that to use this method, the passed in Activity must have already
- * set data to share over Beam by using method calls such as
- * {@link #setNdefPushMessageCallback} or
- * {@link #setBeamPushUrisCallback}.
- *
- * @param activity the current foreground Activity that has registered data to share
- * @return whether the Beam animation was successfully invoked
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public boolean invokeBeam(Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- return false;
- }
-
- /**
- * Enable NDEF message push over NFC while this Activity is in the foreground.
- *
- * <p>You must explicitly call this method every time the activity is
- * resumed, and you must call {@link #disableForegroundNdefPush} before
- * your activity completes {@link Activity#onPause}.
- *
- * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
- * instead: it automatically hooks into your activity life-cycle,
- * so you do not need to call enable/disable in your onResume/onPause.
- *
- * <p>For NDEF push to function properly the other NFC device must
- * support either NFC Forum's SNEP (Simple Ndef Exchange Protocol), or
- * Android's "com.android.npp" (Ndef Push Protocol). This was optional
- * on Gingerbread level Android NFC devices, but SNEP is mandatory on
- * Ice-Cream-Sandwich and beyond.
- *
- * <p>This method must be called from the main thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param activity foreground activity
- * @param message a NDEF Message to push over NFC
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @Deprecated
- @UnsupportedAppUsage
- public void enableForegroundNdefPush(Activity activity, NdefMessage message) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Disable NDEF message push over P2P.
- *
- * <p>After calling {@link #enableForegroundNdefPush}, an activity
- * must call this method before its {@link Activity#onPause} callback
- * completes.
- *
- * <p>Strongly recommend to use the new {@link #setNdefPushMessage}
- * instead: it automatically hooks into your activity life-cycle,
- * so you do not need to call enable/disable in your onResume/onPause.
- *
- * <p>This method must be called from the main thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param activity the Foreground activity
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @Deprecated
- @UnsupportedAppUsage
- public void disableForegroundNdefPush(Activity activity) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- }
-
- /**
- * Sets Secure NFC feature.
- * <p>This API is for the Settings application.
- * @return True if successful
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean enableSecureNfc(boolean enable) {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.setNfcSecure(enable), false);
-
- }
-
- /**
- * Checks if the device supports Secure NFC functionality.
- *
- * @return True if device supports Secure NFC, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- */
- public boolean isSecureNfcSupported() {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.deviceSupportsNfcSecure(), false);
-
- }
-
- /**
- * Returns information regarding Nfc antennas on the device
- * such as their relative positioning on the device.
- *
- * @return Information on the nfc antenna(s) on the device.
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- */
- @Nullable
- public NfcAntennaInfo getNfcAntennaInfo() {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.getNfcAntennaInfo(), null);
-
- }
-
- /**
- * Checks Secure NFC feature is enabled.
- *
- * @return True if Secure NFC is enabled, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- * @throws UnsupportedOperationException if device doesn't support
- * Secure NFC functionality. {@link #isSecureNfcSupported}
- */
- public boolean isSecureNfcEnabled() {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isNfcSecureEnabled(), false);
-
- }
-
- /**
- * Sets NFC Reader option feature.
- * <p>This API is for the Settings application.
- * @return True if successful
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean enableReaderOption(boolean enable) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() ->
- sService.enableReaderOption(enable, mContext.getPackageName()), false);
-
- }
-
- /**
- * Checks if the device supports NFC Reader option functionality.
- *
- * @return True if device supports NFC Reader option, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
- public boolean isReaderOptionSupported() {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isReaderOptionSupported(), false);
-
- }
-
- /**
- * Checks NFC Reader option feature is enabled.
- *
- * @return True if NFC Reader option is enabled, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @throws UnsupportedOperationException if device doesn't support
- * NFC Reader option functionality. {@link #isReaderOptionSupported}
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_READER_OPTION)
- public boolean isReaderOptionEnabled() {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isReaderOptionEnabled(), false);
-
- }
-
- /**
- * Enable NDEF Push feature.
- * <p>This API is for the Settings application.
- * @hide
- * @removed
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @UnsupportedAppUsage
- public boolean enableNdefPush() {
- return false;
- }
-
- /**
- * Disable NDEF Push feature.
- * <p>This API is for the Settings application.
- * @hide
- * @removed
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @UnsupportedAppUsage
- public boolean disableNdefPush() {
- return false;
- }
-
- /**
- * Return true if the NDEF Push (Android Beam) feature is enabled.
- * <p>This function will return true only if both NFC is enabled, and the
- * NDEF Push feature is enabled.
- * <p>Note that if NFC is enabled but NDEF Push is disabled then this
- * device can still <i>receive</i> NDEF messages, it just cannot send them.
- * <p>Applications cannot directly toggle the NDEF Push feature, but they
- * can request Settings UI allowing the user to toggle NDEF Push using
- * <code>startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS))</code>
- * <p>Example usage in an Activity that requires NDEF Push:
- * <p><pre>
- * protected void onResume() {
- * super.onResume();
- * if (!nfcAdapter.isEnabled()) {
- * startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
- * } else if (!nfcAdapter.isNdefPushEnabled()) {
- * startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
- * }
- * }</pre>
- *
- * @see android.provider.Settings#ACTION_NFCSHARING_SETTINGS
- * @return true if NDEF Push feature is enabled
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- * @removed this feature is removed. File sharing can work using other technology like
- * Bluetooth.
- */
- @java.lang.Deprecated
- @UnsupportedAppUsage
- public boolean isNdefPushEnabled() {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- return false;
- }
-
- /**
- * Signals that you are no longer interested in communicating with an NFC tag
- * for as long as it remains in range.
- *
- * All future attempted communication to this tag will fail with {@link IOException}.
- * The NFC controller will be put in a low-power polling mode, allowing the device
- * to save power in cases where it's "attached" to a tag all the time (e.g. a tag in
- * car dock).
- *
- * Additionally the debounceMs parameter allows you to specify for how long the tag needs
- * to have gone out of range, before it will be dispatched again.
- *
- * Note: the NFC controller typically polls at a pretty slow interval (100 - 500 ms).
- * This means that if the tag repeatedly goes in and out of range (for example, in
- * case of a flaky connection), and the controller happens to poll every time the
- * tag is out of range, it *will* re-dispatch the tag after debounceMs, despite the tag
- * having been "in range" during the interval.
- *
- * Note 2: if a tag with another UID is detected after this API is called, its effect
- * will be cancelled; if this tag shows up before the amount of time specified in
- * debounceMs, it will be dispatched again.
- *
- * Note 3: some tags have a random UID, in which case this API won't work reliably.
- *
- * @param tag the {@link android.nfc.Tag Tag} to ignore.
- * @param debounceMs minimum amount of time the tag needs to be out of range before being
- * dispatched again.
- * @param tagRemovedListener listener to be called when the tag is removed from the field.
- * Note that this will only be called if the tag has been out of range
- * for at least debounceMs, or if another tag came into range before
- * debounceMs. May be null in case you don't want a callback.
- * @param handler the {@link android.os.Handler Handler} that will be used for delivering
- * the callback. if the handler is null, then the thread used for delivering
- * the callback is unspecified.
- * @return false if the tag couldn't be found (or has already gone out of range), true otherwise
- */
- public boolean ignore(final Tag tag, int debounceMs,
- final OnTagRemovedListener tagRemovedListener, final Handler handler) {
- ITagRemovedCallback.Stub iListener = null;
- if (tagRemovedListener != null) {
- iListener = new ITagRemovedCallback.Stub() {
- @Override
- public void onTagRemoved() throws RemoteException {
- if (handler != null) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- tagRemovedListener.onTagRemoved();
- }
- });
- } else {
- tagRemovedListener.onTagRemoved();
- }
- synchronized (mLock) {
- mTagRemovedListener = null;
- }
- }
- };
- }
- synchronized (mLock) {
- mTagRemovedListener = iListener;
- }
- final ITagRemovedCallback.Stub passedListener = iListener;
- return callServiceReturn(() ->
- sService.ignore(tag.getServiceHandle(), debounceMs, passedListener), false);
- }
-
- /**
- * Inject a mock NFC tag.<p>
- * Used for testing purposes.
- * <p class="note">Requires the
- * {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
- * @hide
- */
- public void dispatch(Tag tag) {
- if (tag == null) {
- throw new NullPointerException("tag cannot be null");
- }
- callService(() -> sService.dispatch(tag));
- }
-
- /**
- * Registers a new NFC unlock handler with the NFC service.
- *
- * <p />NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted
- * NFC device. The handler should return true if it successfully authenticates the user and
- * unlocks the keyguard.
- *
- * <p /> The parameter {@code tagTechnologies} determines which Tag technologies will be polled for
- * at the lockscreen. Polling for less tag technologies reduces latency, and so it is
- * strongly recommended to only provide the Tag technologies that the handler is expected to
- * receive. There must be at least one tag technology provided, otherwise the unlock handler
- * is ignored.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler,
- String[] tagTechnologies) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- // If there are no tag technologies, don't bother adding unlock handler
- if (tagTechnologies.length == 0) {
- return false;
- }
-
- try {
- synchronized (mLock) {
- if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
- // update the tag technologies
- callService(() -> {
- sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
- mNfcUnlockHandlers.remove(unlockHandler);
- });
- }
-
- INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() {
- @Override
- public boolean onUnlockAttempted(Tag tag) throws RemoteException {
- return unlockHandler.onUnlockAttempted(tag);
- }
- };
- return callServiceReturn(() -> {
- sService.addNfcUnlockHandler(
- iHandler, Tag.getTechCodesFromStrings(tagTechnologies));
- mNfcUnlockHandlers.put(unlockHandler, iHandler);
- return true;
- }, false);
- }
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Unable to register LockscreenDispatch", e);
- return false;
- }
-
- }
-
- /**
- * Removes a previously registered unlock handler. Also removes the tag technologies
- * associated with the removed unlock handler.
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- synchronized (mLock) {
- if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
- return callServiceReturn(() -> {
- sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler));
- return true;
- }, false);
- }
- return true;
- }
- }
-
- /**
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public INfcAdapterExtras getNfcAdapterExtrasInterface() {
- if (mContext == null) {
- throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
- + " NFC extras APIs");
- }
- return callServiceReturn(() ->
- sService.getNfcAdapterExtrasInterface(mContext.getPackageName()), null);
-
- }
-
- void enforceResumed(Activity activity) {
- if (!activity.isResumed()) {
- throw new IllegalStateException("API cannot be called while activity is paused");
- }
- }
-
- int getSdkVersion() {
- if (mContext == null) {
- return android.os.Build.VERSION_CODES.GINGERBREAD; // best guess
- } else {
- return mContext.getApplicationInfo().targetSdkVersion;
- }
- }
-
- /**
- * Sets NFC controller always on feature.
- * <p>This API is for the NFCC internal state management. It allows to discriminate
- * the controller function from the NFC function by keeping the NFC controller on without
- * any NFC RF enabled if necessary.
- * <p>This call is asynchronous. Register a listener {@link ControllerAlwaysOnListener}
- * by {@link #registerControllerAlwaysOnListener} to find out when the operation is
- * complete.
- * <p>If this returns true, then either NFCC always on state has been set based on the value,
- * or a {@link ControllerAlwaysOnListener#onControllerAlwaysOnChanged(boolean)} will be invoked
- * to indicate the state change.
- * If this returns false, then there is some problem that prevents an attempt to turn NFCC
- * always on.
- * @param value if true the NFCC will be kept on (with no RF enabled if NFC adapter is
- * disabled), if false the NFCC will follow completely the Nfc adapter state.
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- * @return true if feature is supported by the device and operation has been initiated,
- * false if the feature is not supported by the device.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public boolean setControllerAlwaysOn(boolean value) {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- int mode = value ? CONTROLLER_ALWAYS_ON_MODE_DEFAULT : CONTROLLER_ALWAYS_ON_DISABLE;
- try {
- callService(() -> sService.setControllerAlwaysOn(mode));
- } catch (UnsupportedOperationException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Checks NFC controller always on feature is enabled.
- *
- * @return True if NFC controller always on is enabled, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public boolean isControllerAlwaysOn() {
- return callServiceReturn(() -> sService.isControllerAlwaysOn(), false);
-
- }
-
- /**
- * Checks if the device supports NFC controller always on functionality.
- *
- * @return True if device supports NFC controller always on, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC,
- * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public boolean isControllerAlwaysOnSupported() {
- if (!sHasNfcFeature && !sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isControllerAlwaysOnSupported(), false);
-
- }
-
- /**
- * Register a {@link ControllerAlwaysOnListener} to listen for NFC controller always on
- * state changes
- * <p>The provided listener will be invoked by the given {@link Executor}.
- *
- * @param executor an {@link Executor} to execute given listener
- * @param listener user implementation of the {@link ControllerAlwaysOnListener}
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public void registerControllerAlwaysOnListener(
- @NonNull @CallbackExecutor Executor executor,
- @NonNull ControllerAlwaysOnListener listener) {
- mControllerAlwaysOnListener.register(executor, listener);
- }
-
- /**
- * Unregister the specified {@link ControllerAlwaysOnListener}
- * <p>The same {@link ControllerAlwaysOnListener} object used when calling
- * {@link #registerControllerAlwaysOnListener(Executor, ControllerAlwaysOnListener)}
- * must be used.
- *
- * <p>Listeners are automatically unregistered when application process goes away
- *
- * @param listener user implementation of the {@link ControllerAlwaysOnListener}
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public void unregisterControllerAlwaysOnListener(
- @NonNull ControllerAlwaysOnListener listener) {
- mControllerAlwaysOnListener.unregister(listener);
- }
-
-
- /**
- * Sets whether we dispatch NFC Tag intents to the package.
- *
- * <p>{@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
- * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
- * disallowed.
- * <p>An app is added to the preference list with the allowed flag set to {@code true}
- * when a Tag intent is dispatched to the package for the first time. This API is called
- * by settings to note that the user wants to change this default preference.
- *
- * @param userId the user to whom this package name will belong to
- * @param pkg the full name (i.e. com.google.android.tag) of the package that will be added to
- * the preference list
- * @param allow {@code true} to allow dispatching Tag intents to the package's activity,
- * {@code false} otherwise
- * @return the {@link #TagIntentAppPreferenceResult} value
- * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
- * {@code false}
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @TagIntentAppPreferenceResult
- public int setTagIntentAppPreferenceForUser(@UserIdInt int userId,
- @NonNull String pkg, boolean allow) {
- Objects.requireNonNull(pkg, "pkg cannot be null");
- if (!isTagIntentAppPreferenceSupported()) {
- Log.e(TAG, "TagIntentAppPreference is not supported");
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() ->
- sService.setTagIntentAppPreferenceForUser(userId, pkg, allow),
- TAG_INTENT_APP_PREF_RESULT_UNAVAILABLE);
- }
-
-
- /**
- * Get the Tag dispatch preference list of the UserId.
- *
- * <p>This returns a mapping of package names for this user id to whether we dispatch Tag
- * intents to the package. {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
- * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if its package is
- * mapped to {@code false}.
- * <p>There are three different possible cases:
- * <p>A package not being in the preference list.
- * It does not contain any Tag intent filters or the user never triggers a Tag detection that
- * matches the intent filter of the package.
- * <p>A package being mapped to {@code true}.
- * When a package has been launched by a tag detection for the first time, the package name is
- * put to the map and by default mapped to {@code true}. The package will receive Tag intents as
- * usual.
- * <p>A package being mapped to {@code false}.
- * The user chooses to disable this package and it will not receive any Tag intents anymore.
- *
- * @param userId the user to whom this preference list will belong to
- * @return a map of the UserId which indicates the mapping from package name to
- * boolean(allow status), otherwise return an empty map
- * @throws UnsupportedOperationException if {@link isTagIntentAppPreferenceSupported} returns
- * {@code false}
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @NonNull
- public Map<String, Boolean> getTagIntentAppPreferenceForUser(@UserIdInt int userId) {
- if (!isTagIntentAppPreferenceSupported()) {
- Log.e(TAG, "TagIntentAppPreference is not supported");
- throw new UnsupportedOperationException();
- }
- return callServiceReturn( () ->
- sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap());
- }
-
- /**
- * Checks if the device supports Tag Intent App Preference functionality.
- *
- * When supported, {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
- * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if
- * {@link isTagIntentAllowed} returns {@code false}.
- *
- * @return {@code true} if the device supports Tag application preference, {@code false}
- * otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable
- */
- @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
- public boolean isTagIntentAppPreferenceSupported() {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isTagIntentAppPreferenceSupported(), false);
- }
-
- /**
- * Notifies the system of a new polling loop.
- *
- * @param frame is the new frame.
- *
- * @hide
- */
- @TestApi
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) {
- callService(() -> sService.notifyPollingLoop(pollingFrame));
- }
-
-
- /**
- * Notifies the system of new HCE data for tests.
- *
- * @hide
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void notifyTestHceData(int technology, byte[] data) {
- callService(() -> sService.notifyTestHceData(technology, data));
- }
-
- /** @hide */
- interface ServiceCall {
- void call() throws RemoteException;
- }
- /** @hide */
- static void callService(ServiceCall call) {
- try {
- if (sService == null) {
- attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
- }
- call.call();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- try {
- call.call();
- } catch (RemoteException ee) {
- ee.rethrowAsRuntimeException();
- }
- }
- }
- /** @hide */
- interface ServiceCallReturn<T> {
- T call() throws RemoteException;
- }
- /** @hide */
- static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
- try {
- if (sService == null) {
- attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
- }
- return call.call();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- try {
- return call.call();
- } catch (RemoteException ee) {
- ee.rethrowAsRuntimeException();
- }
- }
- return defaultReturn;
- }
-
- /**
- * Notifies the system of a an HCE session being deactivated.
- * *
- * @hide
- */
- @TestApi
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void notifyHceDeactivated() {
- callService(() -> sService.notifyHceDeactivated());
- }
-
- /**
- * Sets NFC charging feature.
- * <p>This API is for the Settings application.
- * @return True if successful
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean setWlcEnabled(boolean enable) {
- if (!sHasNfcWlcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.setWlcEnabled(enable), false);
- }
-
- /**
- * Checks NFC charging feature is enabled.
- *
- * @return True if NFC charging is enabled, false otherwise
- * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
- * is unavailable
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- public boolean isWlcEnabled() {
- if (!sHasNfcWlcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.isWlcEnabled(), false);
-
- }
-
- /**
- * A listener to be invoked when NFC controller always on state changes.
- * <p>Register your {@code ControllerAlwaysOnListener} implementation with {@link
- * NfcAdapter#registerWlcStateListener} and disable it with {@link
- * NfcAdapter#unregisterWlcStateListenerListener}.
- * @see #registerWlcStateListener
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- public interface WlcStateListener {
- /**
- * Called on NFC WLC state changes
- */
- void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo);
- }
-
- /**
- * Register a {@link WlcStateListener} to listen for NFC WLC state changes
- * <p>The provided listener will be invoked by the given {@link Executor}.
- *
- * @param executor an {@link Executor} to execute given listener
- * @param listener user implementation of the {@link WlcStateListener}
- * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
- * is unavailable
- *
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- public void registerWlcStateListener(
- @NonNull @CallbackExecutor Executor executor,
- @NonNull WlcStateListener listener) {
- if (!sHasNfcWlcFeature) {
- throw new UnsupportedOperationException();
- }
- mNfcWlcStateListener.register(executor, listener);
- }
-
- /**
- * Unregister the specified {@link WlcStateListener}
- * <p>The same {@link WlcStateListener} object used when calling
- * {@link #registerWlcStateListener(Executor, WlcStateListener)}
- * must be used.
- *
- * <p>Listeners are automatically unregistered when application process goes away
- *
- * @param listener user implementation of the {@link WlcStateListener}a
- * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
- * is unavailable
- *
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- public void unregisterWlcStateListener(
- @NonNull WlcStateListener listener) {
- if (!sHasNfcWlcFeature) {
- throw new UnsupportedOperationException();
- }
- mNfcWlcStateListener.unregister(listener);
- }
-
- /**
- * Returns information on the NFC charging listener device
- *
- * @return Information on the NFC charging listener device
- * @throws UnsupportedOperationException if FEATURE_NFC_CHARGING
- * is unavailable
- */
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
- @Nullable
- public WlcListenerDeviceInfo getWlcListenerDeviceInfo() {
- if (!sHasNfcWlcFeature) {
- throw new UnsupportedOperationException();
- }
- return callServiceReturn(() -> sService.getWlcListenerDeviceInfo(), null);
-
- }
-
- /**
- * Vendor NCI command success.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public static final int SEND_VENDOR_NCI_STATUS_SUCCESS = 0;
- /**
- * Vendor NCI command rejected.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public static final int SEND_VENDOR_NCI_STATUS_REJECTED = 1;
- /**
- * Vendor NCI command corrupted.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public static final int SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED = 2;
- /**
- * Vendor NCI command failed with unknown reason.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public static final int SEND_VENDOR_NCI_STATUS_FAILED = 3;
-
- /**
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- SEND_VENDOR_NCI_STATUS_SUCCESS,
- SEND_VENDOR_NCI_STATUS_REJECTED,
- SEND_VENDOR_NCI_STATUS_MESSAGE_CORRUPTED,
- SEND_VENDOR_NCI_STATUS_FAILED,
- })
- @interface SendVendorNciStatus {}
-
- /**
- * Message Type for NCI Command.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public static final int MESSAGE_TYPE_COMMAND = 1;
-
- /**
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {
- MESSAGE_TYPE_COMMAND,
- })
- @interface MessageType {}
-
- /**
- * Send Vendor specific Nci Messages with custom message type.
- *
- * The format of the NCI messages are defined in the NCI specification. The platform is
- * responsible for fragmenting the payload if necessary.
- *
- * Note that mt (message type) is added at the beginning of method parameters as it is more
- * distinctive than other parameters and was requested from vendor.
- *
- * @param mt message Type of the command
- * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
- * the NCI specification
- * @param oid opcode ID of the command. This is left to the OEM / vendor to decide
- * @param payload containing vendor Nci message payload
- * @return message send status
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public @SendVendorNciStatus int sendVendorNciMessage(@MessageType int mt,
- @IntRange(from = 0, to = 15) int gid, @IntRange(from = 0) int oid,
- @NonNull byte[] payload) {
- Objects.requireNonNull(payload, "Payload must not be null");
- return callServiceReturn(() -> sService.sendVendorNciMessage(mt, gid, oid, payload),
- SEND_VENDOR_NCI_STATUS_FAILED);
- }
-
- /**
- * Register an {@link NfcVendorNciCallback} to listen for Nfc vendor responses and notifications
- * <p>The provided callback will be invoked by the given {@link Executor}.
- *
- * <p>When first registering a callback, the callbacks's
- * {@link NfcVendorNciCallback#onVendorNciCallBack(byte[])} is immediately invoked to
- * notify the vendor notification.
- *
- * @param executor an {@link Executor} to execute given callback
- * @param callback user implementation of the {@link NfcVendorNciCallback}
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void registerNfcVendorNciCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull NfcVendorNciCallback callback) {
- mNfcVendorNciCallbackListener.register(executor, callback);
- }
-
- /**
- * Unregister the specified {@link NfcVendorNciCallback}
- *
- * <p>The same {@link NfcVendorNciCallback} object used when calling
- * {@link #registerNfcVendorNciCallback(Executor, NfcVendorNciCallback)} must be used.
- *
- * <p>Callbacks are automatically unregistered when application process goes away
- *
- * @param callback user implementation of the {@link NfcVendorNciCallback}
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void unregisterNfcVendorNciCallback(@NonNull NfcVendorNciCallback callback) {
- mNfcVendorNciCallbackListener.unregister(callback);
- }
-
- /**
- * Interface for receiving vendor NCI responses and notifications.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- public interface NfcVendorNciCallback {
- /**
- * Invoked when a vendor specific NCI response is received.
- *
- * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
- * the NCI specification.
- * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
- * @param payload containing vendor Nci message payload.
- */
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- void onVendorNciResponse(
- @IntRange(from = 0, to = 15) int gid, int oid, @NonNull byte[] payload);
-
- /**
- * Invoked when a vendor specific NCI notification is received.
- *
- * @param gid group ID of the command. This needs to be one of the vendor reserved GIDs from
- * the NCI specification.
- * @param oid opcode ID of the command. This is left to the OEM / vendor to decide.
- * @param payload containing vendor Nci message payload.
- */
- @FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD)
- void onVendorNciNotification(
- @IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
- }
-
- /**
- * Used by data migration to indicate data migration is in progrerss or not.
- *
- * Note: This is @hide intentionally since the client is inside the NFC apex.
- * @param inProgress true if migration is in progress, false once done.
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void indicateDataMigration(boolean inProgress) {
- callService(() -> sService.indicateDataMigration(inProgress, mContext.getPackageName()));
- }
-
- /**
- * Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @NonNull public NfcOemExtension getNfcOemExtension() {
- synchronized (sLock) {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- }
- return mNfcOemExtension;
- }
-
- /**
- * Activity action: Bring up the settings page that allows the user to enable or disable tag
- * intent reception for apps.
- *
- * <p>This will direct user to the settings page shows a list that asks users whether
- * they want to allow or disallow the package to start an activity when a tag is discovered.
- *
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
- public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE =
- "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
-
- /**
- * Checks whether the user has disabled the calling app from receiving NFC tag intents.
- *
- * <p>This method checks whether the caller package name is either not present in the user
- * disabled list or is explicitly allowed by the user.
- *
- * @return {@code true} if an app is either not present in the list or is added to the list
- * with the flag set to {@code true}. Otherwise, it returns {@code false}.
- * It also returns {@code true} if {@link isTagIntentAppPreferenceSupported} returns
- * {@code false}.
- *
- * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
- */
- @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
- public boolean isTagIntentAllowed() {
- if (!sHasNfcFeature) {
- throw new UnsupportedOperationException();
- }
- if (!isTagIntentAppPreferenceSupported()) {
- return true;
- }
- return callServiceReturn(() -> sService.isTagIntentAllowed(mContext.getPackageName(),
- UserHandle.myUserId()), false);
- }
-}
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.aidl b/nfc/java/android/nfc/NfcAntennaInfo.aidl
deleted file mode 100644
index d5e79fc37282..000000000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NfcAntennaInfo;
diff --git a/nfc/java/android/nfc/NfcAntennaInfo.java b/nfc/java/android/nfc/NfcAntennaInfo.java
deleted file mode 100644
index c57b2e029cc5..000000000000
--- a/nfc/java/android/nfc/NfcAntennaInfo.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Contains information on all available Nfc
- * antennas on an Android device as well as information
- * on the device itself in relation positioning of the
- * antennas.
- */
-public final class NfcAntennaInfo implements Parcelable {
- // Width of the device in millimeters.
- private final int mDeviceWidth;
- // Height of the device in millimeters.
- private final int mDeviceHeight;
- // Whether the device is foldable.
- private final boolean mDeviceFoldable;
- // All available Nfc Antennas on the device.
- private final List<AvailableNfcAntenna> mAvailableNfcAntennas;
-
- public NfcAntennaInfo(int deviceWidth, int deviceHeight, boolean deviceFoldable,
- @NonNull List<AvailableNfcAntenna> availableNfcAntennas) {
- this.mDeviceWidth = deviceWidth;
- this.mDeviceHeight = deviceHeight;
- this.mDeviceFoldable = deviceFoldable;
- this.mAvailableNfcAntennas = availableNfcAntennas;
- }
-
- /**
- * Width of the device in millimeters.
- */
- public int getDeviceWidth() {
- return mDeviceWidth;
- }
-
- /**
- * Height of the device in millimeters.
- */
- public int getDeviceHeight() {
- return mDeviceHeight;
- }
-
- /**
- * Whether the device is foldable. When the device is foldable,
- * the 0, 0 is considered to be top-left when the device is unfolded and
- * the screens are facing the user. For non-foldable devices 0, 0
- * is top-left when the user is facing the screen.
- */
- public boolean isDeviceFoldable() {
- return mDeviceFoldable;
- }
-
- /**
- * Get all NFC antennas that exist on the device.
- */
- @NonNull
- public List<AvailableNfcAntenna> getAvailableNfcAntennas() {
- return mAvailableNfcAntennas;
- }
-
- private NfcAntennaInfo(Parcel in) {
- this.mDeviceWidth = in.readInt();
- this.mDeviceHeight = in.readInt();
- this.mDeviceFoldable = in.readByte() != 0;
- this.mAvailableNfcAntennas = new ArrayList<>();
- in.readTypedList(this.mAvailableNfcAntennas,
- AvailableNfcAntenna.CREATOR);
- }
-
- public static final @NonNull Parcelable.Creator<NfcAntennaInfo> CREATOR =
- new Parcelable.Creator<NfcAntennaInfo>() {
- @Override
- public NfcAntennaInfo createFromParcel(Parcel in) {
- return new NfcAntennaInfo(in);
- }
-
- @Override
- public NfcAntennaInfo[] newArray(int size) {
- return new NfcAntennaInfo[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mDeviceWidth);
- dest.writeInt(mDeviceHeight);
- dest.writeByte((byte) (mDeviceFoldable ? 1 : 0));
- dest.writeTypedList(mAvailableNfcAntennas, 0);
- }
-}
diff --git a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java b/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
deleted file mode 100644
index 6ae58fd38cbe..000000000000
--- a/nfc/java/android/nfc/NfcControllerAlwaysOnListener.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcControllerAlwaysOnListener extends INfcControllerAlwaysOnListener.Stub {
- private static final String TAG = NfcControllerAlwaysOnListener.class.getSimpleName();
-
- private final INfcAdapter mAdapter;
-
- private final Map<ControllerAlwaysOnListener, Executor> mListenerMap = new HashMap<>();
-
- private boolean mCurrentState = false;
- private boolean mIsRegistered = false;
-
- public NfcControllerAlwaysOnListener(@NonNull INfcAdapter adapter) {
- mAdapter = adapter;
- }
-
- /**
- * Register a {@link ControllerAlwaysOnListener} with this
- * {@link NfcControllerAlwaysOnListener}
- *
- * @param executor an {@link Executor} to execute given listener
- * @param listener user implementation of the {@link ControllerAlwaysOnListener}
- */
- public void register(@NonNull Executor executor,
- @NonNull ControllerAlwaysOnListener listener) {
- try {
- if (!mAdapter.isControllerAlwaysOnSupported()) {
- return;
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to register");
- return;
- }
- synchronized (this) {
- if (mListenerMap.containsKey(listener)) {
- return;
- }
-
- mListenerMap.put(listener, executor);
- if (!mIsRegistered) {
- try {
- mAdapter.registerControllerAlwaysOnListener(this);
- mIsRegistered = true;
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to register");
- }
- }
- }
- }
-
- /**
- * Unregister the specified {@link ControllerAlwaysOnListener}
- *
- * @param listener user implementation of the {@link ControllerAlwaysOnListener}
- */
- public void unregister(@NonNull ControllerAlwaysOnListener listener) {
- try {
- if (!mAdapter.isControllerAlwaysOnSupported()) {
- return;
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to unregister");
- return;
- }
- synchronized (this) {
- if (!mListenerMap.containsKey(listener)) {
- return;
- }
-
- mListenerMap.remove(listener);
-
- if (mListenerMap.isEmpty() && mIsRegistered) {
- try {
- mAdapter.unregisterControllerAlwaysOnListener(this);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to unregister");
- }
- mIsRegistered = false;
- }
- }
- }
-
- private void sendCurrentState(@NonNull ControllerAlwaysOnListener listener) {
- synchronized (this) {
- Executor executor = mListenerMap.get(listener);
-
- final long identity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> listener.onControllerAlwaysOnChanged(
- mCurrentState));
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void onControllerAlwaysOnChanged(boolean isEnabled) {
- synchronized (this) {
- mCurrentState = isEnabled;
- for (ControllerAlwaysOnListener cb : mListenerMap.keySet()) {
- sendCurrentState(cb);
- }
- }
- }
-}
-
diff --git a/nfc/java/android/nfc/NfcEvent.java b/nfc/java/android/nfc/NfcEvent.java
deleted file mode 100644
index aff4f52f2bab..000000000000
--- a/nfc/java/android/nfc/NfcEvent.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-/**
- * Wraps information associated with any NFC event.
- *
- * <p>Immutable object, with direct access to the (final) fields.
- *
- * <p>An {@link NfcEvent} object is usually included in callbacks from
- * {@link NfcAdapter}. Check the documentation of the callback to see
- * which fields may be set.
- *
- * <p>This wrapper object is used (instead of parameters
- * in the callback) because it allows new fields to be added without breaking
- * API compatibility.
- *
- * @see NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete
- * @see NfcAdapter.CreateNdefMessageCallback#createNdefMessage
- */
-public final class NfcEvent {
- /**
- * The {@link NfcAdapter} associated with the NFC event.
- */
- public final NfcAdapter nfcAdapter;
-
- /**
- * The major LLCP version number of the peer associated with the NFC event.
- */
- public final int peerLlcpMajorVersion;
-
- /**
- * The minor LLCP version number of the peer associated with the NFC event.
- */
- public final int peerLlcpMinorVersion;
-
- NfcEvent(NfcAdapter nfcAdapter, byte peerLlcpVersion) {
- this.nfcAdapter = nfcAdapter;
- this.peerLlcpMajorVersion = (peerLlcpVersion & 0xF0) >> 4;
- this.peerLlcpMinorVersion = peerLlcpVersion & 0x0F;
- }
-}
diff --git a/nfc/java/android/nfc/NfcFrameworkInitializer.java b/nfc/java/android/nfc/NfcFrameworkInitializer.java
deleted file mode 100644
index 1ab8a1ebd72c..000000000000
--- a/nfc/java/android/nfc/NfcFrameworkInitializer.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.app.SystemServiceRegistry;
-import android.content.Context;
-
-/**
- * Class for performing registration for Nfc service.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public class NfcFrameworkInitializer {
- private NfcFrameworkInitializer() {}
-
- private static volatile NfcServiceManager sNfcServiceManager;
-
- /**
- * Sets an instance of {@link NfcServiceManager} that allows
- * the nfc mainline module to register/obtain nfc binder services. This is called
- * by the platform during the system initialization.
- *
- * @param nfcServiceManager instance of {@link NfcServiceManager} that allows
- * the nfc mainline module to register/obtain nfcd binder services.
- */
- public static void setNfcServiceManager(
- @NonNull NfcServiceManager nfcServiceManager) {
- if (sNfcServiceManager != null) {
- throw new IllegalStateException("setNfcServiceManager called twice!");
- }
-
- if (nfcServiceManager == null) {
- throw new IllegalArgumentException("nfcServiceManager must not be null");
- }
-
- sNfcServiceManager = nfcServiceManager;
- }
-
- /** @hide */
- public static NfcServiceManager getNfcServiceManager() {
- return sNfcServiceManager;
- }
-
- /**
- * Called by {@link SystemServiceRegistry}'s static initializer and registers NFC service
- * to {@link Context}, so that {@link Context#getSystemService} can return them.
- *
- * @throws IllegalStateException if this is called from anywhere besides
- * {@link SystemServiceRegistry}
- */
- public static void registerServiceWrappers() {
- SystemServiceRegistry.registerContextAwareService(Context.NFC_SERVICE,
- NfcManager.class, context -> new NfcManager(context));
- }
-}
diff --git a/nfc/java/android/nfc/NfcManager.java b/nfc/java/android/nfc/NfcManager.java
deleted file mode 100644
index 644e3122774b..000000000000
--- a/nfc/java/android/nfc/NfcManager.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.SystemService;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.os.Build;
-
-/**
- * High level manager used to obtain an instance of an {@link NfcAdapter}.
- * <p>
- * Use {@link android.content.Context#getSystemService(java.lang.String)}
- * with {@link Context#NFC_SERVICE} to create an {@link NfcManager},
- * then call {@link #getDefaultAdapter} to obtain the {@link NfcAdapter}.
- * <p>
- * Alternately, you can just call the static helper
- * {@link NfcAdapter#getDefaultAdapter(android.content.Context)}.
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about using NFC, read the
- * <a href="{@docRoot}guide/topics/nfc/index.html">Near Field Communication</a> developer guide.</p>
- * </div>
- *
- * @see NfcAdapter#getDefaultAdapter(android.content.Context)
- */
-@SystemService(Context.NFC_SERVICE)
-public final class NfcManager {
- private final NfcAdapter mAdapter;
-
- /**
- * @hide
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- public NfcManager(Context context) {
- NfcAdapter adapter;
- context = context.getApplicationContext();
- if (context == null) {
- throw new IllegalArgumentException(
- "context not associated with any application (using a mock context?)");
- }
- try {
- adapter = NfcAdapter.getNfcAdapter(context);
- } catch (UnsupportedOperationException e) {
- adapter = null;
- }
- mAdapter = adapter;
- }
-
- /**
- * Get the default NFC Adapter for this device.
- *
- * @return the default NFC Adapter
- */
- public NfcAdapter getDefaultAdapter() {
- return mAdapter;
- }
-}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
deleted file mode 100644
index b46e34368e77..000000000000
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ /dev/null
@@ -1,1248 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
-import static android.nfc.cardemulation.CardEmulation.PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
-import static android.nfc.cardemulation.CardEmulation.routeIntToString;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-import android.annotation.DurationMillisLong;
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.nfc.cardemulation.ApduServiceInfo;
-import android.nfc.cardemulation.CardEmulation;
-import android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.se.omapi.Reader;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * Used for OEM extension APIs.
- * This class holds all the APIs and callbacks defined for OEMs/vendors to extend the NFC stack
- * for their proprietary features.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class NfcOemExtension {
- private static final String TAG = "NfcOemExtension";
- private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
- private static final int TYPE_TECHNOLOGY = 0;
- private static final int TYPE_PROTOCOL = 1;
- private static final int TYPE_AID = 2;
- private static final int TYPE_SYSTEMCODE = 3;
-
- private final NfcAdapter mAdapter;
- private final NfcOemExtensionCallback mOemNfcExtensionCallback;
- private boolean mIsRegistered = false;
- private final Map<Callback, Executor> mCallbackMap = new HashMap<>();
- private final Context mContext;
- private final Object mLock = new Object();
- private boolean mCardEmulationActivated = false;
- private boolean mRfFieldActivated = false;
- private boolean mRfDiscoveryStarted = false;
- private boolean mEeListenActivated = false;
-
- /**
- * Broadcast Action: Sent on NFC stack initialization when NFC OEM extensions are enabled.
- * <p> OEM extension modules should use this intent to start their extension service </p>
- * @hide
- */
- public static final String ACTION_OEM_EXTENSION_INIT = "android.nfc.action.OEM_EXTENSION_INIT";
-
- /**
- * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
- * Enables the controller in default mode when NFC is disabled (existing API behavior).
- * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int ENABLE_DEFAULT = NfcAdapter.CONTROLLER_ALWAYS_ON_MODE_DEFAULT;
-
- /**
- * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
- * Enables the controller in transparent mode when NFC is disabled.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int ENABLE_TRANSPARENT = 2;
-
- /**
- * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
- * Enables the controller and initializes and enables the EE subsystem when NFC is disabled.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int ENABLE_EE = 3;
-
- /**
- * Mode Type for {@link #setControllerAlwaysOnMode(int)}.
- * Disable the Controller Always On Mode.
- * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int DISABLE = NfcAdapter.CONTROLLER_ALWAYS_ON_DISABLE;
-
- /**
- * Possible controller modes for {@link #setControllerAlwaysOnMode(int)}.
- *
- * @hide
- */
- @IntDef(prefix = { "" }, value = {
- ENABLE_DEFAULT,
- ENABLE_TRANSPARENT,
- ENABLE_EE,
- DISABLE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ControllerMode{}
-
- /**
- * Technology Type for {@link #getActiveNfceeList()}.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int NFCEE_TECH_NONE = 0;
-
- /**
- * Technology Type for {@link #getActiveNfceeList()}.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int NFCEE_TECH_A = 1;
-
- /**
- * Technology Type for {@link #getActiveNfceeList()}.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int NFCEE_TECH_B = 1 << 1;
-
- /**
- * Technology Type for {@link #getActiveNfceeList()}.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int NFCEE_TECH_F = 1 << 2;
-
- /**
- * Nfc technology flags for {@link #getActiveNfceeList()}.
- *
- * @hide
- */
- @IntDef(flag = true, value = {
- NFCEE_TECH_NONE,
- NFCEE_TECH_A,
- NFCEE_TECH_B,
- NFCEE_TECH_F,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface NfceeTechnology {}
-
- /**
- * Event that Host Card Emulation is activated.
- */
- public static final int HCE_ACTIVATE = 1;
- /**
- * Event that some data is transferred in Host Card Emulation.
- */
- public static final int HCE_DATA_TRANSFERRED = 2;
- /**
- * Event that Host Card Emulation is deactivated.
- */
- public static final int HCE_DEACTIVATE = 3;
- /**
- * Possible events from {@link Callback#onHceEventReceived}.
- *
- * @hide
- */
- @IntDef(value = {
- HCE_ACTIVATE,
- HCE_DATA_TRANSFERRED,
- HCE_DEACTIVATE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface HostCardEmulationAction {}
-
- /**
- * Status code returned when the polling state change request succeeded.
- * @see #pausePolling()
- * @see #resumePolling()
- */
- public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
- /**
- * Status code returned when the polling state change request is already in
- * required state.
- * @see #pausePolling()
- * @see #resumePolling()
- */
- public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
- /**
- * Possible status codes for {@link #pausePolling()} and
- * {@link #resumePolling()}.
- * @hide
- */
- @IntDef(value = {
- POLLING_STATE_CHANGE_SUCCEEDED,
- POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface PollingStateChangeStatusCode {}
-
- /**
- * Status OK
- */
- public static final int STATUS_OK = 0;
- /**
- * Status unknown error
- */
- public static final int STATUS_UNKNOWN_ERROR = 1;
-
- /**
- * Status codes passed to OEM extension callbacks.
- *
- * @hide
- */
- @IntDef(value = {
- STATUS_OK,
- STATUS_UNKNOWN_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface StatusCode {}
-
- /**
- * Routing commit succeeded.
- */
- public static final int COMMIT_ROUTING_STATUS_OK = 0;
- /**
- * Routing commit failed.
- */
- public static final int COMMIT_ROUTING_STATUS_FAILED = 3;
- /**
- * Routing commit failed due to the update is in progress.
- */
- public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6;
-
- /**
- * Status codes returned when calling {@link #forceRoutingTableCommit()}
- * @hide
- */
- @IntDef(prefix = "COMMIT_ROUTING_STATUS_", value = {
- COMMIT_ROUTING_STATUS_OK,
- COMMIT_ROUTING_STATUS_FAILED,
- COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CommitRoutingStatusCode {}
- /**
- * Interface for Oem extensions for NFC.
- */
- public interface Callback {
- /**
- * Notify Oem to tag is connected or not
- * ex - if tag is connected notify cover and Nfctest app if app is in testing mode
- *
- * @param connected status of the tag true if tag is connected otherwise false
- */
- void onTagConnected(boolean connected);
-
- /**
- * Update the Nfc Adapter State
- * @param state new state that need to be updated
- */
- void onStateUpdated(@NfcAdapter.AdapterState int state);
- /**
- * Check if NfcService apply routing method need to be skipped for
- * some feature.
- * @param isSkipped The {@link Consumer} to be completed. If apply routing can be skipped,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- */
- void onApplyRouting(@NonNull Consumer<Boolean> isSkipped);
- /**
- * Check if NfcService ndefRead method need to be skipped To skip
- * and start checking for presence of tag
- * @param isSkipped The {@link Consumer} to be completed. If Ndef read can be skipped,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- */
- void onNdefRead(@NonNull Consumer<Boolean> isSkipped);
- /**
- * Method to check if Nfc is allowed to be enabled by OEMs.
- * @param isAllowed The {@link Consumer} to be completed. If enabling NFC is allowed,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- * false if NFC cannot be enabled at this time.
- */
- void onEnableRequested(@NonNull Consumer<Boolean> isAllowed);
- /**
- * Method to check if Nfc is allowed to be disabled by OEMs.
- * @param isAllowed The {@link Consumer} to be completed. If disabling NFC is allowed,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- * false if NFC cannot be disabled at this time.
- */
- void onDisableRequested(@NonNull Consumer<Boolean> isAllowed);
-
- /**
- * Callback to indicate that Nfc starts to boot.
- */
- void onBootStarted();
-
- /**
- * Callback to indicate that Nfc starts to enable.
- */
- void onEnableStarted();
-
- /**
- * Callback to indicate that Nfc starts to disable.
- */
- void onDisableStarted();
-
- /**
- * Callback to indicate if NFC boots successfully or not.
- * @param status the status code indicating if boot finished successfully
- */
- void onBootFinished(@StatusCode int status);
-
- /**
- * Callback to indicate if NFC is successfully enabled.
- * @param status the status code indicating if enable finished successfully
- */
- void onEnableFinished(@StatusCode int status);
-
- /**
- * Callback to indicate if NFC is successfully disabled.
- * @param status the status code indicating if disable finished successfully
- */
- void onDisableFinished(@StatusCode int status);
-
- /**
- * Check if NfcService tag dispatch need to be skipped.
- * @param isSkipped The {@link Consumer} to be completed. If tag dispatch can be skipped,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- */
- void onTagDispatch(@NonNull Consumer<Boolean> isSkipped);
-
- /**
- * Notifies routing configuration is changed.
- * @param isCommitRoutingSkipped The {@link Consumer} to be
- * completed. If routing commit should be skipped,
- * the {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
- */
- void onRoutingChanged(@NonNull Consumer<Boolean> isCommitRoutingSkipped);
-
- /**
- * API to activate start stop cpu boost on hce event.
- *
- * <p>When HCE is activated, transferring data, and deactivated,
- * must call this method to activate, start and stop cpu boost respectively.
- * @param action Flag indicating actions to activate, start and stop cpu boost.
- */
- void onHceEventReceived(@HostCardEmulationAction int action);
-
- /**
- * API to notify when reader option has been changed using
- * {@link NfcAdapter#enableReaderOption(boolean)} by some app.
- * @param enabled Flag indicating ReaderMode enabled/disabled
- */
- void onReaderOptionChanged(boolean enabled);
-
- /**
- * Notifies NFC is activated in listen mode.
- * NFC Forum NCI-2.3 ch.5.2.6 specification
- *
- * <p>NFCC is ready to communicate with a Card reader
- *
- * @param isActivated true, if card emulation activated, else de-activated.
- */
- void onCardEmulationActivated(boolean isActivated);
-
- /**
- * Notifies the Remote NFC Endpoint RF Field is activated.
- * NFC Forum NCI-2.3 ch.5.3 specification
- *
- * @param isActivated true, if RF Field is ON, else RF Field is OFF.
- */
- void onRfFieldActivated(boolean isActivated);
-
- /**
- * Notifies the NFC RF discovery is started or in the IDLE state.
- * NFC Forum NCI-2.3 ch.5.2 specification
- *
- * @param isDiscoveryStarted true, if RF discovery started, else RF state is Idle.
- */
- void onRfDiscoveryStarted(boolean isDiscoveryStarted);
-
- /**
- * Notifies the NFCEE (NFC Execution Environment) Listen has been activated.
- *
- * @param isActivated true, if EE Listen is ON, else EE Listen is OFF.
- */
- 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.
- *
- * @param packages the OEM packages name stored in the tag
- * @param intentConsumer The {@link Consumer} to be completed.
- * The {@link Consumer#accept(Object)} should be called with
- * the Intent required.
- *
- */
- void onGetOemAppSearchIntent(@NonNull List<String> packages,
- @NonNull Consumer<Intent> intentConsumer);
-
- /**
- * Checks if the NDEF message contains any specific OEM package executable content
- *
- * @param tag the {@link android.nfc.Tag Tag}
- * @param message NDEF Message to read from tag
- * @param hasOemExecutableContent The {@link Consumer} to be completed. If there is
- * OEM package executable content, the
- * {@link Consumer#accept(Object)} should be called with
- * {@link Boolean#TRUE}, otherwise call with
- * {@link Boolean#FALSE}.
- */
- void onNdefMessage(@NonNull Tag tag, @NonNull NdefMessage message,
- @NonNull Consumer<Boolean> hasOemExecutableContent);
-
- /**
- * Callback to indicate the app chooser activity should be launched for handling CE
- * transaction. This is invoked for example when there are more than 1 app installed that
- * can handle the HCE transaction. OEMs can launch the Activity based
- * on their requirement.
- *
- * @param selectedAid the selected AID from APDU
- * @param services {@link ApduServiceInfo} of the service triggering the activity
- * @param failedComponent the component failed to be resolved
- * @param category the category of the service
- */
- void onLaunchHceAppChooserActivity(@NonNull String selectedAid,
- @NonNull List<ApduServiceInfo> services,
- @NonNull ComponentName failedComponent,
- @NonNull String category);
-
- /**
- * Callback to indicate tap again dialog should be launched for handling HCE transaction.
- * This is invoked for example when a CE service needs the device to unlocked before
- * handling the transaction. OEMs can launch the Activity based on their requirement.
- *
- * @param service {@link ApduServiceInfo} of the service triggering the dialog
- * @param category the category of the service
- */
- void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
-
- /**
- * Callback to indicate that routing table is full and the OEM can optionally launch a
- * dialog to request the user to remove some Card Emulation apps from the device to free
- * routing table space.
- */
- void onRoutingTableFull();
-
- /**
- * Callback when OEM specified log event are notified.
- * @param item the log items that contains log information of NFC event.
- */
- void onLogEventNotified(@NonNull OemLogItems item);
-
- /**
- * Callback to to extract OEM defined packages from given NDEF message when
- * a NFC tag is detected. These are used to handle NFC tags encoded with a
- * proprietary format for storing app name (Android native app format).
- *
- * @param message NDEF message containing OEM package names
- * @param packageConsumer The {@link Consumer} to be completed.
- * The {@link Consumer#accept(Object)} should be called with
- * the list of package names.
- */
- void onExtractOemPackages(@NonNull NdefMessage message,
- @NonNull Consumer<List<String>> packageConsumer);
- }
-
-
- /**
- * Constructor to be used only by {@link NfcAdapter}.
- */
- NfcOemExtension(@NonNull Context context, @NonNull NfcAdapter adapter) {
- mContext = context;
- mAdapter = adapter;
- mOemNfcExtensionCallback = new NfcOemExtensionCallback();
- }
-
- /**
- * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
- * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
- * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
- * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
- * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- *
- * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
- * read/write operations.
- *
- * <p>Returns {@link T4tNdefNfcee}
- * <p>Does not cause any RF activity and does not block.
- * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
- * @hide
- */
- @SystemApi
- @NonNull
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public T4tNdefNfcee getT4tNdefNfcee() {
- return T4tNdefNfcee.getInstance();
- }
-
- /**
- * Register an {@link Callback} to listen for NFC oem extension callbacks
- * Multiple clients can register and callbacks will be invoked asynchronously.
- *
- * <p>The provided callback will be invoked by the given {@link Executor}.
- * As part of {@link #registerCallback(Executor, Callback)} the
- * {@link Callback} will be invoked with current NFC state
- * before the {@link #registerCallback(Executor, Callback)} function completes.
- *
- * @param executor an {@link Executor} to execute given callback
- * @param callback oem implementation of {@link Callback}
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void registerCallback(@NonNull @CallbackExecutor Executor executor,
- @NonNull Callback callback) {
- synchronized (mLock) {
- if (executor == null || callback == null) {
- Log.e(TAG, "Executor and Callback must not be null!");
- throw new IllegalArgumentException();
- }
-
- if (mCallbackMap.containsKey(callback)) {
- Log.e(TAG, "Callback already registered. Unregister existing callback before"
- + "registering");
- throw new IllegalArgumentException();
- }
- mCallbackMap.put(callback, executor);
- if (!mIsRegistered) {
- NfcAdapter.callService(() -> {
- NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
- mIsRegistered = true;
- });
- } else {
- updateNfCState(callback, executor);
- }
- }
- }
-
- private void updateNfCState(Callback callback, Executor executor) {
- if (callback != null) {
- Log.i(TAG, "updateNfCState");
- executor.execute(() -> {
- callback.onCardEmulationActivated(mCardEmulationActivated);
- callback.onRfFieldActivated(mRfFieldActivated);
- callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
- callback.onEeListenActivated(mEeListenActivated);
- });
- }
- }
-
- /**
- * Unregister the specified {@link Callback}
- *
- * <p>The same {@link Callback} object used when calling
- * {@link #registerCallback(Executor, Callback)} must be used.
- *
- * <p>Callbacks are automatically unregistered when an application process goes away
- *
- * @param callback oem implementation of {@link Callback}
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void unregisterCallback(@NonNull Callback callback) {
- synchronized (mLock) {
- if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
- Log.e(TAG, "Callback not registered");
- throw new IllegalArgumentException();
- }
- if (mCallbackMap.size() == 1) {
- NfcAdapter.callService(() -> {
- NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
- mIsRegistered = false;
- mCallbackMap.remove(callback);
- });
- } else {
- mCallbackMap.remove(callback);
- }
- }
- }
-
- /**
- * Clear NfcService preference, interface method to clear NFC preference values on OEM specific
- * events. For ex: on soft reset, Nfc default values needs to be overridden by OEM defaults.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void clearPreference() {
- NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference());
- }
-
- /**
- * Get the screen state from system and set it to current screen state.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void synchronizeScreenState() {
- NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState());
- }
-
- /**
- * Check if the firmware needs updating.
- *
- * <p>If an update is needed, a firmware will be triggered when NFC is disabled.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void maybeTriggerFirmwareUpdate() {
- NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
- }
-
- /**
- * Get the Active NFCEE (NFC Execution Environment) List
- *
- * @return Map< String, @NfceeTechnology Integer >
- * A HashMap where keys are activated secure elements and
- * the values are bitmap of technologies supported by each secure element:
- * NFCEE_TECH_A == 0x1
- * NFCEE_TECH_B == 0x2
- * NFCEE_TECH_F == 0x4
- * and keys can contain "eSE" and "SIM" with a number,
- * in case of failure an empty map is returned.
- * @see Reader#getName() for the list of possible NFCEE names.
- */
- @NonNull
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public Map<String, Integer> getActiveNfceeList() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.fetchActiveNfceeList(), new HashMap<String, Integer>());
- }
-
- /**
- * Sets NFC controller always on feature.
- * <p>This API is for the NFCC internal state management. It allows to discriminate
- * the controller function from the NFC function by keeping the NFC controller on without
- * any NFC RF enabled if necessary.
- * <p>This call is asynchronous, register listener {@link NfcAdapter.ControllerAlwaysOnListener}
- * by {@link NfcAdapter#registerControllerAlwaysOnListener} to find out when the operation is
- * complete.
- * <p> Note: This adds more always on modes on top of existing
- * {@link NfcAdapter#setControllerAlwaysOn(boolean)} API which can be used to set the NFCC in
- * only {@link #ENABLE_DEFAULT} and {@link #DISABLE} modes.
- * @param mode one of {@link ControllerMode} modes
- * @throws UnsupportedOperationException if
- * <li> if FEATURE_NFC, FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF,
- * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE
- * are unavailable </li>
- * <li> if the feature is unavailable @see NfcAdapter#isNfcControllerAlwaysOnSupported() </li>
- * @hide
- * @see NfcAdapter#setControllerAlwaysOn(boolean)
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON)
- public void setControllerAlwaysOnMode(@ControllerMode int mode) {
- if (!NfcAdapter.sHasNfcFeature && !NfcAdapter.sHasCeFeature) {
- throw new UnsupportedOperationException();
- }
- NfcAdapter.callService(() -> NfcAdapter.sService.setControllerAlwaysOn(mode));
- }
-
- /**
- * Triggers NFC initialization. If OEM extension is registered
- * (indicated via `enable_oem_extension` NFC overlay), the NFC stack initialization at bootup
- * is delayed until the OEM extension app triggers the initialization via this call.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void triggerInitialization() {
- NfcAdapter.callService(() -> NfcAdapter.sService.triggerInitialization());
- }
-
- /**
- * Gets the last user toggle status.
- * @return true if NFC is set to ON, false otherwise
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean hasUserEnabledNfc() {
- return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.getSettingStatus(), false);
- }
-
- /**
- * Checks if the tag is present or not.
- * @return true if the tag is present, false otherwise
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean isTagPresent() {
- return NfcAdapter.callServiceReturn(() -> NfcAdapter.sService.isTagPresent(), false);
- }
-
- /**
- * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
- * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
- * Use {@link #resumePolling()} to resume the polling.
- * Use {@link #getMaxPausePollingTimeoutMs()} to check the max timeout value.
- * @param timeoutInMs the pause polling duration in millisecond.
- * @return status of the operation
- * @throws IllegalArgumentException if timeoutInMs value is invalid
- * (0 < timeoutInMs < max).
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong long timeoutInMs) {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.pausePolling(timeoutInMs),
- POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
- }
-
- /**
- * Resumes default NFC tag reader mode polling for the current device state if polling is
- * paused. Calling this while already in polling is a no-op.
- * @return status of the operation
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public @PollingStateChangeStatusCode int resumePolling() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.resumePolling(),
- POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
- }
-
- /**
- * Gets the max pause polling timeout value in millisecond.
- * @return long integer representing the max timeout
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @DurationMillisLong
- public long getMaxPausePollingTimeoutMills() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.getMaxPausePollingTimeoutMs(), 0L);
- }
-
- /**
- * Set whether to enable auto routing change or not (enabled by default).
- * If disabled, routing targets are limited to a single off-host destination.
- *
- * @param state status of auto routing change, true if enable, otherwise false
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public void setAutoChangeEnabled(boolean state) {
- NfcAdapter.callService(() ->
- NfcAdapter.sCardEmulationService.setAutoChangeStatus(state));
- }
-
- /**
- * Check if auto routing change is enabled or not.
- *
- * @return true if enabled, otherwise false
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean isAutoChangeEnabled() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sCardEmulationService.isAutoChangeEnabled(), false);
- }
-
- /**
- * Get current routing status
- *
- * @return {@link RoutingStatus} indicating the default route, default ISO-DEP
- * route and default off-host route.
- */
- @NonNull
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public RoutingStatus getRoutingStatus() {
- List<String> status = NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sCardEmulationService.getRoutingStatus(), new ArrayList<>());
- return new RoutingStatus(routeStringToInt(status.get(0)),
- routeStringToInt(status.get(1)),
- routeStringToInt(status.get(2)));
- }
-
- /**
- * Overwrites NFC controller routing table, which includes Protocol Route, Technology Route,
- * and Empty AID Route.
- *
- * The parameter set to
- * {@link ProtocolAndTechnologyRoute#PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
- * can be used to keep current values for that entry. At least one route should be overridden
- * when calling this API, otherwise throw {@link IllegalArgumentException}.
- *
- * @param protocol ISO-DEP route destination, where the possible inputs are defined in
- * {@link ProtocolAndTechnologyRoute}.
- * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
- * are defined in
- * {@link ProtocolAndTechnologyRoute}
- * @param emptyAid Zero-length AID route destination, where the possible inputs are defined in
- * {@link ProtocolAndTechnologyRoute}
- * @param systemCode System Code route destination, where the possible inputs are defined in
- * {@link ProtocolAndTechnologyRoute}
- */
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public void overwriteRoutingTable(
- @CardEmulation.ProtocolAndTechnologyRoute int protocol,
- @CardEmulation.ProtocolAndTechnologyRoute int technology,
- @CardEmulation.ProtocolAndTechnologyRoute int emptyAid,
- @CardEmulation.ProtocolAndTechnologyRoute int systemCode) {
-
- String protocolRoute = routeIntToString(protocol);
- String technologyRoute = routeIntToString(technology);
- String emptyAidRoute = routeIntToString(emptyAid);
- String systemCodeRoute = routeIntToString(systemCode);
-
- NfcAdapter.callService(() ->
- NfcAdapter.sCardEmulationService.overwriteRoutingTable(
- mContext.getUser().getIdentifier(),
- emptyAidRoute,
- protocolRoute,
- technologyRoute,
- systemCodeRoute
- ));
- }
-
- /**
- * Gets current routing table entries.
- * @return List of {@link NfcRoutingTableEntry} representing current routing table
- */
- @NonNull
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public List<NfcRoutingTableEntry> getRoutingTable() {
- List<Entry> entryList = NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sService.getRoutingTableEntryList(), null);
- List<NfcRoutingTableEntry> result = new ArrayList<>();
- for (Entry entry : entryList) {
- switch (entry.getType()) {
- case TYPE_TECHNOLOGY -> result.add(
- new RoutingTableTechnologyEntry(entry.getNfceeId(),
- RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()),
- routeStringToInt(entry.getRoutingType()))
- );
- case TYPE_PROTOCOL -> result.add(
- new RoutingTableProtocolEntry(entry.getNfceeId(),
- RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()),
- routeStringToInt(entry.getRoutingType()))
- );
- case TYPE_AID -> result.add(
- new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry(),
- routeStringToInt(entry.getRoutingType()))
- );
- case TYPE_SYSTEMCODE -> result.add(
- new RoutingTableSystemCodeEntry(entry.getNfceeId(),
- entry.getEntry().getBytes(StandardCharsets.UTF_8),
- routeStringToInt(entry.getRoutingType()))
- );
- }
- }
- return result;
- }
-
- /**
- * API to force a routing table commit.
- * @return a {@link StatusCode} to indicate if commit routing succeeded or not
- */
- @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @CommitRoutingStatusCode
- public int forceRoutingTableCommit() {
- return NfcAdapter.callServiceReturn(
- () -> NfcAdapter.sService.commitRouting(), COMMIT_ROUTING_STATUS_FAILED);
- }
-
- private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
-
- @Override
- public void onTagConnected(boolean connected) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(connected, cb::onTagConnected, ex));
- }
-
- @Override
- public void onCardEmulationActivated(boolean isActivated) throws RemoteException {
- mCardEmulationActivated = isActivated;
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(isActivated, cb::onCardEmulationActivated, ex));
- }
-
- @Override
- public void onRfFieldActivated(boolean isActivated) throws RemoteException {
- mRfFieldActivated = isActivated;
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(isActivated, cb::onRfFieldActivated, ex));
- }
-
- @Override
- public void onRfDiscoveryStarted(boolean isDiscoveryStarted) throws RemoteException {
- mRfDiscoveryStarted = isDiscoveryStarted;
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(isDiscoveryStarted, cb::onRfDiscoveryStarted, ex));
- }
-
- @Override
- public void onEeListenActivated(boolean isActivated) throws RemoteException {
- mEeListenActivated = isActivated;
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(isActivated, cb::onEeListenActivated, ex));
- }
-
- @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));
- }
-
- @Override
- public void onApplyRouting(ResultReceiver isSkipped) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isSkipped), cb::onApplyRouting, ex));
- }
- @Override
- public void onNdefRead(ResultReceiver isSkipped) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isSkipped), cb::onNdefRead, ex));
- }
- @Override
- public void onEnable(ResultReceiver isAllowed) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isAllowed), cb::onEnableRequested, ex));
- }
- @Override
- public void onDisable(ResultReceiver isAllowed) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isAllowed), cb::onDisableRequested, ex));
- }
- @Override
- public void onBootStarted() throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(null, (Object input) -> cb.onBootStarted(), ex));
- }
- @Override
- public void onEnableStarted() throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(null, (Object input) -> cb.onEnableStarted(), ex));
- }
- @Override
- public void onDisableStarted() throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(null, (Object input) -> cb.onDisableStarted(), ex));
- }
- @Override
- public void onBootFinished(int status) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(status, cb::onBootFinished, ex));
- }
- @Override
- public void onEnableFinished(int status) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(status, cb::onEnableFinished, ex));
- }
- @Override
- public void onDisableFinished(int status) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(status, cb::onDisableFinished, ex));
- }
- @Override
- public void onTagDispatch(ResultReceiver isSkipped) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isSkipped), cb::onTagDispatch, ex));
- }
- @Override
- public void onRoutingChanged(ResultReceiver isSkipped) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(
- new ReceiverWrapper<>(isSkipped), cb::onRoutingChanged, ex));
- }
- @Override
- public void onHceEventReceived(int action) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(action, cb::onHceEventReceived, ex));
- }
-
- @Override
- public void onReaderOptionChanged(boolean enabled) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(enabled, cb::onReaderOptionChanged, ex));
- }
-
- public void onRoutingTableFull() throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(null,
- (Object input) -> cb.onRoutingTableFull(), ex));
- }
-
- @Override
- public void onGetOemAppSearchIntent(List<String> packages, ResultReceiver intentConsumer)
- throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoid2ArgCallback(packages, new ReceiverWrapper<>(intentConsumer),
- cb::onGetOemAppSearchIntent, ex));
- }
-
- @Override
- public void onNdefMessage(Tag tag, NdefMessage message,
- ResultReceiver hasOemExecutableContent) throws RemoteException {
- mCallbackMap.forEach((cb, ex) -> {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- try {
- ex.execute(() -> cb.onNdefMessage(
- tag, message, new ReceiverWrapper<>(hasOemExecutableContent)));
- } catch (RuntimeException exception) {
- throw exception;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- });
- }
-
- @Override
- public void onLaunchHceAppChooserActivity(String selectedAid,
- List<ApduServiceInfo> services,
- ComponentName failedComponent, String category)
- throws RemoteException {
- mCallbackMap.forEach((cb, ex) -> {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- try {
- ex.execute(() -> cb.onLaunchHceAppChooserActivity(
- selectedAid, services, failedComponent, category));
- } catch (RuntimeException exception) {
- throw exception;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- });
- }
-
- @Override
- public void onLaunchHceTapAgainActivity(ApduServiceInfo service, String category)
- throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoid2ArgCallback(service, category, cb::onLaunchHceTapAgainDialog, ex));
- }
-
- @Override
- public void onLogEventNotified(OemLogItems item) throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(item, cb::onLogEventNotified, ex));
- }
-
- @Override
- public void onExtractOemPackages(NdefMessage message, ResultReceiver packageConsumer)
- throws RemoteException {
- mCallbackMap.forEach((cb, ex) ->
- handleVoid2ArgCallback(message,
- new ReceiverWrapper<>(packageConsumer),
- cb::onExtractOemPackages, ex));
- }
-
- private <T> void handleVoidCallback(
- T input, Consumer<T> callbackMethod, Executor executor) {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> callbackMethod.accept(input));
- } catch (RuntimeException ex) {
- throw ex;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- private <T1, T2> void handleVoid2ArgCallback(
- T1 input1, T2 input2, BiConsumer<T1, T2> callbackMethod, Executor executor) {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- try {
- executor.execute(() -> callbackMethod.accept(input1, input2));
- } catch (RuntimeException ex) {
- throw ex;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- private <S, T> S handleNonVoidCallbackWithInput(
- S defaultValue, T input, Function<T, S> callbackMethod) throws RemoteException {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- S result = defaultValue;
- try {
- ExecutorService executor = Executors.newSingleThreadExecutor();
- FutureTask<S> futureTask = new FutureTask<>(() -> callbackMethod.apply(input));
- var unused = executor.submit(futureTask);
- try {
- result = futureTask.get(
- OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
- } catch (ExecutionException | InterruptedException e) {
- e.printStackTrace();
- } catch (TimeoutException e) {
- Log.w(TAG, "Callback timed out: " + callbackMethod);
- e.printStackTrace();
- } finally {
- executor.shutdown();
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return result;
- }
- }
-
- private <T> T handleNonVoidCallbackWithoutInput(T defaultValue, Supplier<T> callbackMethod)
- throws RemoteException {
- synchronized (mLock) {
- final long identity = Binder.clearCallingIdentity();
- T result = defaultValue;
- try {
- ExecutorService executor = Executors.newSingleThreadExecutor();
- FutureTask<T> futureTask = new FutureTask<>(callbackMethod::get);
- var unused = executor.submit(futureTask);
- try {
- result = futureTask.get(
- OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
- } catch (ExecutionException | InterruptedException e) {
- e.printStackTrace();
- } catch (TimeoutException e) {
- Log.w(TAG, "Callback timed out: " + callbackMethod);
- e.printStackTrace();
- } finally {
- executor.shutdown();
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return result;
- }
- }
- }
-
- private @CardEmulation.ProtocolAndTechnologyRoute int routeStringToInt(String route) {
- if (route.equals("DH")) {
- return PROTOCOL_AND_TECHNOLOGY_ROUTE_DH;
- } else if (route.startsWith("eSE")) {
- return PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE;
- } else if (route.startsWith("SIM")) {
- return PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC;
- } else {
- throw new IllegalStateException("Unexpected value: " + route);
- }
- }
-
- private class ReceiverWrapper<T> implements Consumer<T> {
- private final ResultReceiver mResultReceiver;
-
- ReceiverWrapper(ResultReceiver resultReceiver) {
- mResultReceiver = resultReceiver;
- }
-
- @Override
- public void accept(T result) {
- if (result instanceof Boolean) {
- mResultReceiver.send((Boolean) result ? 1 : 0, null);
- } else if (result instanceof Intent) {
- Bundle bundle = new Bundle();
- bundle.putParcelable("intent", (Intent) result);
- mResultReceiver.send(0, bundle);
- } else if (result instanceof List<?> list) {
- if (list.stream().allMatch(String.class::isInstance)) {
- Bundle bundle = new Bundle();
- bundle.putStringArray("packageNames",
- list.stream().map(pkg -> (String) pkg).toArray(String[]::new));
- mResultReceiver.send(0, bundle);
- }
- }
- }
-
- @Override
- public Consumer<T> andThen(Consumer<? super T> after) {
- return Consumer.super.andThen(after);
- }
- }
-}
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
deleted file mode 100644
index 4153779a8ba2..000000000000
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-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},
- * {@link RoutingTableAidEntry} and {@link RoutingTableSystemCodeEntry}.
- *
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public abstract class NfcRoutingTableEntry {
- private final int mNfceeId;
- private final int mType;
- private final int mRouteType;
-
- /**
- * 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, @RoutingTableType int type,
- @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
- mNfceeId = nfceeId;
- mType = type;
- mRouteType = routeType;
- }
-
- /**
- * Gets the NFCEE Id of this entry.
- * @return an integer of NFCEE Id.
- */
- public int getNfceeId() {
- return mNfceeId;
- }
-
- /**
- * Get the type of this entry.
- * @return an integer defined in {@link RoutingTableType}
- */
- @RoutingTableType
- public int getType() {
- return mType;
- }
-
- /**
- * Get the route type of this entry.
- * @return an integer defined in
- * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
- */
- @CardEmulation.ProtocolAndTechnologyRoute
- public int getRouteType() {
- return mRouteType;
- }
-}
diff --git a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java b/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
deleted file mode 100644
index 742d75fe4bc3..000000000000
--- a/nfc/java/android/nfc/NfcVendorNciCallbackListener.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.NfcVendorNciCallback;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public final class NfcVendorNciCallbackListener extends INfcVendorNciCallback.Stub {
- private static final String TAG = "Nfc.NfcVendorNciCallbacks";
- private final INfcAdapter mAdapter;
- private boolean mIsRegistered = false;
- private final Map<NfcVendorNciCallback, Executor> mCallbackMap = new HashMap<>();
-
- public NfcVendorNciCallbackListener(@NonNull INfcAdapter adapter) {
- mAdapter = adapter;
- }
-
- public void register(@NonNull Executor executor, @NonNull NfcVendorNciCallback callback) {
- synchronized (this) {
- if (mCallbackMap.containsKey(callback)) {
- return;
- }
- mCallbackMap.put(callback, executor);
- if (!mIsRegistered) {
- try {
- mAdapter.registerVendorExtensionCallback(this);
- mIsRegistered = true;
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to register adapter state callback");
- mCallbackMap.remove(callback);
- throw e.rethrowFromSystemServer();
- }
- }
- }
- }
-
- public void unregister(@NonNull NfcVendorNciCallback callback) {
- synchronized (this) {
- if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
- return;
- }
- if (mCallbackMap.size() == 1) {
- try {
- mAdapter.unregisterVendorExtensionCallback(this);
- mIsRegistered = false;
- mCallbackMap.remove(callback);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to unregister AdapterStateCallback with service");
- throw e.rethrowFromSystemServer();
- }
- } else {
- mCallbackMap.remove(callback);
- }
- }
- }
-
- @Override
- public void onVendorResponseReceived(int gid, int oid, @NonNull byte[] payload)
- throws RemoteException {
- synchronized (this) {
- final long identity = Binder.clearCallingIdentity();
- try {
- for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
- Executor executor = mCallbackMap.get(callback);
- executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));
- }
- } catch (RuntimeException ex) {
- throw ex;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void onVendorNotificationReceived(int gid, int oid, @NonNull byte[] payload)
- throws RemoteException {
- synchronized (this) {
- final long identity = Binder.clearCallingIdentity();
- try {
- for (NfcVendorNciCallback callback : mCallbackMap.keySet()) {
- Executor executor = mCallbackMap.get(callback);
- executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));
- }
- } catch (RuntimeException ex) {
- throw ex;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-}
diff --git a/nfc/java/android/nfc/NfcWlcStateListener.java b/nfc/java/android/nfc/NfcWlcStateListener.java
deleted file mode 100644
index 890cb090f587..000000000000
--- a/nfc/java/android/nfc/NfcWlcStateListener.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.NonNull;
-import android.nfc.NfcAdapter.WlcStateListener;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/**
- * @hide
- */
-public class NfcWlcStateListener extends INfcWlcStateListener.Stub {
- private static final String TAG = NfcWlcStateListener.class.getSimpleName();
-
- private final INfcAdapter mAdapter;
-
- private final Map<WlcStateListener, Executor> mListenerMap = new HashMap<>();
-
- private WlcListenerDeviceInfo mCurrentState = null;
- private boolean mIsRegistered = false;
-
- public NfcWlcStateListener(@NonNull INfcAdapter adapter) {
- mAdapter = adapter;
- }
-
- /**
- * Register a {@link WlcStateListener} with this
- * {@link WlcStateListener}
- *
- * @param executor an {@link Executor} to execute given listener
- * @param listener user implementation of the {@link WlcStateListener}
- */
- public void register(@NonNull Executor executor, @NonNull WlcStateListener listener) {
- synchronized (this) {
- if (mListenerMap.containsKey(listener)) {
- return;
- }
-
- mListenerMap.put(listener, executor);
-
- if (!mIsRegistered) {
- try {
- mAdapter.registerWlcStateListener(this);
- mIsRegistered = true;
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to register");
- }
- }
- }
- }
-
- /**
- * Unregister the specified {@link WlcStateListener}
- *
- * @param listener user implementation of the {@link WlcStateListener}
- */
- public void unregister(@NonNull WlcStateListener listener) {
- synchronized (this) {
- if (!mListenerMap.containsKey(listener)) {
- return;
- }
-
- mListenerMap.remove(listener);
-
- if (mListenerMap.isEmpty() && mIsRegistered) {
- try {
- mAdapter.unregisterWlcStateListener(this);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to unregister");
- }
- mIsRegistered = false;
- }
- }
- }
-
- private void sendCurrentState(@NonNull WlcStateListener listener) {
- synchronized (this) {
- Executor executor = mListenerMap.get(listener);
- final long identity = Binder.clearCallingIdentity();
- try {
- if (Flags.enableNfcCharging()) {
- executor.execute(() -> listener.onWlcStateChanged(
- mCurrentState));
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- @Override
- public void onWlcStateChanged(@NonNull WlcListenerDeviceInfo wlcListenerDeviceInfo) {
- synchronized (this) {
- mCurrentState = wlcListenerDeviceInfo;
-
- for (WlcStateListener cb : mListenerMap.keySet()) {
- sendCurrentState(cb);
- }
- }
- }
-}
-
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/nfc/java/android/nfc/OemLogItems.aidl
deleted file mode 100644
index 3bcb445fc7d2..000000000000
--- a/nfc/java/android/nfc/OemLogItems.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable OemLogItems; \ No newline at end of file
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
deleted file mode 100644
index 4f3e1999f5d3..000000000000
--- a/nfc/java/android/nfc/OemLogItems.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.time.Instant;
-
-/**
- * A log class for OEMs to get log information of NFC events.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class OemLogItems implements Parcelable {
- /**
- * Used when RF field state is changed.
- */
- public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 0X01;
- /**
- * Used when NFC is toggled. Event should be set to {@link LogEvent#EVENT_ENABLE} or
- * {@link LogEvent#EVENT_DISABLE} if this action is used.
- */
- public static final int LOG_ACTION_NFC_TOGGLE = 0x0201;
- /**
- * Used when sending host routing status.
- */
- public static final int LOG_ACTION_HCE_DATA = 0x0204;
- /**
- * Used when screen state is changed.
- */
- public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 0x0206;
- /**
- * Used when tag is detected.
- */
- public static final int LOG_ACTION_TAG_DETECTED = 0x03;
-
- /**
- * @hide
- */
- @IntDef(prefix = { "LOG_ACTION_" }, value = {
- LOG_ACTION_RF_FIELD_STATE_CHANGED,
- LOG_ACTION_NFC_TOGGLE,
- LOG_ACTION_HCE_DATA,
- LOG_ACTION_SCREEN_STATE_CHANGED,
- LOG_ACTION_TAG_DETECTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface LogAction {}
-
- /**
- * Represents the event is not set.
- */
- public static final int EVENT_UNSET = 0;
- /**
- * Represents nfc enable is called.
- */
- public static final int EVENT_ENABLE = 1;
- /**
- * Represents nfc disable is called.
- */
- public static final int EVENT_DISABLE = 2;
- /** @hide */
- @IntDef(prefix = { "EVENT_" }, value = {
- EVENT_UNSET,
- EVENT_ENABLE,
- EVENT_DISABLE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface LogEvent {}
- private int mAction;
- private int mEvent;
- private int mCallingPid;
- private byte[] mCommandApdus;
- private byte[] mResponseApdus;
- private Instant mRfFieldOnTime;
- private Tag mTag;
-
- /** @hide */
- public OemLogItems(@LogAction int action, @LogEvent int event, int callingPid,
- byte[] commandApdus, byte[] responseApdus, Instant rfFieldOnTime,
- Tag tag) {
- mAction = action;
- mEvent = event;
- mTag = tag;
- mCallingPid = callingPid;
- mCommandApdus = commandApdus;
- mResponseApdus = responseApdus;
- mRfFieldOnTime = rfFieldOnTime;
- }
-
- /**
- * Describe the kinds of special objects contained in this Parcelable
- * instance's marshaled representation. For example, if the object will
- * include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},
- * the return value of this method must include the
- * {@link #CONTENTS_FILE_DESCRIPTOR} bit.
- *
- * @return a bitmask indicating the set of special object types marshaled
- * by this Parcelable object instance.
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * Flatten this object in to a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written.
- * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
- */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mAction);
- dest.writeInt(mEvent);
- dest.writeInt(mCallingPid);
- dest.writeInt(mCommandApdus.length);
- dest.writeByteArray(mCommandApdus);
- dest.writeInt(mResponseApdus.length);
- dest.writeByteArray(mResponseApdus);
- dest.writeBoolean(mRfFieldOnTime != null);
- if (mRfFieldOnTime != null) {
- dest.writeLong(mRfFieldOnTime.getEpochSecond());
- dest.writeInt(mRfFieldOnTime.getNano());
- }
- dest.writeParcelable(mTag, 0);
- }
-
- /** @hide */
- public static class Builder {
- private final OemLogItems mItem;
-
- public Builder(@LogAction int type) {
- mItem = new OemLogItems(type, EVENT_UNSET, 0, new byte[0], new byte[0], null, null);
- }
-
- /** Setter of the log action. */
- public OemLogItems.Builder setAction(@LogAction int action) {
- mItem.mAction = action;
- return this;
- }
-
- /** Setter of the log calling event. */
- public OemLogItems.Builder setCallingEvent(@LogEvent int event) {
- mItem.mEvent = event;
- return this;
- }
-
- /** Setter of the log calling Pid. */
- public OemLogItems.Builder setCallingPid(int pid) {
- mItem.mCallingPid = pid;
- return this;
- }
-
- /** Setter of APDU command. */
- public OemLogItems.Builder setApduCommand(byte[] apdus) {
- mItem.mCommandApdus = apdus;
- return this;
- }
-
- /** Setter of RF field on time. */
- public OemLogItems.Builder setRfFieldOnTime(Instant time) {
- mItem.mRfFieldOnTime = time;
- return this;
- }
-
- /** Setter of APDU response. */
- public OemLogItems.Builder setApduResponse(byte[] apdus) {
- mItem.mResponseApdus = apdus;
- return this;
- }
-
- /** Setter of dispatched tag. */
- public OemLogItems.Builder setTag(Tag tag) {
- mItem.mTag = tag;
- return this;
- }
-
- /** Builds an {@link OemLogItems} instance. */
- public OemLogItems build() {
- return mItem;
- }
- }
-
- /**
- * Gets the action of this log.
- * @return one of {@link LogAction}
- */
- @LogAction
- public int getAction() {
- return mAction;
- }
-
- /**
- * Gets the event of this log. This will be set to {@link LogEvent#EVENT_ENABLE} or
- * {@link LogEvent#EVENT_DISABLE} only when action is set to
- * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
- * @return one of {@link LogEvent}
- */
- @LogEvent
- public int getEvent() {
- return mEvent;
- }
-
- /**
- * Gets the calling Pid of this log. This field will be set only when action is set to
- * {@link LogAction#LOG_ACTION_NFC_TOGGLE}
- * @return calling Pid
- */
- public int getCallingPid() {
- return mCallingPid;
- }
-
- /**
- * Gets the command APDUs of this log. This field will be set only when action is set to
- * {@link LogAction#LOG_ACTION_HCE_DATA}
- * @return a byte array of command APDUs with the same format as
- * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
- */
- @Nullable
- public byte[] getCommandApdu() {
- return mCommandApdus;
- }
-
- /**
- * Gets the response APDUs of this log. This field will be set only when action is set to
- * {@link LogAction#LOG_ACTION_HCE_DATA}
- * @return a byte array of response APDUs with the same format as
- * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}
- */
- @Nullable
- public byte[] getResponseApdu() {
- return mResponseApdus;
- }
-
- /**
- * Gets the RF field event time in this log in millisecond. This field will be set only when
- * action is set to {@link LogAction#LOG_ACTION_RF_FIELD_STATE_CHANGED}
- * @return an {@link Instant} of RF field event time.
- */
- @Nullable
- public Instant getRfFieldEventTimeMillis() {
- return mRfFieldOnTime;
- }
-
- /**
- * Gets the tag of this log. This field will be set only when action is set to
- * {@link LogAction#LOG_ACTION_TAG_DETECTED}
- * @return a detected {@link Tag} in {@link #LOG_ACTION_TAG_DETECTED} case. Return
- * null otherwise.
- */
- @Nullable
- public Tag getTag() {
- return mTag;
- }
-
- private String byteToHex(byte[] bytes) {
- char[] HexArray = "0123456789ABCDEF".toCharArray();
- char[] hexChars = new char[bytes.length * 2];
- for (int j = 0; j < bytes.length; j++) {
- int v = bytes[j] & 0xFF;
- hexChars[j * 2] = HexArray[v >>> 4];
- hexChars[j * 2 + 1] = HexArray[v & 0x0F];
- }
- return new String(hexChars);
- }
-
- @Override
- public String toString() {
- return "[mCommandApdus: "
- + ((mCommandApdus != null) ? byteToHex(mCommandApdus) : "null")
- + "[mResponseApdus: "
- + ((mResponseApdus != null) ? byteToHex(mResponseApdus) : "null")
- + ", mCallingApi= " + mEvent
- + ", mAction= " + mAction
- + ", mCallingPId = " + mCallingPid
- + ", mRfFieldOnTime= " + mRfFieldOnTime;
- }
- private OemLogItems(Parcel in) {
- this.mAction = in.readInt();
- this.mEvent = in.readInt();
- this.mCallingPid = in.readInt();
- this.mCommandApdus = new byte[in.readInt()];
- in.readByteArray(this.mCommandApdus);
- this.mResponseApdus = new byte[in.readInt()];
- in.readByteArray(this.mResponseApdus);
- boolean isRfFieldOnTimeSet = in.readBoolean();
- if (isRfFieldOnTimeSet) {
- this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
- } else {
- this.mRfFieldOnTime = null;
- }
- this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);
- }
-
- public static final @NonNull Parcelable.Creator<OemLogItems> CREATOR =
- new Parcelable.Creator<OemLogItems>() {
- @Override
- public OemLogItems createFromParcel(Parcel in) {
- return new OemLogItems(in);
- }
-
- @Override
- public OemLogItems[] newArray(int size) {
- return new OemLogItems[size];
- }
- };
-
-}
diff --git a/nfc/java/android/nfc/RoutingStatus.java b/nfc/java/android/nfc/RoutingStatus.java
deleted file mode 100644
index 4a1b1f3cecbc..000000000000
--- a/nfc/java/android/nfc/RoutingStatus.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * A class indicating default route, ISO-DEP route and off-host route.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-public class RoutingStatus {
- private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute;
- private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute;
- private final @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute;
-
- RoutingStatus(@CardEmulation.ProtocolAndTechnologyRoute int mDefaultRoute,
- @CardEmulation.ProtocolAndTechnologyRoute int mDefaultIsoDepRoute,
- @CardEmulation.ProtocolAndTechnologyRoute int mDefaultOffHostRoute) {
- this.mDefaultRoute = mDefaultRoute;
- this.mDefaultIsoDepRoute = mDefaultIsoDepRoute;
- this.mDefaultOffHostRoute = mDefaultOffHostRoute;
- }
-
- /**
- * Getter of the default route.
- * @return an integer defined in
- * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @CardEmulation.ProtocolAndTechnologyRoute
- public int getDefaultRoute() {
- return mDefaultRoute;
- }
-
- /**
- * Getter of the default ISO-DEP route.
- * @return an integer defined in
- * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @CardEmulation.ProtocolAndTechnologyRoute
- public int getDefaultIsoDepRoute() {
- return mDefaultIsoDepRoute;
- }
-
- /**
- * Getter of the default off-host route.
- * @return an integer defined in
- * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @CardEmulation.ProtocolAndTechnologyRoute
- public int getDefaultOffHostRoute() {
- return mDefaultOffHostRoute;
- }
-
-}
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
deleted file mode 100644
index be94f9fc117c..000000000000
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * Represents an Application ID (AID) entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableAidEntry extends NfcRoutingTableEntry {
- private final String mValue;
-
- /** @hide */
- public RoutingTableAidEntry(int nfceeId, String value,
- @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
- super(nfceeId, TYPE_AID, routeType);
- this.mValue = value;
- }
-
- /**
- * Gets AID value.
- * @return String of AID
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @NonNull
- public String getAid() {
- return mValue;
- }
-}
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
deleted file mode 100644
index a68d8c167865..000000000000
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a protocol entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableProtocolEntry extends NfcRoutingTableEntry {
- /**
- * Protocol undetermined.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_UNDETERMINED = 0;
- /**
- * T1T Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_T1T = 1;
- /**
- * T2T Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_T2T = 2;
- /**
- * T3T Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_T3T = 3;
- /**
- * ISO-DEP Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_ISO_DEP = 4;
- /**
- * DEP Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_NFC_DEP = 5;
- /**
- * T5T Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_T5T = 6;
- /**
- * NDEF Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_NDEF = 7;
- /**
- * Unsupported Protocol
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int PROTOCOL_UNSUPPORTED = -1;
-
- /**
- *
- * @hide
- */
- @IntDef(prefix = { "PROTOCOL_" }, value = {
- PROTOCOL_UNDETERMINED,
- PROTOCOL_T1T,
- PROTOCOL_T2T,
- PROTOCOL_T3T,
- PROTOCOL_ISO_DEP,
- PROTOCOL_NFC_DEP,
- PROTOCOL_T5T,
- PROTOCOL_NDEF,
- PROTOCOL_UNSUPPORTED
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ProtocolValue {}
-
- private final @ProtocolValue int mValue;
-
- /** @hide */
- public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value,
- @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
- super(nfceeId, TYPE_PROTOCOL, routeType);
- this.mValue = value;
- }
-
- /**
- * Gets Protocol value.
- * @return Protocol defined in {@link ProtocolValue}
- */
- @ProtocolValue
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public int getProtocol() {
- return mValue;
- }
-
- /** @hide */
- @ProtocolValue
- public static int protocolStringToInt(String protocolString) {
- return switch (protocolString) {
- case "PROTOCOL_T1T" -> PROTOCOL_T1T;
- case "PROTOCOL_T2T" -> PROTOCOL_T2T;
- case "PROTOCOL_T3T" -> PROTOCOL_T3T;
- case "PROTOCOL_ISO_DEP" -> PROTOCOL_ISO_DEP;
- case "PROTOCOL_NFC_DEP" -> PROTOCOL_NFC_DEP;
- case "PROTOCOL_T5T" -> PROTOCOL_T5T;
- case "PROTOCOL_NDEF" -> PROTOCOL_NDEF;
- case "PROTOCOL_UNDETERMINED" -> PROTOCOL_UNDETERMINED;
- default -> PROTOCOL_UNSUPPORTED;
- };
- }
-}
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
deleted file mode 100644
index 06cc0a5f26f1..000000000000
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-/**
- * 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)
-@SystemApi
-public class RoutingTableSystemCodeEntry extends NfcRoutingTableEntry {
- private final byte[] mValue;
-
- /** @hide */
- public RoutingTableSystemCodeEntry(int nfceeId, byte[] value,
- @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
- super(nfceeId, TYPE_SYSTEM_CODE, routeType);
- this.mValue = value;
- }
-
- /**
- * Gets system code value.
- * @return Byte array of system code
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- @NonNull
- public byte[] getSystemCode() {
- return mValue;
- }
-}
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
deleted file mode 100644
index 86239ce7a6b2..000000000000
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.SystemApi;
-import android.nfc.cardemulation.CardEmulation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Represents a technology entry in current routing table.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
- /**
- * 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 which is based on ISO/IEC 14443-3 standard.
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int TECHNOLOGY_B = 1;
- /**
- * 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.
- * <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;
- /**
- * Unsupported technology
- */
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public static final int TECHNOLOGY_UNSUPPORTED = -1;
-
- /**
- *
- * @hide
- */
- @IntDef(prefix = { "TECHNOLOGY_" }, value = {
- TECHNOLOGY_A,
- TECHNOLOGY_B,
- TECHNOLOGY_F,
- TECHNOLOGY_V,
- TECHNOLOGY_UNSUPPORTED
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TechnologyValue{}
-
- private final @TechnologyValue int mValue;
-
- /** @hide */
- public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value,
- @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
- super(nfceeId, TYPE_TECHNOLOGY, routeType);
- this.mValue = value;
- }
-
- /**
- * Gets technology value.
- * @return technology value
- */
- @TechnologyValue
- @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
- public int getTechnology() {
- return mValue;
- }
-
- /** @hide */
- @TechnologyValue
- public static int techStringToInt(String tech) {
- return switch (tech) {
- case "TECHNOLOGY_A" -> TECHNOLOGY_A;
- case "TECHNOLOGY_B" -> TECHNOLOGY_B;
- case "TECHNOLOGY_F" -> TECHNOLOGY_F;
- case "TECHNOLOGY_V" -> TECHNOLOGY_V;
- default -> TECHNOLOGY_UNSUPPORTED;
- };
- }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
deleted file mode 100644
index 06d02c54eb2e..000000000000
--- a/nfc/java/android/nfc/T4tNdefNfcee.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.annotation.WorkerThread;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) operations.
- * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
- * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
- * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfcee {
- private static final String TAG = "NdefNfcee";
- static T4tNdefNfcee sNdefNfcee;
-
- private T4tNdefNfcee() {
- }
-
- /**
- * Helper to get an instance of this class.
- *
- * @return
- * @hide
- */
- @NonNull
- public static T4tNdefNfcee getInstance() {
- if (sNdefNfcee == null) {
- sNdefNfcee = new T4tNdefNfcee();
- }
- return sNdefNfcee;
- }
-
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data is successful.
- */
- public static final int WRITE_DATA_SUCCESS = 0;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to unknown reasons.
- */
- public static final int WRITE_DATA_ERROR_INTERNAL = -1;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to ongoing rf activity.
- */
- public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to Nfc off.
- */
- public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to invalid file id.
- */
- public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to invalid length.
- */
- public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to core connection create failure.
- */
- public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
- /**
- * Return flag for {@link #writeData(int, byte[])}.
- * It indicates write data fail due to empty payload.
- */
- public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
- /**
- * Returns flag for {@link #writeData(int, byte[])}.
- * It idicates write data fail due to invalid ndef format.
- */
- public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
-
- /**
- * Possible return values for {@link #writeData(int, byte[])}.
- *
- * @hide
- */
- @IntDef(prefix = { "WRITE_DATA_" }, value = {
- WRITE_DATA_SUCCESS,
- WRITE_DATA_ERROR_INTERNAL,
- WRITE_DATA_ERROR_RF_ACTIVATED,
- WRITE_DATA_ERROR_NFC_NOT_ON,
- WRITE_DATA_ERROR_INVALID_FILE_ID,
- WRITE_DATA_ERROR_INVALID_LENGTH,
- WRITE_DATA_ERROR_CONNECTION_FAILED,
- WRITE_DATA_ERROR_EMPTY_PAYLOAD,
- WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WriteDataStatus{}
-
- /**
- * This API performs writes of T4T data to NFCEE.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread.</p>
- *
- * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
- * Section 4.2 File Identifiers and Access Conditions
- * for more information) to which to write.
- * @param data This should be valid Ndef Message format.
- * Refer to Nfc forum NDEF specification NDEF Message section
- * @return status of the operation.
- * @hide
- */
- @SystemApi
- @WorkerThread
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
- @NonNull byte[] data) {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
- }
-
- /**
- * This API performs reading of T4T content of Nfcee.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread.</p>
- *
- * @param fileId File Id (Refer
- * Section 4.2 File Identifiers and Access Conditions
- * for more information) from which to read.
- * @return - Returns Ndef message if success
- * Refer to Nfc forum NDEF specification NDEF Message section
- * @throws IllegalStateException if read fails because the fileId is invalid.
- * @hide
- */
- @SystemApi
- @WorkerThread
- @NonNull
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.readData(fileId), null);
- }
-
- /**
- * Return flag for {@link #clearNdefData()}.
- * It indicates clear data is successful.
- */
- public static final int CLEAR_DATA_SUCCESS = 1;
- /**
- * Return flag for {@link #clearNdefData()}.
- * It indicates clear data failed due to internal error while processing the clear.
- */
- public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
-
- /**
- * Possible return values for {@link #clearNdefData()}.
- *
- * @hide
- */
- @IntDef(prefix = { "CLEAR_DATA_" }, value = {
- CLEAR_DATA_SUCCESS,
- CLEAR_DATA_FAILED_INTERNAL,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ClearDataStatus{}
-
- /**
- * This API will set all the T4T NDEF NFCEE data to zero.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread.
- *
- * <p>This API can be called regardless of NDEF file lock state.
- * </p>
- * @return status of the operation
- *
- * @hide
- */
- @SystemApi
- @WorkerThread
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public @ClearDataStatus int clearData() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
- }
-
- /**
- * Returns whether NDEF NFCEE operation is ongoing or not.
- *
- * @return true if NDEF NFCEE operation is ongoing, else false.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean isOperationOngoing() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
- }
-
- /**
- * This Api is to check the status of NDEF NFCEE emulation feature is
- * supported or not.
- *
- * @return true if NDEF NFCEE emulation feature is supported, else false.
- * @hide
- */
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public boolean isSupported() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
- }
-
- /**
- * This API performs reading of T4T NDEF NFCEE CC file content.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- *
- * @return Returns CC file content if success or null if failed to read.
- * @hide
- */
- @SystemApi
- @WorkerThread
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @Nullable
- public T4tNdefNfceeCcFileInfo readCcfile() {
- return NfcAdapter.callServiceReturn(() ->
- NfcAdapter.sNdefNfceeService.readCcfile(), null);
- }
-}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
deleted file mode 100644
index 5fca0529124e..000000000000
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
- * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
- * The CC file stores metadata about the T4T tag being emulated.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- * @hide
- */
-@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
-@SystemApi
-public final class T4tNdefNfceeCcFileInfo implements Parcelable {
- /**
- * Indicates the size of this capability container (called “CC File”)<p>
- */
- private int mCcLength;
- /**
- * Indicates the mapping specification version<p>
- */
- private int mVersion;
- /**
- * Indicates the max data size by a single ReadBinary<p>
- */
- private int mMaxReadLength;
- /**
- * Indicates the max data size by a single UpdateBinary<p>
- */
- private int mMaxWriteLength;
- /**
- * Indicates the NDEF File Identifier<p>
- */
- private int mFileId;
- /**
- * Indicates the maximum Max NDEF file size<p>
- */
- private int mMaxSize;
- /**
- * Indicates the read access condition<p>
- */
- private int mReadAccess;
- /**
- * Indicates the write access condition<p>
- */
- private int mWriteAccess;
-
- /**
- * Constructor to be used by NFC service and internal classes.
- * @hide
- */
- public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
- int ndefFileId, int ndefMaxSize,
- int ndefReadAccess, int ndefWriteAccess) {
- mCcLength = cclen;
- mVersion = version;
- mMaxWriteLength = maxLc;
- mMaxReadLength = maxLe;
- mFileId = ndefFileId;
- mMaxSize = ndefMaxSize;
- mReadAccess = ndefReadAccess;
- mWriteAccess = ndefWriteAccess;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
-
- dest.writeInt(mCcLength);
- dest.writeInt(mVersion);
- dest.writeInt(mMaxWriteLength);
- dest.writeInt(mMaxReadLength);
- dest.writeInt(mFileId);
- dest.writeInt(mMaxSize);
- dest.writeInt(mReadAccess);
- dest.writeInt(mWriteAccess);
- }
-
- /**
- * Indicates the size of this capability container (called “CC File”).
- *
- * @return length of the CC file.
- */
- @IntRange(from = 0xf, to = 0x7fff)
- public int getCcFileLength() {
- return mCcLength;
- }
-
- /**
- * T4T tag mapping version 2.0.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- */
- public static final int VERSION_2_0 = 0x20;
- /**
- * T4T tag mapping version 2.0.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
- */
- public static final int VERSION_3_0 = 0x30;
-
- /**
- * Possible return values for {@link #getVersion()}.
- * @hide
- */
- @IntDef(prefix = { "VERSION_" }, value = {
- VERSION_2_0,
- VERSION_3_0,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Version{}
-
- /**
- * Indicates the mapping version of the T4T tag supported.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
- *
- * @return version of the specification
- */
- @Version
- public int getVersion() {
- return mVersion;
- }
-
- /**
- * Indicates the max data size that can be read by a single invocation of
- * {@link T4tNdefNfcee#readData(int)}.
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
- * @return max size of read (in bytes).
- */
- @IntRange(from = 0xf, to = 0xffff)
- public int getMaxReadLength() {
- return mMaxReadLength;
- }
-
- /**
- * Indicates the max data size that can be written by a single invocation of
- * {@link T4tNdefNfcee#writeData(int, byte[])}
- *
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
- * @return max size of write (in bytes).
- */
- @IntRange(from = 0xd, to = 0xffff)
- public int getMaxWriteLength() {
- return mMaxWriteLength;
- }
-
- /**
- * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
- * {@link T4tNdefNfcee#writeData(int, byte[])}
- *
- * @return FileId of the data stored or -1 if no data is present.
- */
- @IntRange(from = -1, to = 65535)
- public int getFileId() {
- return mFileId;
- }
-
- /**
- * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
- *
- * @return max size of the contents.
- */
- @IntRange(from = 0x5, to = 0x7fff)
- public int getMaxSize() {
- return mMaxSize;
- }
-
- /**
- * T4T tag read access granted without any security.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
- /**
- * T4T tag read access granted with limited proprietary access only.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
-
- /**
- * Possible return values for {@link #getVersion()}.
- * @hide
- */
- @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
- READ_ACCESS_GRANTED_RESTRICTED,
- READ_ACCESS_GRANTED_UNRESTRICTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ReadAccess {}
-
- /**
- * Indicates the read access condition.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @return read access restriction
- */
- @ReadAccess
- public int getReadAccess() {
- return mReadAccess;
- }
-
- /**
- * T4T tag write access granted without any security.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
- /**
- * T4T tag write access granted with limited proprietary access only.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
- /**
- * T4T tag write access not granted.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- */
- public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
-
- /**
- * Possible return values for {@link #getVersion()}.
- * @hide
- */
- @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
- WRITE_ACCESS_GRANTED_RESTRICTED,
- WRITE_ACCESS_GRANTED_UNRESTRICTED,
- WRITE_ACCESS_NOT_GRANTED,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WriteAccess {}
-
- /**
- * Indicates the write access condition.
- * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
- * @return write access restriction
- */
- @WriteAccess
- public int getWriteAccess() {
- return mWriteAccess;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
- new Parcelable.Creator<>() {
- @Override
- public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
-
- // NdefNfceeCcFileInfo fields
- int cclen = in.readInt();
- int version = in.readInt();
- int maxLe = in.readInt();
- int maxLc = in.readInt();
- int ndefFileId = in.readInt();
- int ndefMaxSize = in.readInt();
- int ndefReadAccess = in.readInt();
- int ndefWriteAccess = in.readInt();
-
- return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
- ndefFileId, ndefMaxSize,
- ndefReadAccess, ndefWriteAccess);
- }
-
- @Override
- public T4tNdefNfceeCcFileInfo[] newArray(int size) {
- return new T4tNdefNfceeCcFileInfo[size];
- }
- };
-}
diff --git a/nfc/java/android/nfc/Tag.aidl b/nfc/java/android/nfc/Tag.aidl
deleted file mode 100644
index 312261ebe76d..000000000000
--- a/nfc/java/android/nfc/Tag.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable Tag; \ No newline at end of file
diff --git a/nfc/java/android/nfc/Tag.java b/nfc/java/android/nfc/Tag.java
deleted file mode 100644
index 500038f14d9d..000000000000
--- a/nfc/java/android/nfc/Tag.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.nfc.tech.IsoDep;
-import android.nfc.tech.MifareClassic;
-import android.nfc.tech.MifareUltralight;
-import android.nfc.tech.Ndef;
-import android.nfc.tech.NdefFormatable;
-import android.nfc.tech.NfcA;
-import android.nfc.tech.NfcB;
-import android.nfc.tech.NfcBarcode;
-import android.nfc.tech.NfcF;
-import android.nfc.tech.NfcV;
-import android.nfc.tech.TagTechnology;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-
-/**
- * Represents an NFC tag that has been discovered.
- * <p>
- * {@link Tag} is an immutable object that represents the state of a NFC tag at
- * the time of discovery. It can be used as a handle to {@link TagTechnology} classes
- * to perform advanced operations, or directly queried for its ID via {@link #getId} and the
- * set of technologies it contains via {@link #getTechList}. Arrays passed to and
- * returned by this class are <em>not</em> cloned, so be careful not to modify them.
- * <p>
- * A new tag object is created every time a tag is discovered (comes into range), even
- * if it is the same physical tag. If a tag is removed and then returned into range, then
- * only the most recent tag object can be successfully used to create a {@link TagTechnology}.
- *
- * <h3>Tag Dispatch</h3>
- * When a tag is discovered, a {@link Tag} object is created and passed to a
- * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an
- * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used
- * to select the
- * most appropriate activity to handle the tag. The Android OS executes each stage in order,
- * and completes dispatch as soon as a single matching activity is found. If there are multiple
- * matching activities found at any one stage then the Android activity chooser dialog is shown
- * to allow the user to select the activity to receive the tag.
- *
- * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching
- * a tag to the correct activity without showing the user an activity chooser dialog.
- * This is important for NFC interactions because they are very transient -- if a user has to
- * move the Android device to choose an application then the connection will likely be broken.
- *
- * <h4>1. Foreground activity dispatch</h4>
- * A foreground activity that has called
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is
- * given priority. See the documentation on
- * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for
- * its usage.
- * <h4>2. NDEF data dispatch</h4>
- * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first
- * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI
- * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME
- * type is put in the intent's type field. This allows activities to register to be launched only
- * when data they know how to handle is present on a tag. This is the preferred method of handling
- * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a
- * specific tag technology.
- * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain
- * NDEF data, or if no activity is registered
- * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch
- * moves to stage 3.
- * <h4>3. Tag Technology dispatch</h4>
- * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to
- * dispatch the tag to an activity that can handle the technologies present on the tag.
- * Technologies are defined as sub-classes of {@link TagTechnology}, see the package
- * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or
- * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail.
- * <h4>4. Fall-back dispatch</h4>
- * If no activity has been matched then {@link Context#startActivity} is called with
- * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism.
- * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}.
- *
- * <h3>NFC Tag Background</h3>
- * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while
- * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or
- * even embedded in a more sophisticated device.
- * <p>
- * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics,
- * and contain some one time
- * programmable areas to make read-only. More complex tags offer math operations
- * and per-sector access control and authentication. The most sophisticated tags
- * contain operating environments allowing complex interactions with the
- * code executing on the tag. Use {@link TagTechnology} classes to access a broad
- * range of capabilities available in NFC tags.
- * <p>
- */
-public final class Tag implements Parcelable {
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- final byte[] mId;
- final int[] mTechList;
- final String[] mTechStringList;
- final Bundle[] mTechExtras;
- final int mServiceHandle; // for use by NFC service, 0 indicates a mock
- final long mCookie; // for accessibility checking
- final INfcTag mTagService; // interface to NFC service, will be null if mock tag
-
- int mConnectedTechnology;
-
- /**
- * Hidden constructor to be used by NFC service and internal classes.
- * @hide
- */
- public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
- long cookie, INfcTag tagService) {
- if (techList == null) {
- throw new IllegalArgumentException("rawTargets cannot be null");
- }
- mId = id;
- mTechList = Arrays.copyOf(techList, techList.length);
- mTechStringList = generateTechStringList(techList);
- // Ensure mTechExtras is as long as mTechList
- mTechExtras = Arrays.copyOf(techListExtras, techList.length);
- mServiceHandle = serviceHandle;
- mCookie = cookie;
- mTagService = tagService;
- mConnectedTechnology = -1;
-
- if (tagService == null) {
- return;
- }
- }
-
- /**
- * Construct a mock Tag.
- * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail
- * with {@link IllegalArgumentException} since it does not represent a physical Tag.
- * <p>This constructor might be useful for mock testing.
- * @param id The tag identifier, can be null
- * @param techList must not be null
- * @return freshly constructed tag
- * @hide
- */
- public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras,
- long cookie) {
- // set serviceHandle to 0 and tagService to null to indicate mock tag
- return new Tag(id, techList, techListExtras, 0, cookie, null);
- }
-
- private String[] generateTechStringList(int[] techList) {
- final int size = techList.length;
- String[] strings = new String[size];
- for (int i = 0; i < size; i++) {
- switch (techList[i]) {
- case TagTechnology.ISO_DEP:
- strings[i] = IsoDep.class.getName();
- break;
- case TagTechnology.MIFARE_CLASSIC:
- strings[i] = MifareClassic.class.getName();
- break;
- case TagTechnology.MIFARE_ULTRALIGHT:
- strings[i] = MifareUltralight.class.getName();
- break;
- case TagTechnology.NDEF:
- strings[i] = Ndef.class.getName();
- break;
- case TagTechnology.NDEF_FORMATABLE:
- strings[i] = NdefFormatable.class.getName();
- break;
- case TagTechnology.NFC_A:
- strings[i] = NfcA.class.getName();
- break;
- case TagTechnology.NFC_B:
- strings[i] = NfcB.class.getName();
- break;
- case TagTechnology.NFC_F:
- strings[i] = NfcF.class.getName();
- break;
- case TagTechnology.NFC_V:
- strings[i] = NfcV.class.getName();
- break;
- case TagTechnology.NFC_BARCODE:
- strings[i] = NfcBarcode.class.getName();
- break;
- default:
- throw new IllegalArgumentException("Unknown tech type " + techList[i]);
- }
- }
- return strings;
- }
-
- static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException {
- if (techStringList == null) {
- throw new IllegalArgumentException("List cannot be null");
- }
- int[] techIntList = new int[techStringList.length];
- HashMap<String, Integer> stringToCodeMap = getTechStringToCodeMap();
- for (int i = 0; i < techStringList.length; i++) {
- Integer code = stringToCodeMap.get(techStringList[i]);
-
- if (code == null) {
- throw new IllegalArgumentException("Unknown tech type " + techStringList[i]);
- }
-
- techIntList[i] = code.intValue();
- }
- return techIntList;
- }
-
- private static HashMap<String, Integer> getTechStringToCodeMap() {
- HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>();
-
- techStringToCodeMap.put(IsoDep.class.getName(), TagTechnology.ISO_DEP);
- techStringToCodeMap.put(MifareClassic.class.getName(), TagTechnology.MIFARE_CLASSIC);
- techStringToCodeMap.put(MifareUltralight.class.getName(), TagTechnology.MIFARE_ULTRALIGHT);
- techStringToCodeMap.put(Ndef.class.getName(), TagTechnology.NDEF);
- techStringToCodeMap.put(NdefFormatable.class.getName(), TagTechnology.NDEF_FORMATABLE);
- techStringToCodeMap.put(NfcA.class.getName(), TagTechnology.NFC_A);
- techStringToCodeMap.put(NfcB.class.getName(), TagTechnology.NFC_B);
- techStringToCodeMap.put(NfcF.class.getName(), TagTechnology.NFC_F);
- techStringToCodeMap.put(NfcV.class.getName(), TagTechnology.NFC_V);
- techStringToCodeMap.put(NfcBarcode.class.getName(), TagTechnology.NFC_BARCODE);
-
- return techStringToCodeMap;
- }
-
- /**
- * For use by NfcService only.
- * @hide
- */
- @UnsupportedAppUsage
- public int getServiceHandle() {
- return mServiceHandle;
- }
-
- /**
- * For use by NfcService only.
- * @hide
- */
- public int[] getTechCodeList() {
- return mTechList;
- }
-
- /**
- * Get the Tag Identifier (if it has one).
- * <p>The tag identifier is a low level serial number, used for anti-collision
- * and identification.
- * <p> Most tags have a stable unique identifier
- * (UID), but some tags will generate a random ID every time they are discovered
- * (RID), and there are some tags with no ID at all (the byte array will be zero-sized).
- * <p> The size and format of an ID is specific to the RF technology used by the tag.
- * <p> This function retrieves the ID as determined at discovery time, and does not
- * perform any further RF communication or block.
- * @return ID as byte array, never null
- */
- public byte[] getId() {
- return mId;
- }
-
- /**
- * Get the technologies available in this tag, as fully qualified class names.
- * <p>
- * A technology is an implementation of the {@link TagTechnology} interface,
- * and can be instantiated by calling the static <code>get(Tag)</code>
- * method on the implementation with this Tag. The {@link TagTechnology}
- * object can then be used to perform advanced, technology-specific operations on a tag.
- * <p>
- * Android defines a mandatory set of technologies that must be correctly
- * enumerated by all Android NFC devices, and an optional
- * set of proprietary technologies.
- * See {@link TagTechnology} for more details.
- * <p>
- * The ordering of the returned array is undefined and should not be relied upon.
- * @return an array of fully-qualified {@link TagTechnology} class-names.
- */
- public String[] getTechList() {
- return mTechStringList;
- }
-
- /**
- * Rediscover the technologies available on this tag.
- * <p>
- * The technologies that are available on a tag may change due to
- * operations being performed on a tag. For example, formatting a
- * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover}
- * method reenumerates the available technologies on the tag
- * and returns a new {@link Tag} object containing these technologies.
- * <p>
- * You may not be connected to any of this {@link Tag}'s technologies
- * when calling this method.
- * This method guarantees that you will be returned the same Tag
- * if it is still in the field.
- * <p>May cause RF activity and may block. Must not be called
- * from the main application thread. A blocked call will be canceled with
- * {@link IOException} by calling {@link #close} from another thread.
- * <p>Does not remove power from the RF field, so a tag having a random
- * ID should not change its ID.
- * @return the rediscovered tag object.
- * @throws IOException if the tag cannot be rediscovered
- * @hide
- */
- // TODO See if we need TagLostException
- // TODO Unhide for ICS
- // TODO Update documentation to make sure it matches with the final
- // implementation.
- public Tag rediscover() throws IOException {
- if (getConnectedTechnology() != -1) {
- throw new IllegalStateException("Close connection to the technology first!");
- }
-
- if (mTagService == null) {
- throw new IOException("Mock tags don't support this operation.");
- }
- try {
- Tag newTag = mTagService.rediscover(getServiceHandle());
- if (newTag != null) {
- return newTag;
- } else {
- throw new IOException("Failed to rediscover tag");
- }
- } catch (RemoteException e) {
- throw new IOException("NFC service dead");
- }
- }
-
-
- /** @hide */
- public boolean hasTech(int techType) {
- for (int tech : mTechList) {
- if (tech == techType) return true;
- }
- return false;
- }
-
- /** @hide */
- public Bundle getTechExtras(int tech) {
- int pos = -1;
- for (int idx = 0; idx < mTechList.length; idx++) {
- if (mTechList[idx] == tech) {
- pos = idx;
- break;
- }
- }
- if (pos < 0) {
- return null;
- }
-
- return mTechExtras[pos];
- }
-
- /** @hide */
- @UnsupportedAppUsage
- public INfcTag getTagService() {
- if (mTagService == null) {
- return null;
- }
-
- try {
- if (!mTagService.isTagUpToDate(mCookie)) {
- String id_str = "";
- for (int i = 0; i < mId.length; i++) {
- id_str = id_str + String.format("%02X ", mId[i]);
- }
- String msg = "Permission Denial: Tag ( ID: " + id_str + ") is out of date";
- throw new SecurityException(msg);
- }
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- }
- return mTagService;
- }
-
- /**
- * Human-readable description of the tag, for debugging.
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("TAG: Tech [");
- String[] techList = getTechList();
- int length = techList.length;
- for (int i = 0; i < length; i++) {
- sb.append(techList[i]);
- if (i < length - 1) {
- sb.append(", ");
- }
- }
- sb.append("]");
- return sb.toString();
- }
-
- /*package*/ static byte[] readBytesWithNull(Parcel in) {
- int len = in.readInt();
- byte[] result = null;
- if (len >= 0) {
- result = new byte[len];
- in.readByteArray(result);
- }
- return result;
- }
-
- /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
- if (b == null) {
- out.writeInt(-1);
- return;
- }
- out.writeInt(b.length);
- out.writeByteArray(b);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- // Null mTagService means this is a mock tag
- int isMock = (mTagService == null)?1:0;
-
- writeBytesWithNull(dest, mId);
- dest.writeInt(mTechList.length);
- dest.writeIntArray(mTechList);
- dest.writeTypedArray(mTechExtras, 0);
- dest.writeInt(mServiceHandle);
- dest.writeLong(mCookie);
- dest.writeInt(isMock);
- if (isMock == 0) {
- dest.writeStrongBinder(mTagService.asBinder());
- }
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<Tag> CREATOR =
- new Parcelable.Creator<Tag>() {
- @Override
- public Tag createFromParcel(Parcel in) {
- INfcTag tagService;
-
- // Tag fields
- byte[] id = Tag.readBytesWithNull(in);
- int[] techList = new int[in.readInt()];
- in.readIntArray(techList);
- Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
- int serviceHandle = in.readInt();
- long cookie = in.readLong();
- int isMock = in.readInt();
- if (isMock == 0) {
- tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
- }
- else {
- tagService = null;
- }
-
- return new Tag(id, techList, techExtras, serviceHandle, cookie, tagService);
- }
-
- @Override
- public Tag[] newArray(int size) {
- return new Tag[size];
- }
- };
-
- /**
- * For internal use only.
- *
- * @hide
- */
- public synchronized boolean setConnectedTechnology(int technology) {
- if (mConnectedTechnology != -1) {
- return false;
- }
- mConnectedTechnology = technology;
- return true;
- }
-
- /**
- * For internal use only.
- *
- * @hide
- */
- public int getConnectedTechnology() {
- return mConnectedTechnology;
- }
-
- /**
- * For internal use only.
- *
- * @hide
- */
- public void setTechnologyDisconnected() {
- mConnectedTechnology = -1;
- }
-}
diff --git a/nfc/java/android/nfc/TagLostException.java b/nfc/java/android/nfc/TagLostException.java
deleted file mode 100644
index 1981d7c0c6e0..000000000000
--- a/nfc/java/android/nfc/TagLostException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import java.io.IOException;
-
-public class TagLostException extends IOException {
- public TagLostException() {
- super();
- }
-
- public TagLostException(String message) {
- super(message);
- }
-}
diff --git a/nfc/java/android/nfc/TechListParcel.aidl b/nfc/java/android/nfc/TechListParcel.aidl
deleted file mode 100644
index 92e646f220f0..000000000000
--- a/nfc/java/android/nfc/TechListParcel.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable TechListParcel; \ No newline at end of file
diff --git a/nfc/java/android/nfc/TechListParcel.java b/nfc/java/android/nfc/TechListParcel.java
deleted file mode 100644
index 9f01559bd344..000000000000
--- a/nfc/java/android/nfc/TechListParcel.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public class TechListParcel implements Parcelable {
-
- private String[][] mTechLists;
-
- public TechListParcel(String[]... strings) {
- mTechLists = strings;
- }
-
- public String[][] getTechLists() {
- return mTechLists;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- int count = mTechLists.length;
- dest.writeInt(count);
- for (int i = 0; i < count; i++) {
- String[] techList = mTechLists[i];
- dest.writeStringArray(techList);
- }
- }
-
- public static final @android.annotation.NonNull Creator<TechListParcel> CREATOR = new Creator<TechListParcel>() {
- @Override
- public TechListParcel createFromParcel(Parcel source) {
- int count = source.readInt();
- String[][] techLists = new String[count][];
- for (int i = 0; i < count; i++) {
- techLists[i] = source.createStringArray();
- }
- return new TechListParcel(techLists);
- }
-
- @Override
- public TechListParcel[] newArray(int size) {
- return new TechListParcel[size];
- }
- };
-}
diff --git a/nfc/java/android/nfc/TransceiveResult.aidl b/nfc/java/android/nfc/TransceiveResult.aidl
deleted file mode 100644
index 98f92ee03eef..000000000000
--- a/nfc/java/android/nfc/TransceiveResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable TransceiveResult;
diff --git a/nfc/java/android/nfc/TransceiveResult.java b/nfc/java/android/nfc/TransceiveResult.java
deleted file mode 100644
index 7992094e6ba1..000000000000
--- a/nfc/java/android/nfc/TransceiveResult.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.IOException;
-
-/**
- * Class used to pipe transceive result from the NFC service.
- *
- * @hide
- */
-public final class TransceiveResult implements Parcelable {
- public static final int RESULT_SUCCESS = 0;
- public static final int RESULT_FAILURE = 1;
- public static final int RESULT_TAGLOST = 2;
- public static final int RESULT_EXCEEDED_LENGTH = 3;
-
- final int mResult;
- final byte[] mResponseData;
-
- public TransceiveResult(final int result, final byte[] data) {
- mResult = result;
- mResponseData = data;
- }
-
- public byte[] getResponseOrThrow() throws IOException {
- switch (mResult) {
- case RESULT_SUCCESS:
- return mResponseData;
- case RESULT_TAGLOST:
- throw new TagLostException("Tag was lost.");
- case RESULT_EXCEEDED_LENGTH:
- throw new IOException("Transceive length exceeds supported maximum");
- default:
- throw new IOException("Transceive failed");
- }
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mResult);
- if (mResult == RESULT_SUCCESS) {
- dest.writeInt(mResponseData.length);
- dest.writeByteArray(mResponseData);
- }
- }
-
- public static final @android.annotation.NonNull Parcelable.Creator<TransceiveResult> CREATOR =
- new Parcelable.Creator<TransceiveResult>() {
- @Override
- public TransceiveResult createFromParcel(Parcel in) {
- int result = in.readInt();
- byte[] responseData;
-
- if (result == RESULT_SUCCESS) {
- int responseLength = in.readInt();
- responseData = new byte[responseLength];
- in.readByteArray(responseData);
- } else {
- responseData = null;
- }
- return new TransceiveResult(result, responseData);
- }
-
- @Override
- public TransceiveResult[] newArray(int size) {
- return new TransceiveResult[size];
- }
- };
-
-}
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl b/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
deleted file mode 100644
index 7f2ca545007b..000000000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable WlcListenerDeviceInfo;
diff --git a/nfc/java/android/nfc/WlcListenerDeviceInfo.java b/nfc/java/android/nfc/WlcListenerDeviceInfo.java
deleted file mode 100644
index 45315f812250..000000000000
--- a/nfc/java/android/nfc/WlcListenerDeviceInfo.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.annotation.FlaggedApi;
-import android.annotation.FloatRange;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains information of the nfc wireless charging listener device information.
- */
-@FlaggedApi(Flags.FLAG_ENABLE_NFC_CHARGING)
-public final class WlcListenerDeviceInfo implements Parcelable {
- /**
- * Device is currently not connected with any WlcListenerDevice.
- */
- public static final int STATE_DISCONNECTED = 1;
-
- /**
- * Device is currently connected with a WlcListenerDevice and is charging it.
- */
- public static final int STATE_CONNECTED_CHARGING = 2;
-
- /**
- * Device is currently connected with a WlcListenerDevice without charging it.
- */
- public static final int STATE_CONNECTED_DISCHARGING = 3;
-
- /**
- * Possible states from {@link #getState}.
- * @hide
- */
- @IntDef(prefix = { "STATE_" }, value = {
- STATE_DISCONNECTED,
- STATE_CONNECTED_CHARGING,
- STATE_CONNECTED_DISCHARGING
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WlcListenerState{}
-
- private int mProductId;
- private double mTemperature;
- private double mBatteryLevel;
- private int mState;
-
- /**
- * Create a new object containing wlc listener information.
- *
- * @param productId code for the device vendor
- * @param temperature current temperature
- * @param batteryLevel current battery level
- * @param state current state
- */
- public WlcListenerDeviceInfo(int productId, double temperature, double batteryLevel,
- @WlcListenerState int state) {
- this.mProductId = productId;
- this.mTemperature = temperature;
- this.mBatteryLevel = batteryLevel;
- this.mState = state;
- }
-
- /**
- * ProductId of the WLC listener device.
- * @return integer that is converted from USI Stylus VendorID[11:0].
- */
- public int getProductId() {
- return mProductId;
- }
-
- /**
- * Temperature of the WLC listener device.
- * @return the value represents the temperature in °C.
- */
- public double getTemperature() {
- return mTemperature;
- }
-
- /**
- * BatteryLevel of the WLC listener device.
- * @return battery level in percentage [0-100]
- */
- public @FloatRange(from = 0.0, to = 100.0) double getBatteryLevel() {
- return mBatteryLevel;
- }
-
- /**
- * State of the WLC listener device.
- */
- public @WlcListenerState int getState() {
- return mState;
- }
-
- private WlcListenerDeviceInfo(Parcel in) {
- this.mProductId = in.readInt();
- this.mTemperature = in.readDouble();
- this.mBatteryLevel = in.readDouble();
- this.mState = in.readInt();
- }
-
- public static final @NonNull Parcelable.Creator<WlcListenerDeviceInfo> CREATOR =
- new Parcelable.Creator<WlcListenerDeviceInfo>() {
- @Override
- public WlcListenerDeviceInfo createFromParcel(Parcel in) {
- return new WlcListenerDeviceInfo(in);
- }
-
- @Override
- public WlcListenerDeviceInfo[] newArray(int size) {
- return new WlcListenerDeviceInfo[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mProductId);
- dest.writeDouble(mTemperature);
- dest.writeDouble(mBatteryLevel);
- dest.writeInt(mState);
- }
-}
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
deleted file mode 100644
index e0bc15fe6e94..000000000000
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ /dev/null
@@ -1,1494 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.Manifest;
-import android.annotation.CallbackExecutor;
-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;
-import android.annotation.SystemApi;
-import android.annotation.UserHandleAware;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.role.RoleManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.ComponentNameAndUser;
-import android.nfc.Constants;
-import android.nfc.Flags;
-import android.nfc.INfcCardEmulation;
-import android.nfc.INfcEventListener;
-import android.nfc.NfcAdapter;
-import android.os.Build;
-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;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.HexFormat;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.regex.Pattern;
-
-/**
- * This class can be used to query the state of
- * NFC card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public final class CardEmulation {
- private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
- private static final Pattern PLPF_PATTERN = Pattern.compile("[0-9A-Fa-f,\\?,\\*\\.]*");
-
- static final String TAG = "CardEmulation";
-
- /**
- * Activity action: ask the user to change the default
- * card emulation service for a certain category. This will
- * show a dialog that asks the user whether they want to
- * replace the current default service with the service
- * identified with the ComponentName specified in
- * {@link #EXTRA_SERVICE_COMPONENT}, for the category
- * specified in {@link #EXTRA_CATEGORY}. There is an optional
- * extra field using {@link Intent#EXTRA_USER} to specify
- * the {@link UserHandle} of the user that owns the app.
- *
- * @deprecated Please use {@link android.app.role.RoleManager#createRequestRoleIntent(String)}
- * with {@link android.app.role.RoleManager#ROLE_WALLET} parameter
- * and {@link Activity#startActivityForResult(Intent, int)} instead.
- */
- @Deprecated
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CHANGE_DEFAULT =
- "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
-
- /**
- * The category extra for {@link #ACTION_CHANGE_DEFAULT}.
- *
- * @see #ACTION_CHANGE_DEFAULT
- */
- public static final String EXTRA_CATEGORY = "category";
-
- /**
- * The service {@link ComponentName} object passed in as an
- * extra for {@link #ACTION_CHANGE_DEFAULT}.
- *
- * @see #ACTION_CHANGE_DEFAULT
- */
- public static final String EXTRA_SERVICE_COMPONENT = "component";
-
- /**
- * Category used for NFC payment services.
- */
- public static final String CATEGORY_PAYMENT = "payment";
-
- /**
- * Category that can be used for all other card emulation
- * services.
- */
- public static final String CATEGORY_OTHER = "other";
-
- /**
- * Return value for {@link #getSelectionModeForCategory(String)}.
- *
- * <p>In this mode, the user has set a default service for this
- * category.
- *
- * <p>When using ISO-DEP card emulation with {@link HostApduService}
- * or {@link OffHostApduService}, if a remote NFC device selects
- * any of the Application IDs (AIDs)
- * that the default service has registered in this category,
- * that service will automatically be bound to to handle
- * the transaction.
- */
- public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
-
- /**
- * Return value for {@link #getSelectionModeForCategory(String)}.
- *
- * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
- * or {@link OffHostApduService}, whenever an Application ID (AID) of this category
- * is selected, the user is asked which service they want to use to handle
- * the transaction, even if there is only one matching service.
- */
- public static final int SELECTION_MODE_ALWAYS_ASK = 1;
-
- /**
- * Return value for {@link #getSelectionModeForCategory(String)}.
- *
- * <p>In this mode, when using ISO-DEP card emulation with {@link HostApduService}
- * or {@link OffHostApduService}, the user will only be asked to select a service
- * if the Application ID (AID) selected by the reader has been registered by multiple
- * services. If there is only one service that has registered for the AID,
- * that service will be invoked directly.
- */
- public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
- /**
- * Route to Device Host (DH).
- */
- @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0;
- /**
- * Route to eSE.
- */
- @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1;
- /**
- * Route to UICC.
- */
- @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2;
-
- /**
- * Route to the default value in config file.
- */
- @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3;
-
- /**
- * Route unset.
- */
- @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1;
-
- /**
- * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * succeeded.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- public static final int SET_SERVICE_ENABLED_STATUS_OK = 0;
-
- /**
- * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * failed due to the unsupported feature.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1;
-
- /**
- * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * failed due to the invalid service.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2;
-
- /**
- * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * failed due to the service is already set to the requested status.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3;
-
- /**
- * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * failed due to unknown error.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4;
-
- /**
- * Status code returned by {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
- * @hide
- */
- @IntDef(prefix = "SET_SERVICE_ENABLED_STATUS_", value = {
- SET_SERVICE_ENABLED_STATUS_OK,
- SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED,
- SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE,
- SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET,
- SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SetServiceEnabledStatusCode {}
-
- /**
- * Property name used to indicate that an application wants to allow associated services
- * to share the same AID routing priority when this application is the role holder.
- * <p>
- * Example:
- * <pre>
- * {@code
- * <application>
- * ...
- * <property android:name="android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY"
- * android:value="true"/>
- * </application>
- * }
- * </pre>
- */
- @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES)
- public static final String PROPERTY_ALLOW_SHARED_ROLE_PRIORITY =
- "android.nfc.cardemulation.PROPERTY_ALLOW_SHARED_ROLE_PRIORITY";
-
- static boolean sIsInitialized = false;
- static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
- static INfcCardEmulation sService;
-
- final Context mContext;
-
- private CardEmulation(Context context, INfcCardEmulation service) {
- mContext = context.getApplicationContext();
- sService = service;
- }
-
- /**
- * Helper to get an instance of this class.
- *
- * @param adapter A reference to an NfcAdapter object.
- * @return
- */
- public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
- if (adapter == null) throw new NullPointerException("NfcAdapter is null");
- Context context = adapter.getContext();
- if (context == null) {
- Log.e(TAG, "NfcAdapter context is null.");
- throw new UnsupportedOperationException();
- }
- if (!sIsInitialized) {
- PackageManager pm = context.getPackageManager();
- if (pm == null) {
- Log.e(TAG, "Cannot get PackageManager");
- throw new UnsupportedOperationException();
- }
- if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
- Log.e(TAG, "This device does not support card emulation");
- throw new UnsupportedOperationException();
- }
- sIsInitialized = true;
- }
- CardEmulation manager = sCardEmus.get(context);
- if (manager == null) {
- // Get card emu service
- INfcCardEmulation service = adapter.getCardEmulationService();
- if (service == null) {
- Log.e(TAG, "This device does not implement the INfcCardEmulation interface.");
- throw new UnsupportedOperationException();
- }
- manager = new CardEmulation(context, service);
- sCardEmus.put(context, manager);
- }
- return manager;
- }
-
- /**
- * Allows an application to query whether a service is currently
- * the default service to handle a card emulation category.
- *
- * <p>Note that if {@link #getSelectionModeForCategory(String)}
- * returns {@link #SELECTION_MODE_ALWAYS_ASK} or {@link #SELECTION_MODE_ASK_IF_CONFLICT},
- * this method will always return false. That is because in these
- * selection modes a default can't be set at the category level. For categories where
- * the selection mode is {@link #SELECTION_MODE_ALWAYS_ASK} or
- * {@link #SELECTION_MODE_ASK_IF_CONFLICT}, use
- * {@link #isDefaultServiceForAid(ComponentName, String)} to determine whether a service
- * is the default for a specific AID.
- *
- * @param service The ComponentName of the service
- * @param category The category
- * @return whether service is currently the default service for the category.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- */
- public boolean isDefaultServiceForCategory(ComponentName service, String category) {
- return callServiceReturn(() ->
- sService.isDefaultServiceForCategory(
- mContext.getUser().getIdentifier(), service, category), false);
- }
-
- /**
- *
- * Allows an application to query whether a service is currently
- * the default handler for a specified ISO7816-4 Application ID.
- *
- * @param service The ComponentName of the service
- * @param aid The ISO7816-4 Application ID
- * @return whether the service is the default handler for the specified AID
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- */
- public boolean isDefaultServiceForAid(ComponentName service, String aid) {
- return callServiceReturn(() ->
- sService.isDefaultServiceForAid(
- mContext.getUser().getIdentifier(), service, aid), false);
- }
-
- /**
- * <p>
- * Returns whether the user has allowed AIDs registered in the
- * specified category to be handled by a service that is preferred
- * by the foreground application, instead of by a pre-configured default.
- *
- * Foreground applications can set such preferences using the
- * {@link #setPreferredService(Activity, ComponentName)} method.
- * <p class="note">
- * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, this method will always
- * return true.
- *
- * @param category The category, e.g. {@link #CATEGORY_PAYMENT}
- * @return whether AIDs in the category can be handled by a service
- * specified by the foreground app.
- */
- @SuppressWarnings("NonUserGetterCalled")
- public boolean categoryAllowsForegroundPreference(String category) {
- Context contextAsUser = mContext.createContextAsUser(
- UserHandle.of(UserHandle.myUserId()), 0);
-
- RoleManager roleManager = contextAsUser.getSystemService(RoleManager.class);
- if (roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)) {
- return true;
- }
-
- if (CATEGORY_PAYMENT.equals(category)) {
- boolean preferForeground = false;
- try {
- preferForeground = Settings.Secure.getInt(
- contextAsUser.getContentResolver(),
- Constants.SETTINGS_SECURE_NFC_PAYMENT_FOREGROUND) != 0;
- } catch (SettingNotFoundException e) {
- }
- return preferForeground;
- } else {
- // Allowed for all other categories
- return true;
- }
- }
-
- /**
- * Returns the service selection mode for the passed in category.
- * Valid return values are:
- * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
- * service for this category, which will be preferred.
- * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
- * every time what service they would like to use in this category.
- * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
- * to pick a service if there is a conflict.
- *
- * <p class="note">
- * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the default service defined
- * by the holder of {@link android.app.role.RoleManager#ROLE_WALLET} and is category agnostic.
- *
- * @param category The category, for example {@link #CATEGORY_PAYMENT}
- * @return the selection mode for the passed in category
- */
- public int getSelectionModeForCategory(String category) {
- if (CATEGORY_PAYMENT.equals(category)) {
- boolean paymentRegistered = callServiceReturn(() ->
- sService.isDefaultPaymentRegistered(), false);
- if (paymentRegistered) {
- return SELECTION_MODE_PREFER_DEFAULT;
- } else {
- return SELECTION_MODE_ALWAYS_ASK;
- }
- } else {
- return SELECTION_MODE_ASK_IF_CONFLICT;
- }
- }
- /**
- * Sets whether when this service becomes the preferred service, if the NFC stack
- * should enable observe mode or disable observe mode. The default is to not enable observe
- * mode when a service either the foreground default service or the default payment service so
- * not calling this method will preserve that behavior.
- *
- * @param service The component name of the service
- * @param enable Whether the service should default to observe mode or not
- * @return whether the change was successful.
- */
- @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
- public boolean setShouldDefaultToObserveModeForService(@NonNull ComponentName service,
- boolean enable) {
- return callServiceReturn(() ->
- sService.setShouldDefaultToObserveModeForService(
- mContext.getUser().getIdentifier(), service, enable), false);
- }
-
- /**
- * Register a polling loop filter (PLF) for a HostApduService and indicate whether it should
- * auto-transact or not. The PLF can be sequence of an
- * even number of at least 2 hexadecimal numbers (0-9, A-F or a-f), representing a series of
- * bytes. When non-standard polling loop frame matches this sequence exactly, it may be
- * delivered to {@link HostApduService#processPollingFrames(List)}. If auto-transact
- * is set to true and this service is currently preferred or there are no other services
- * registered for this filter then observe mode will also be disabled.
- * @param service The HostApduService to register the filter for
- * @param pollingLoopFilter The filter to register
- * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
- * transactions to proceed when this filter matches, false otherwise
- * @return true if the filter was registered, false otherwise
- * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public boolean registerPollingLoopFilterForService(@NonNull ComponentName service,
- @NonNull String pollingLoopFilter, boolean autoTransact) {
- final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
- return callServiceReturn(() ->
- sService.registerPollingLoopFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopFilterV, autoTransact),
- false);
- }
-
- /**
- * Unregister a polling loop filter (PLF) for a HostApduService. If the PLF had previously been
- * registered via {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)}
- * for this service it will be removed.
- * @param service The HostApduService to unregister the filter for
- * @param pollingLoopFilter The filter to unregister
- * @return true if the filter was removed, false otherwise
- * @throws IllegalArgumentException if the passed in string doesn't parse to at least one byte
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public boolean removePollingLoopFilterForService(@NonNull ComponentName service,
- @NonNull String pollingLoopFilter) {
- final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
- return callServiceReturn(() ->
- sService.removePollingLoopFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopFilterV), false);
- }
-
-
- /**
- * Register a polling loop pattern filter (PLPF) for a HostApduService and indicate whether it
- * should auto-transact or not. The pattern may include the characters 0-9 and A-F as well as
- * the regular expression operators `.`, `?` and `*`. When the beginning of anon-standard
- * polling loop frame matches this sequence exactly, it may be delivered to
- * {@link HostApduService#processPollingFrames(List)}. If auto-transact is set to true and this
- * service is currently preferred or there are no other services registered for this filter
- * then observe mode will also be disabled.
- * @param service The HostApduService to register the filter for
- * @param pollingLoopPatternFilter The pattern filter to register, must to be compatible with
- * {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
- * and `.`, `?` and `*` operators
- * @param autoTransact true to have the NFC stack automatically disable observe mode and allow
- * transactions to proceed when this filter matches, false otherwise
- * @return true if the filter was registered, false otherwise
- * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
- * numbers and `.`, `?` and `*` operators
- * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service,
- @NonNull String pollingLoopPatternFilter, boolean autoTransact) {
- final String pollingLoopPatternFilterV =
- validatePollingLoopPatternFilter(pollingLoopPatternFilter);
- return callServiceReturn(() ->
- sService.registerPollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV,
- autoTransact),
- false);
- }
-
- /**
- * Unregister a polling loop pattern filter (PLPF) for a HostApduService. If the PLF had
- * previously been registered via
- * {@link #registerPollingLoopFilterForService(ComponentName, String, boolean)} for this
- * service it will be removed.
- * @param service The HostApduService to unregister the filter for
- * @param pollingLoopPatternFilter The filter to unregister, must to be compatible with
- * {@link java.util.regex.Pattern#compile(String)} and only contain hexadecimal numbers
- * and`.`, `?` and `*` operators
- * @return true if the filter was removed, false otherwise
- * @throws IllegalArgumentException if the filter containst elements other than hexadecimal
- * numbers and `.`, `?` and `*` operators
- * @throws java.util.regex.PatternSyntaxException if the regex syntax is invalid
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service,
- @NonNull String pollingLoopPatternFilter) {
- final String pollingLoopPatternFilterV =
- validatePollingLoopPatternFilter(pollingLoopPatternFilter);
- return callServiceReturn(() ->
- sService.removePollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV), false);
- }
-
- /**
- * Registers a list of AIDs for a specific category for the
- * specified service.
- *
- * <p>If a list of AIDs for that category was previously
- * registered for this service (either statically
- * through the manifest, or dynamically by using this API),
- * that list of AIDs will be replaced with this one.
- *
- * <p>Note that you can only register AIDs for a service that
- * is running under the same UID as the caller of this API. Typically
- * this means you need to call this from the same
- * package as the service itself, though UIDs can also
- * be shared between packages using shared UIDs.
- *
- * @param service The component name of the service
- * @param category The category of AIDs to be registered
- * @param aids A list containing the AIDs to be registered
- * @return whether the registration was successful.
- */
- public boolean registerAidsForService(ComponentName service, String category,
- List<String> aids) {
- final AidGroup aidGroup = new AidGroup(aids, category);
- return callServiceReturn(() ->
- sService.registerAidGroupForService(
- mContext.getUser().getIdentifier(), service, aidGroup), false);
- }
-
- /**
- * Unsets the off-host Secure Element for the given service.
- *
- * <p>Note that this will only remove Secure Element that was dynamically
- * set using the {@link #setOffHostForService(ComponentName, String)}
- * and resets it to a value that was statically assigned using manifest.
- *
- * <p>Note that you can only unset off-host SE for a service that
- * is running under the same UID as the caller of this API. Typically
- * this means you need to call this from the same
- * package as the service itself, though UIDs can also
- * be shared between packages using shared UIDs.
- *
- * @param service The component name of the service
- * @return whether the registration was successful.
- */
- @RequiresPermission(android.Manifest.permission.NFC)
- @NonNull
- public boolean unsetOffHostForService(@NonNull ComponentName service) {
- return callServiceReturn(() ->
- sService.unsetOffHostForService(
- mContext.getUser().getIdentifier(), service), false);
- }
-
- /**
- * Sets the off-host Secure Element for the given service.
- *
- * <p>If off-host SE was initially set (either statically
- * through the manifest, or dynamically by using this API),
- * it will be replaced with this one. All AIDs registered by
- * this service will be re-routed to this Secure Element if
- * successful. AIDs that was statically assigned using manifest
- * will re-route to off-host SE that stated in manifest after NFC
- * toggle.
- *
- * <p>Note that you can only set off-host SE for a service that
- * is running under the same UID as the caller of this API. Typically
- * this means you need to call this from the same
- * package as the service itself, though UIDs can also
- * be shared between packages using shared UIDs.
- *
- * <p>Registeration will be successful only if the Secure Element
- * exists on the device.
- *
- * @param service The component name of the service
- * @param offHostSecureElement Secure Element to register the AID to. Only accept strings with
- * prefix SIM or prefix eSE.
- * Ref: GSMA TS.26 - NFC Handset Requirements
- * TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
- * SIM[smartcard slot]
- * (e.g. SIM/SIM1, SIM2… SIMn).
- * TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
- * eSE[number]
- * (e.g. eSE/eSE1, eSE2, etc.).
- * @return whether the registration was successful.
- */
- @RequiresPermission(android.Manifest.permission.NFC)
- @NonNull
- public boolean setOffHostForService(@NonNull ComponentName service,
- @NonNull String offHostSecureElement) {
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
- if (adapter == null || offHostSecureElement == null) {
- return false;
- }
-
- List<String> validSE = adapter.getSupportedOffHostSecureElements();
- if ((offHostSecureElement.startsWith("eSE") && !validSE.contains("eSE"))
- || (offHostSecureElement.startsWith("SIM") && !validSE.contains("SIM"))) {
- return false;
- }
-
- if (!offHostSecureElement.startsWith("eSE") && !offHostSecureElement.startsWith("SIM")) {
- return false;
- }
-
- if (offHostSecureElement.equals("eSE")) {
- offHostSecureElement = "eSE1";
- } else if (offHostSecureElement.equals("SIM")) {
- offHostSecureElement = "SIM1";
- }
- final String offHostSecureElementV = new String(offHostSecureElement);
- return callServiceReturn(() ->
- sService.setOffHostForService(
- mContext.getUser().getIdentifier(), service, offHostSecureElementV), false);
- }
-
- /**
- * Retrieves the currently registered AIDs for the specified
- * category for a service.
- *
- * <p>Note that this will only return AIDs that were dynamically
- * registered using {@link #registerAidsForService(ComponentName, String, List)}
- * method. It will *not* return AIDs that were statically registered
- * in the manifest.
- *
- * @param service The component name of the service
- * @param category The category for which the AIDs were registered,
- * e.g. {@link #CATEGORY_PAYMENT}
- * @return The list of AIDs registered for this category, or null if it couldn't be found.
- */
- public List<String> getAidsForService(ComponentName service, String category) {
- AidGroup group = callServiceReturn(() ->
- sService.getAidGroupForService(
- mContext.getUser().getIdentifier(), service, category), null);
- return (group != null ? group.getAids() : null);
- }
-
- /**
- * Removes a previously registered list of AIDs for the specified category for the
- * service provided.
- *
- * <p>Note that this will only remove AIDs that were dynamically
- * registered using the {@link #registerAidsForService(ComponentName, String, List)}
- * method. It will *not* remove AIDs that were statically registered in
- * the manifest. If dynamically registered AIDs are removed using
- * this method, and a statically registered AID group for the same category
- * exists in the manifest, the static AID group will become active again.
- *
- * @param service The component name of the service
- * @param category The category of the AIDs to be removed, e.g. {@link #CATEGORY_PAYMENT}
- * @return whether the group was successfully removed.
- */
- public boolean removeAidsForService(ComponentName service, String category) {
- return callServiceReturn(() ->
- sService.removeAidGroupForService(
- mContext.getUser().getIdentifier(), service, category), false);
- }
-
- /**
- * Allows a foreground application to specify which card emulation service
- * should be preferred while a specific Activity is in the foreground.
- *
- * <p>The specified Activity must currently be in resumed state. A good
- * paradigm is to call this method in your {@link Activity#onResume}, and to call
- * {@link #unsetPreferredService(Activity)} in your {@link Activity#onPause}.
- *
- * <p>This method call will fail in two specific scenarios:
- * <ul>
- * <li> If the service registers one or more AIDs in the {@link #CATEGORY_PAYMENT}
- * category, but the user has indicated that foreground apps are not allowed
- * to override the default payment service.
- * <li> If the service registers one or more AIDs in the {@link #CATEGORY_OTHER}
- * category that are also handled by the default payment service, and the
- * user has indicated that foreground apps are not allowed to override the
- * default payment service.
- * </ul>
- *
- * <p> Use {@link #categoryAllowsForegroundPreference(String)} to determine
- * whether foreground apps can override the default payment service.
- *
- * <p>Note that this preference is not persisted by the OS, and hence must be
- * called every time the Activity is resumed.
- *
- * @param activity The activity which prefers this service to be invoked
- * @param service The service to be preferred while this activity is in the foreground
- * @return whether the registration was successful
- */
- public boolean setPreferredService(Activity activity, ComponentName service) {
- // Verify the activity is in the foreground before calling into NfcService
- if (activity == null || service == null) {
- throw new NullPointerException("activity or service or category is null");
- }
- return callServiceReturn(() -> sService.setPreferredService(service), false);
- }
-
- /**
- * Unsets the preferred service for the specified Activity.
- *
- * <p>Note that the specified Activity must still be in resumed
- * state at the time of this call. A good place to call this method
- * is in your {@link Activity#onPause} implementation.
- *
- * @param activity The activity which the service was registered for
- * @return true when successful
- */
- public boolean unsetPreferredService(Activity activity) {
- if (activity == null) {
- throw new NullPointerException("activity is null");
- }
- return callServiceReturn(() -> sService.unsetPreferredService(), false);
- }
-
- /**
- * Some devices may allow an application to register all
- * AIDs that starts with a certain prefix, e.g.
- * "A000000004*" to register all MasterCard AIDs.
- *
- * Use this method to determine whether this device
- * supports registering AID prefixes.
- *
- * @return whether AID prefix registering is supported on this device.
- */
- public boolean supportsAidPrefixRegistration() {
- return callServiceReturn(() -> sService.supportsAidPrefixRegistration(), false);
- }
-
- /**
- * Retrieves the registered AIDs for the preferred payment service.
- *
- * @return The list of AIDs registered for this category, or null if it couldn't be found.
- */
- @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
- @Nullable
- public List<String> getAidsForPreferredPaymentService() {
- ApduServiceInfo serviceInfo = callServiceReturn(() ->
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
- return (serviceInfo != null ? serviceInfo.getAids() : null);
- }
-
- /**
- * Retrieves the route destination for the preferred payment service.
- *
- * <p class="note">
- * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
- * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
- * will return the route for one of the services registered by the role holder (if any). If
- * there are multiple services registered, it is unspecified which of those will be used to
- * determine the route.
- *
- * @return The route destination secure element name of the preferred payment service.
- * HCE payment: "Host"
- * OffHost payment: 1. String with prefix SIM or prefix eSE string.
- * Ref: GSMA TS.26 - NFC Handset Requirements
- * TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be
- * SIM[smartcard slot]
- * (e.g. SIM/SIM1, SIM2… SIMn).
- * TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be
- * eSE[number]
- * (e.g. eSE/eSE1, eSE2, etc.).
- * 2. "OffHost" if the payment service does not specify secure element
- * name.
- */
- @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
- @Nullable
- public String getRouteDestinationForPreferredPaymentService() {
- ApduServiceInfo serviceInfo = callServiceReturn(() ->
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
- if (serviceInfo != null) {
- if (!serviceInfo.isOnHost()) {
- return serviceInfo.getOffHostSecureElement() == null ?
- "OffHost" : serviceInfo.getOffHostSecureElement();
- }
- return "Host";
- }
- return null;
- }
-
- /**
- * Returns a user-visible description of the preferred payment service.
- *
- * <p class="note">
- * Starting with {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, the preferred payment service
- * no longer exists and is replaced by {@link android.app.role.RoleManager#ROLE_WALLET}. This
- * will return the description for one of the services registered by the role holder (if any).
- * If there are multiple services registered, it is unspecified which of those will be used
- * to obtain the service description here.
- *
- * @return the preferred payment service description
- */
- @RequiresPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
- @Nullable
- public CharSequence getDescriptionForPreferredPaymentService() {
- ApduServiceInfo serviceInfo = callServiceReturn(() ->
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
- return (serviceInfo != null ? serviceInfo.getDescription() : null);
- }
-
- /**
- * @hide
- */
- public boolean setDefaultServiceForCategory(ComponentName service, String category) {
- return callServiceReturn(() ->
- sService.setDefaultServiceForCategory(
- mContext.getUser().getIdentifier(), service, category), false);
- }
-
- /**
- * @hide
- */
- public boolean setDefaultForNextTap(ComponentName service) {
- return callServiceReturn(() ->
- sService.setDefaultForNextTap(
- mContext.getUser().getIdentifier(), service), false);
- }
-
- /**
- * @hide
- */
- public boolean setDefaultForNextTap(int userId, ComponentName service) {
- return callServiceReturn(() ->
- sService.setDefaultForNextTap(userId, service), false);
- }
-
- /**
- * @hide
- */
- public List<ApduServiceInfo> getServices(String category) {
- return callServiceReturn(() ->
- sService.getServices(
- mContext.getUser().getIdentifier(), category), null);
- }
-
- /**
- * Retrieves list of services registered of the provided category for the provided user.
- *
- * @param category Category string, one of {@link #CATEGORY_PAYMENT} or {@link #CATEGORY_OTHER}
- * @param userId the user handle of the user whose information is being requested.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
- @NonNull
- public List<ApduServiceInfo> getServices(@NonNull String category, @UserIdInt int userId) {
- return callServiceReturn(() ->
- sService.getServices(userId, category), null);
- }
-
- /**
- * Tests the validity of the polling loop filter.
- * @param pollingLoopFilter The polling loop filter to test.
- *
- * @hide
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static @NonNull String validatePollingLoopFilter(@NonNull String pollingLoopFilter) {
- // Verify hex characters
- byte[] plfBytes = HexFormat.of().parseHex(pollingLoopFilter);
- if (plfBytes.length == 0) {
- throw new IllegalArgumentException(
- "Polling loop filter must contain at least one byte.");
- }
- return HexFormat.of().withUpperCase().formatHex(plfBytes);
- }
-
- /**
- * Tests the validity of the polling loop pattern filter.
- * @param pollingLoopPatternFilter The polling loop filter to test.
- *
- * @hide
- */
- @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static @NonNull String validatePollingLoopPatternFilter(
- @NonNull String pollingLoopPatternFilter) {
- // Verify hex characters
- if (!PLPF_PATTERN.matcher(pollingLoopPatternFilter).matches()) {
- throw new IllegalArgumentException(
- "Polling loop pattern filters may only contain hexadecimal numbers, ?s and *s");
- }
- return Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT)).toString();
- }
-
- /**
- * A valid AID according to ISO/IEC 7816-4:
- * <ul>
- * <li>Has >= 5 bytes and <=16 bytes (>=10 hex chars and <= 32 hex chars)
- * <li>Consist of only hex characters
- * <li>Additionally, we allow an asterisk at the end, to indicate
- * a prefix
- * <li>Additinally we allow an (#) at symbol at the end, to indicate
- * a subset
- * </ul>
- *
- * @hide
- */
- public static boolean isValidAid(String aid) {
- if (aid == null)
- return false;
-
- // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
- if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
- Log.e(TAG, "AID " + aid + " is not a valid AID.");
- return false;
- }
-
- // If not a prefix/subset AID, the total length must be even (even # of AID chars)
- if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
- Log.e(TAG, "AID " + aid + " is not a valid AID.");
- return false;
- }
-
- // Verify hex characters
- if (!AID_PATTERN.matcher(aid).matches()) {
- Log.e(TAG, "AID " + aid + " is not a valid AID.");
- return false;
- }
-
- return true;
- }
-
- /**
- * Allows to set or unset preferred service (category other) to avoid AID Collision. The user
- * should use corresponding context using {@link Context#createContextAsUser(UserHandle, int)}
- *
- * @param service The ComponentName of the service
- * @param status true to enable, false to disable
- * @return status code defined in {@link SetServiceEnabledStatusCode}
- *
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- @SetServiceEnabledStatusCode
- public int setServiceEnabledForCategoryOther(@NonNull ComponentName service,
- boolean status) {
- return callServiceReturn(() ->
- sService.setServiceEnabledForCategoryOther(mContext.getUser().getIdentifier(),
- service, status), SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR);
- }
-
- /** @hide */
- @IntDef(prefix = "PROTOCOL_AND_TECHNOLOGY_ROUTE_",
- value = {
- PROTOCOL_AND_TECHNOLOGY_ROUTE_DH,
- PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE,
- PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC,
- PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET,
- PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ProtocolAndTechnologyRoute {}
-
- /**
- * Setting NFC controller routing table, which includes Protocol Route and Technology Route,
- * while this Activity is in the foreground.
- *
- * The parameter set to {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
- * can be used to keep current values for that entry. Either
- * Protocol Route or Technology Route should be override when calling this API, otherwise
- * throw {@link IllegalArgumentException}.
- * <p>
- * Example usage in an Activity that requires to set proto route to "ESE" and keep tech route:
- * <pre>
- * protected void onResume() {
- * mNfcAdapter.overrideRoutingTable(
- * this, {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE},
- * {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET});
- * }</pre>
- * </p>
- * Also activities must call {@link #recoverRoutingTable(Activity)}
- * when it goes to the background. Only the package of the
- * currently preferred service (the service set as preferred by the current foreground
- * application via {@link CardEmulation#setPreferredService(Activity, ComponentName)} or the
- * current Default Wallet Role Holder {@link RoleManager#ROLE_WALLET}),
- * otherwise a call to this method will fail and throw {@link SecurityException}.
- * @param activity The Activity that requests NFC controller routing table to be changed.
- * @param protocol ISO-DEP route destination, where the possible inputs are defined
- * in {@link ProtocolAndTechnologyRoute}.
- * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
- * are defined in {@link ProtocolAndTechnologyRoute}
- * @throws SecurityException if the caller is not the preferred NFC service
- * @throws IllegalArgumentException if the activity is not resumed or the caller is not in the
- * foreground.
- * <p>
- * This is a high risk API and only included to support mainline effort
- * @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,
- @ProtocolAndTechnologyRoute int technology) {
- if (!activity.isResumed()) {
- throw new IllegalArgumentException("Activity must be resumed.");
- }
- String protocolRoute = routeIntToString(protocol);
- String technologyRoute = routeIntToString(technology);
- callService(() ->
- sService.overrideRoutingTable(
- mContext.getUser().getIdentifier(),
- protocolRoute,
- technologyRoute,
- mContext.getPackageName()));
- }
-
- /**
- * Restore the NFC controller routing table,
- * which was changed by {@link #overrideRoutingTable(Activity, int, int)}
- *
- * @param activity The Activity that requested NFC controller routing table to be changed.
- * @throws IllegalArgumentException if the caller is not in the foreground.
- *
- * @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()) {
- throw new IllegalArgumentException("Activity must be resumed.");
- }
- callService(() ->
- sService.recoverRoutingTable(
- mContext.getUser().getIdentifier()));
- }
-
- /**
- * Is EUICC supported as a Secure Element EE which supports off host card emulation.
- *
- * @return true if the device supports EUICC for off host card emulation, false otherwise.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
- public boolean isEuiccSupported() {
- return callServiceReturn(() -> sService.isEuiccSupported(), false);
- }
-
- /**
- * 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;
-
- /**
- * Setting the default subscription ID failed because of unknown error.
- * @hide
- */
- @SystemApi
- @FlaggedApi(Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
- public static final int SET_SUBSCRIPTION_ID_STATUS_UNKNOWN = -1;
-
- /** @hide */
- @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
- value = {
- 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,
- SET_SUBSCRIPTION_ID_STATUS_UNKNOWN
- })
- @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 transactions </p>
- *
- * @param subscriptionId the default NFC subscription Id to set. User can get subscription id
- * from {@link SubscriptionManager#getSubscriptionId(int)}
- * @return status of the operation.
- *
- * @throws UnsupportedOperationException If the device does not have
- * {@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 transactions </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
- * @return A ComponentName for the setting value, or null.
- *
- * @hide
- */
- @SystemApi
- @UserHandleAware
- @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
- @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
- @FlaggedApi(android.permission.flags.Flags.FLAG_WALLET_ROLE_ENABLED)
- @Nullable
- public static ComponentName getPreferredPaymentService(@NonNull Context context) {
- context.checkCallingOrSelfPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO);
- String defaultPaymentComponent = Settings.Secure.getString(context.getContentResolver(),
- Constants.SETTINGS_SECURE_NFC_PAYMENT_DEFAULT_COMPONENT);
-
- if (defaultPaymentComponent == null) {
- return null;
- }
-
- return ComponentName.unflattenFromString(defaultPaymentComponent);
- }
-
- /** @hide */
- interface ServiceCall {
- void call() throws RemoteException;
- }
- /** @hide */
- public static void callService(ServiceCall call) {
- try {
- if (sService == null) {
- NfcAdapter.attemptDeadServiceRecovery(
- new RemoteException("NFC CardEmulation Service is null"));
- sService = NfcAdapter.getCardEmulationService();
- }
- call.call();
- } catch (RemoteException e) {
- NfcAdapter.attemptDeadServiceRecovery(e);
- sService = NfcAdapter.getCardEmulationService();
- try {
- call.call();
- } catch (RemoteException ee) {
- ee.rethrowAsRuntimeException();
- }
- }
- }
- /** @hide */
- interface ServiceCallReturn<T> {
- T call() throws RemoteException;
- }
- /** @hide */
- public static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
- try {
- if (sService == null) {
- NfcAdapter.attemptDeadServiceRecovery(
- new RemoteException("NFC CardEmulation Service is null"));
- sService = NfcAdapter.getCardEmulationService();
- }
- return call.call();
- } catch (RemoteException e) {
- NfcAdapter.attemptDeadServiceRecovery(e);
- sService = NfcAdapter.getCardEmulationService();
- // Try one more time
- try {
- return call.call();
- } catch (RemoteException ee) {
- ee.rethrowAsRuntimeException();
- }
- }
- return defaultReturn;
- }
-
- /** @hide */
- public static String routeIntToString(@ProtocolAndTechnologyRoute int route) {
- return switch (route) {
- case PROTOCOL_AND_TECHNOLOGY_ROUTE_DH -> "DH";
- case PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE -> "eSE";
- case PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC -> "SIM";
- case PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET -> null;
- case PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT -> "default";
- default -> throw new IllegalStateException("Unexpected value: " + route);
- };
- }
-
- @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 {
- /**
- * This method is called when this package gains or loses preferred Nfc service status,
- * either the Default Wallet Role holder (see {@link
- * android.app.role.RoleManager#ROLE_WALLET}) or the preferred service of the foreground
- * activity set with {@link #setPreferredService(Activity, ComponentName)}
- *
- * @param isPreferred true is this service has become the preferred Nfc service, false if it
- * is no longer the preferred service
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- default void onPreferredServiceChanged(boolean isPreferred) {}
-
- /**
- * This method is called when observe mode has been enabled or disabled.
- *
- * @param isEnabled true if observe mode has been enabled, false if it has been disabled
- */
- @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<>();
-
- final INfcEventListener mINfcEventListener =
- new INfcEventListener.Stub() {
- public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) {
- if (!android.nfc.Flags.nfcEventListener()) {
- return;
- }
- boolean isPreferred =
- componentNameAndUser != null
- && componentNameAndUser.getUserId()
- == mContext.getUser().getIdentifier()
- && componentNameAndUser.getComponentName() != null
- && Objects.equals(
- mContext.getPackageName(),
- componentNameAndUser.getComponentName()
- .getPackageName());
- 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(() -> listenerCall.invoke(listener));
- });
- }
- }
- };
-
- /**
- * Register a listener for NFC Events.
- *
- * @param executor The Executor to run the call back with
- * @param listener The listener to register
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- public void registerNfcEventListener(
- @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventListener listener) {
- if (!android.nfc.Flags.nfcEventListener()) {
- return;
- }
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.put(listener, executor);
- if (mNfcEventListeners.size() == 1) {
- callService(() -> sService.registerNfcEventListener(mINfcEventListener));
- }
- }
- }
-
- /**
- * Unregister a preferred service listener that was previously registered with {@link
- * #registerNfcEventListener(Executor, NfcEventListener)}
- *
- * @param listener The previously registered listener to unregister
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- public void unregisterNfcEventListener(@NonNull NfcEventListener listener) {
- if (!android.nfc.Flags.nfcEventListener()) {
- return;
- }
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.remove(listener);
- if (mNfcEventListeners.size() == 0) {
- callService(() -> sService.unregisterNfcEventListener(mINfcEventListener));
- }
- }
- }
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
deleted file mode 100644
index db1f6a2bb3b1..000000000000
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SuppressLint;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.nfc.NfcAdapter;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * <p>HostApduService is a convenience {@link Service} class that can be
- * extended to emulate an NFC card inside an Android
- * service component.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction to card emulation, see
- * <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * Host-based Card Emulation</a>.</p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * service, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, a service may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to this service
- * <li>No AIDs in the group are routed to this service
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this service, and some to another.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs groups
- * are requested by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a HostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
- * &lt;/intent-filter&gt;
- * &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- * android:description="@string/servicedesc" android:requireDeviceUnlock="false"&gt;
- * &lt;aid-group android:description="@string/aiddescription" android:category="other">
- * &lt;aid-filter android:name="F0010203040506"/&gt;
- * &lt;aid-filter android:name="F0394148148100"/&gt;
- * &lt;/aid-group&gt;
- * &lt;/host-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * The
- * {@link android.R.styleable#HostApduService_requireDeviceUnlock &lt;requireDeviceUnlock&gt;}
- * attribute can be used to specify that the device must be unlocked before this service
- * can be invoked to handle APDUs.
- * <p>The {@link android.R.styleable#HostApduService &lt;host-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- * <h3>AID conflict resolution</h3>
- * Multiple HostApduServices may be installed on a single device, and the same AID
- * can be registered by more than one service. The Android platform resolves AID
- * conflicts depending on which category an AID belongs to. Each category may
- * have a different conflict resolution policy. For example, for some categories
- * the user may be able to select a default service in the Android settings UI.
- * For other categories, to policy may be to always ask the user which service
- * is to be invoked in case of conflict.
- *
- * To query the conflict resolution policy for a certain category, see
- * {@link CardEmulation#getSelectionModeForCategory(String)}.
- *
- * <h3>Data exchange</h3>
- * <p>Once the platform has resolved a "SELECT AID" command APDU to a specific
- * service component, the "SELECT AID" command APDU and all subsequent
- * command APDUs will be sent to that service through
- * {@link #processCommandApdu(byte[], Bundle)}, until either:
- * <ul>
- * <li>The NFC link is broken</li>
- * <li>A "SELECT AID" APDU is received which resolves to another service</li>
- * </ul>
- * These two scenarios are indicated by a call to {@link #onDeactivated(int)}.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- *
- */
-public abstract class HostApduService extends Service {
- /**
- * The {@link Intent} action that must be declared as handled by the service.
- */
- @SdkConstant(SdkConstantType.SERVICE_ACTION)
- public static final String SERVICE_INTERFACE =
- "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
-
- /**
- * The name of the meta-data element that contains
- * more information about this service.
- */
- public static final String SERVICE_META_DATA =
- "android.nfc.cardemulation.host_apdu_service";
-
- /**
- * Reason for {@link #onDeactivated(int)}.
- * Indicates deactivation was due to the NFC link
- * being lost.
- */
- public static final int DEACTIVATION_LINK_LOSS = 0;
-
- /**
- * Reason for {@link #onDeactivated(int)}.
- *
- * <p>Indicates deactivation was due to a different AID
- * being selected (which implicitly deselects the AID
- * currently active on the logical channel).
- *
- * <p>Note that this next AID may still be resolved to this
- * service, in which case {@link #processCommandApdu(byte[], Bundle)}
- * will be called again.
- */
- public static final int DEACTIVATION_DESELECTED = 1;
-
- static final String TAG = "ApduService";
-
- /**
- * MSG_COMMAND_APDU is sent by NfcService when
- * a 7816-4 command APDU has been received.
- *
- * @hide
- */
- public static final int MSG_COMMAND_APDU = 0;
-
- /**
- * MSG_RESPONSE_APDU is sent to NfcService to send
- * a response APDU back to the remote device.
- *
- * @hide
- */
- public static final int MSG_RESPONSE_APDU = 1;
-
- /**
- * MSG_DEACTIVATED is sent by NfcService when
- * the current session is finished; either because
- * another AID was selected that resolved to
- * another service, or because the NFC link
- * was deactivated.
- *
- * @hide
- */
- public static final int MSG_DEACTIVATED = 2;
-
- /**
- *
- * @hide
- */
- public static final int MSG_UNHANDLED = 3;
-
- /**
- * @hide
- */
- public static final int MSG_POLLING_LOOP = 4;
-
-
- /**
- * @hide
- */
- public static final String KEY_DATA = "data";
-
- /**
- * @hide
- */
- public static final String KEY_POLLING_LOOP_FRAMES_BUNDLE =
- "android.nfc.cardemulation.POLLING_FRAMES";
-
- /**
- * Messenger interface to NfcService for sending responses.
- * Only accessed on main thread by the message handler.
- *
- * @hide
- */
- Messenger mNfcService = null;
-
- final Messenger mMessenger = new Messenger(new MsgHandler());
-
- final class MsgHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_COMMAND_APDU:
- Bundle dataBundle = msg.getData();
- if (dataBundle == null) {
- return;
- }
- if (mNfcService == null) mNfcService = msg.replyTo;
-
- byte[] apdu = dataBundle.getByteArray(KEY_DATA);
- if (apdu != null) {
- HostApduService has = HostApduService.this;
- byte[] responseApdu = processCommandApdu(apdu, null);
- if (responseApdu != null) {
- if (mNfcService == null) {
- Log.e(TAG, "Response not sent; service was deactivated.");
- return;
- }
- Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
- Bundle responseBundle = new Bundle();
- responseBundle.putByteArray(KEY_DATA, responseApdu);
- responseMsg.setData(responseBundle);
- responseMsg.replyTo = mMessenger;
- try {
- mNfcService.send(responseMsg);
- } catch (RemoteException e) {
- Log.e("TAG", "Response not sent; RemoteException calling into " +
- "NfcService.");
- }
- }
- } else {
- Log.e(TAG, "Received MSG_COMMAND_APDU without data.");
- }
- break;
- case MSG_RESPONSE_APDU:
- if (mNfcService == null) {
- Log.e(TAG, "Response not sent; service was deactivated.");
- return;
- }
- try {
- msg.replyTo = mMessenger;
- mNfcService.send(msg);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling into NfcService.");
- }
- break;
- case MSG_DEACTIVATED:
- // Make sure we won't call into NfcService again
- mNfcService = null;
- onDeactivated(msg.arg1);
- break;
- case MSG_UNHANDLED:
- if (mNfcService == null) {
- Log.e(TAG, "notifyUnhandled not sent; service was deactivated.");
- return;
- }
- try {
- msg.replyTo = mMessenger;
- mNfcService.send(msg);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling into NfcService.");
- }
- break;
- case MSG_POLLING_LOOP:
- if (android.nfc.Flags.nfcReadPollingLoop()) {
- ArrayList<PollingFrame> pollingFrames =
- msg.getData().getParcelableArrayList(
- KEY_POLLING_LOOP_FRAMES_BUNDLE, PollingFrame.class);
- processPollingFrames(pollingFrames);
- }
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
-
- @Override
- public final IBinder onBind(Intent intent) {
- return mMessenger.getBinder();
- }
-
- /**
- * Sends a response APDU back to the remote device.
- *
- * <p>Note: this method may be called from any thread and will not block.
- * @param responseApdu A byte-array containing the reponse APDU.
- */
- public final void sendResponseApdu(byte[] responseApdu) {
- Message responseMsg = Message.obtain(null, MSG_RESPONSE_APDU);
- Bundle dataBundle = new Bundle();
- dataBundle.putByteArray(KEY_DATA, responseApdu);
- responseMsg.setData(dataBundle);
- try {
- mMessenger.send(responseMsg);
- } catch (RemoteException e) {
- Log.e("TAG", "Local messenger has died.");
- }
- }
-
- /**
- * Calling this method allows the service to tell the OS
- * that it won't be able to complete this transaction -
- * for example, because it requires data connectivity
- * that is not present at that moment.
- *
- * The OS may use this indication to give the user a list
- * of alternative applications that can handle the last
- * AID that was selected. If the user would select an
- * application from the list, that action by itself
- * will not cause the default to be changed; the selected
- * application will be invoked for the next tap only.
- *
- * If there are no other applications that can handle
- * this transaction, the OS will show an error dialog
- * indicating your service could not complete the
- * transaction.
- *
- * <p>Note: this method may be called anywhere between
- * the first {@link #processCommandApdu(byte[], Bundle)}
- * call and a {@link #onDeactivated(int)} call.
- */
- public final void notifyUnhandled() {
- Message unhandledMsg = Message.obtain(null, MSG_UNHANDLED);
- try {
- mMessenger.send(unhandledMsg);
- } catch (RemoteException e) {
- Log.e("TAG", "Local messenger has died.");
- }
- }
-
- /**
- * This method is called when polling frames have been received from a
- * remote device. If the device is in observe mode, the service should
- * call {@link NfcAdapter#allowTransaction()} once it is ready to proceed
- * with the transaction. If the device is not in observe mode, the service
- * can use this polling frame information to determine how to proceed if it
- * subsequently has {@link #processCommandApdu(byte[], Bundle)} called. The
- * service must override this method inorder to receive polling frames,
- * otherwise the base implementation drops the frame.
- *
- * @param frame A description of the polling frame.
- */
- @SuppressLint("OnNameExpected")
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public void processPollingFrames(@NonNull List<PollingFrame> frame) {
- }
-
- /**
- * <p>This method will be called when a command APDU has been received
- * from a remote device. A response APDU can be provided directly
- * by returning a byte-array in this method. Note that in general
- * response APDUs must be sent as quickly as possible, given the fact
- * that the user is likely holding their device over an NFC reader
- * when this method is called.
- *
- * <p class="note">If there are multiple services that have registered for the same
- * AIDs in their meta-data entry, you will only get called if the user has
- * explicitly selected your service, either as a default or just for the next tap.
- *
- * <p class="note">This method is running on the main thread of your application.
- * If you cannot return a response APDU immediately, return null
- * and use the {@link #sendResponseApdu(byte[])} method later.
- *
- * @param commandApdu The APDU that was received from the remote device
- * @param extras A bundle containing extra data. May be null.
- * @return a byte-array containing the response APDU, or null if no
- * response APDU can be sent at this point.
- */
- public abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras);
-
- /**
- * This method will be called in two possible scenarios:
- * <li>The NFC link has been deactivated or lost
- * <li>A different AID has been selected and was resolved to a different
- * service component
- * @param reason Either {@link #DEACTIVATION_LINK_LOSS} or {@link #DEACTIVATION_DESELECTED}
- */
- public abstract void onDeactivated(int reason);
-
-}
diff --git a/nfc/java/android/nfc/cardemulation/HostNfcFService.java b/nfc/java/android/nfc/cardemulation/HostNfcFService.java
deleted file mode 100644
index 65b5ca77de62..000000000000
--- a/nfc/java/android/nfc/cardemulation/HostNfcFService.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * <p>HostNfcFService is a convenience {@link Service} class that can be
- * extended to emulate an NFC-F card inside an Android service component.
- *
- * <h3>NFC Protocols</h3>
- * <p>Cards emulated by this class are based on the NFC-Forum NFC-F
- * protocol (based on the JIS-X 6319-4 specification.)</p>
- *
- * <h3>System Code and NFCID2 registration</h3>
- * <p>A {@link HostNfcFService HostNfcFService service} can register
- * exactly one System Code and one NFCID2. For details about the use of
- * System Code and NFCID2, see the NFC Forum Digital specification.</p>
- * <p>To statically register a System Code and NFCID2 with the service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service.
- *
- * <p>All {@link HostNfcFService HostNfcFService} declarations in the manifest must require the
- * {@link android.Manifest.permission#BIND_NFC_SERVICE} permission
- * in their &lt;service&gt; tag, to ensure that only the platform can bind to your service.</p>
- *
- * <p>An example of a HostNfcFService manifest declaration is shown below:
- *
- * <pre> &lt;service android:name=".MyHostNfcFService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/&gt;
- * &lt;/intent-filter&gt;
- * &lt;meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/nfcfservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an nfcfservice.xml file.
- * An example of this file with a System Code and NFCID2 declaration is shown below:
- * <pre>
- * &lt;host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
- * android:description="@string/servicedesc"&gt;
- * &lt;system-code-filter android:name="4000"/&gt;
- * &lt;nfcid2-filter android:name="02FE000000000000"/&gt;
- &lt;t3tPmm-filter android:name="FFFFFFFFFFFFFFFF"/&gt;
- * &lt;/host-nfcf-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#HostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- * <p>The {@link android.R.styleable#HostNfcFService &lt;host-nfcf-service&gt;} must
- * contain:
- * <ul>
- * <li>Exactly one {@link android.R.styleable#SystemCodeFilter &lt;system-code-filter&gt;} tag.</li>
- * <li>Exactly one {@link android.R.styleable#Nfcid2Filter &lt;nfcid2-filter&gt;} tag.</li>
- * <li>Zero or one {@link android.R.styleable#T3tPmmFilter &lt;t3tPmm-filter&gt;} tag.</li>
- * </ul>
- * </p>
- *
- * <p>Alternatively, the System Code and NFCID2 can be dynamically registererd for a service
- * by using the {@link NfcFCardEmulation#registerSystemCodeForService(ComponentName, String)} and
- * {@link NfcFCardEmulation#setNfcid2ForService(ComponentName, String)} methods.
- * </p>
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC devices wants to communicate with your service, it
- * sends a SENSF_REQ command to the NFC controller, requesting a System Code.
- * If a {@link NfcFCardEmulation NfcFCardEmulation service} has registered
- * this system code and has been enabled by the foreground application, the
- * NFC controller will respond with the NFCID2 that is registered for this service.
- * The reader can then continue data exchange with this service by using the NFCID2.</p>
- *
- * <h3>Data exchange</h3>
- * <p>After service selection, all frames addressed to the NFCID2 of this service will
- * be sent through {@link #processNfcFPacket(byte[], Bundle)}, until the NFC link is
- * broken.<p>
- *
- * <p>When the NFC link is broken, {@link #onDeactivated(int)} will be called.</p>
- */
-public abstract class HostNfcFService extends Service {
- /**
- * The {@link Intent} action that must be declared as handled by the service.
- */
- @SdkConstant(SdkConstantType.SERVICE_ACTION)
- public static final String SERVICE_INTERFACE =
- "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
-
- /**
- * The name of the meta-data element that contains
- * more information about this service.
- */
- public static final String SERVICE_META_DATA =
- "android.nfc.cardemulation.host_nfcf_service";
-
- /**
- * Reason for {@link #onDeactivated(int)}.
- * Indicates deactivation was due to the NFC link
- * being lost.
- */
- public static final int DEACTIVATION_LINK_LOSS = 0;
-
- static final String TAG = "NfcFService";
-
- /**
- * MSG_COMMAND_PACKET is sent by NfcService when
- * a NFC-F command packet has been received.
- *
- * @hide
- */
- public static final int MSG_COMMAND_PACKET = 0;
-
- /**
- * MSG_RESPONSE_PACKET is sent to NfcService to send
- * a response packet back to the remote device.
- *
- * @hide
- */
- public static final int MSG_RESPONSE_PACKET = 1;
-
- /**
- * MSG_DEACTIVATED is sent by NfcService when
- * the current session is finished; because
- * the NFC link was deactivated.
- *
- * @hide
- */
- public static final int MSG_DEACTIVATED = 2;
-
- /**
- * @hide
- */
- public static final String KEY_DATA = "data";
-
- /**
- * @hide
- */
- public static final String KEY_MESSENGER = "messenger";
-
- /**
- * Messenger interface to NfcService for sending responses.
- * Only accessed on main thread by the message handler.
- *
- * @hide
- */
- Messenger mNfcService = null;
-
- final Messenger mMessenger = new Messenger(new MsgHandler());
-
- final class MsgHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_COMMAND_PACKET:
- Bundle dataBundle = msg.getData();
- if (dataBundle == null) {
- return;
- }
- if (mNfcService == null) mNfcService = msg.replyTo;
-
- byte[] packet = dataBundle.getByteArray(KEY_DATA);
- if (packet != null) {
- byte[] responsePacket = processNfcFPacket(packet, null);
- if (responsePacket != null) {
- if (mNfcService == null) {
- Log.e(TAG, "Response not sent; service was deactivated.");
- return;
- }
- Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
- Bundle responseBundle = new Bundle();
- responseBundle.putByteArray(KEY_DATA, responsePacket);
- responseMsg.setData(responseBundle);
- responseMsg.replyTo = mMessenger;
- try {
- mNfcService.send(responseMsg);
- } catch (RemoteException e) {
- Log.e("TAG", "Response not sent; RemoteException calling into " +
- "NfcService.");
- }
- }
- } else {
- Log.e(TAG, "Received MSG_COMMAND_PACKET without data.");
- }
- break;
- case MSG_RESPONSE_PACKET:
- if (mNfcService == null) {
- Log.e(TAG, "Response not sent; service was deactivated.");
- return;
- }
- try {
- msg.replyTo = mMessenger;
- mNfcService.send(msg);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling into NfcService.");
- }
- break;
- case MSG_DEACTIVATED:
- // Make sure we won't call into NfcService again
- mNfcService = null;
- onDeactivated(msg.arg1);
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
-
- @Override
- public final IBinder onBind(Intent intent) {
- return mMessenger.getBinder();
- }
-
- /**
- * Sends a response packet back to the remote device.
- *
- * <p>Note: this method may be called from any thread and will not block.
- * @param responsePacket A byte-array containing the response packet.
- */
- public final void sendResponsePacket(byte[] responsePacket) {
- Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
- Bundle dataBundle = new Bundle();
- dataBundle.putByteArray(KEY_DATA, responsePacket);
- responseMsg.setData(dataBundle);
- try {
- mMessenger.send(responseMsg);
- } catch (RemoteException e) {
- Log.e("TAG", "Local messenger has died.");
- }
- }
-
- /**
- * <p>This method will be called when a NFC-F packet has been received
- * from a remote device. A response packet can be provided directly
- * by returning a byte-array in this method. Note that in general
- * response packets must be sent as quickly as possible, given the fact
- * that the user is likely holding their device over an NFC reader
- * when this method is called.
- *
- * <p class="note">This method is running on the main thread of your application.
- * If you cannot return a response packet immediately, return null
- * and use the {@link #sendResponsePacket(byte[])} method later.
- *
- * @param commandPacket The NFC-F packet that was received from the remote device
- * @param extras A bundle containing extra data. May be null.
- * @return a byte-array containing the response packet, or null if no
- * response packet can be sent at this point.
- */
- public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras);
-
- /**
- * This method will be called in following possible scenarios:
- * <li>The NFC link has been lost
- * @param reason {@link #DEACTIVATION_LINK_LOSS}
- */
- public abstract void onDeactivated(int reason);
-}
diff --git a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java b/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
deleted file mode 100644
index 48bbf5b61052..000000000000
--- a/nfc/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.nfc.INfcFCardEmulation;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * This class can be used to query the state of
- * NFC-F card emulation services.
- *
- * For a general introduction into NFC card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide</a>.</p>
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION_NFCF}
- * to be present on the device.
- */
-public final class NfcFCardEmulation {
- static final String TAG = "NfcFCardEmulation";
-
- static boolean sIsInitialized = false;
- static HashMap<Context, NfcFCardEmulation> sCardEmus = new HashMap<Context, NfcFCardEmulation>();
- static INfcFCardEmulation sService;
-
- final Context mContext;
-
- private NfcFCardEmulation(Context context, INfcFCardEmulation service) {
- mContext = context.getApplicationContext();
- sService = service;
- }
-
- /**
- * Helper to get an instance of this class.
- *
- * @param adapter A reference to an NfcAdapter object.
- * @return
- */
- public static synchronized NfcFCardEmulation getInstance(NfcAdapter adapter) {
- if (adapter == null) throw new NullPointerException("NfcAdapter is null");
- Context context = adapter.getContext();
- if (context == null) {
- Log.e(TAG, "NfcAdapter context is null.");
- throw new UnsupportedOperationException();
- }
- if (!sIsInitialized) {
- PackageManager pm = context.getPackageManager();
- if (pm == null) {
- Log.e(TAG, "Cannot get PackageManager");
- throw new UnsupportedOperationException();
- }
- if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
- Log.e(TAG, "This device does not support NFC-F card emulation");
- throw new UnsupportedOperationException();
- }
- sIsInitialized = true;
- }
- NfcFCardEmulation manager = sCardEmus.get(context);
- if (manager == null) {
- // Get card emu service
- INfcFCardEmulation service = adapter.getNfcFCardEmulationService();
- if (service == null) {
- Log.e(TAG, "This device does not implement the INfcFCardEmulation interface.");
- throw new UnsupportedOperationException();
- }
- manager = new NfcFCardEmulation(context, service);
- sCardEmus.put(context, manager);
- }
- return manager;
- }
-
- /**
- * Retrieves the current System Code for the specified service.
- *
- * <p>Before calling {@link #registerSystemCodeForService(ComponentName, String)},
- * the System Code contained in the Manifest file is returned. After calling
- * {@link #registerSystemCodeForService(ComponentName, String)}, the System Code
- * registered there is returned. After calling
- * {@link #unregisterSystemCodeForService(ComponentName)}, "null" is returned.
- *
- * @param service The component name of the service
- * @return the current System Code
- */
- public String getSystemCodeForService(ComponentName service) throws RuntimeException {
- if (service == null) {
- throw new NullPointerException("service is null");
- }
- try {
- return sService.getSystemCodeForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- return sService.getSystemCodeForService(mContext.getUser().getIdentifier(),
- service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return null;
- }
- }
- }
-
- /**
- * Registers a System Code for the specified service.
- *
- * <p>The System Code must be in range from "4000" to "4FFF" (excluding "4*FF").
- *
- * <p>If a System Code was previously registered for this service
- * (either statically through the manifest, or dynamically by using this API),
- * it will be replaced with this one.
- *
- * <p>Even if the same System Code is already registered for another service,
- * this method succeeds in registering the System Code.
- *
- * <p>Note that you can only register a System Code for a service that
- * is running under the same UID as the caller of this API. Typically
- * this means you need to call this from the same
- * package as the service itself, though UIDs can also
- * be shared between packages using shared UIDs.
- *
- * @param service The component name of the service
- * @param systemCode The System Code to be registered
- * @return whether the registration was successful.
- */
- public boolean registerSystemCodeForService(ComponentName service, String systemCode)
- throws RuntimeException {
- if (service == null || systemCode == null) {
- throw new NullPointerException("service or systemCode is null");
- }
- try {
- return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
- service, systemCode);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.registerSystemCodeForService(mContext.getUser().getIdentifier(),
- service, systemCode);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return false;
- }
- }
- }
-
- /**
- * Removes a registered System Code for the specified service.
- *
- * @param service The component name of the service
- * @return whether the System Code was successfully removed.
- */
- public boolean unregisterSystemCodeForService(ComponentName service) throws RuntimeException {
- if (service == null) {
- throw new NullPointerException("service is null");
- }
- try {
- return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.removeSystemCodeForService(mContext.getUser().getIdentifier(),
- service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return false;
- }
- }
- }
-
- /**
- * Retrieves the current NFCID2 for the specified service.
- *
- * <p>Before calling {@link #setNfcid2ForService(ComponentName, String)},
- * the NFCID2 contained in the Manifest file is returned. If "random" is specified
- * in the Manifest file, a random number assigned by the system at installation time
- * is returned. After setting an NFCID2
- * with {@link #setNfcid2ForService(ComponentName, String)}, this NFCID2 is returned.
- *
- * @param service The component name of the service
- * @return the current NFCID2
- */
- public String getNfcid2ForService(ComponentName service) throws RuntimeException {
- if (service == null) {
- throw new NullPointerException("service is null");
- }
- try {
- return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- return sService.getNfcid2ForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return null;
- }
- }
- }
-
- /**
- * Set a NFCID2 for the specified service.
- *
- * <p>The NFCID2 must be in range from "02FE000000000000" to "02FEFFFFFFFFFFFF".
- *
- * <p>If a NFCID2 was previously set for this service
- * (either statically through the manifest, or dynamically by using this API),
- * it will be replaced.
- *
- * <p>Note that you can only set the NFCID2 for a service that
- * is running under the same UID as the caller of this API. Typically
- * this means you need to call this from the same
- * package as the service itself, though UIDs can also
- * be shared between packages using shared UIDs.
- *
- * @param service The component name of the service
- * @param nfcid2 The NFCID2 to be registered
- * @return whether the setting was successful.
- */
- public boolean setNfcid2ForService(ComponentName service, String nfcid2)
- throws RuntimeException {
- if (service == null || nfcid2 == null) {
- throw new NullPointerException("service or nfcid2 is null");
- }
- try {
- return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
- service, nfcid2);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setNfcid2ForService(mContext.getUser().getIdentifier(),
- service, nfcid2);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return false;
- }
- }
- }
-
- /**
- * Allows a foreground application to specify which card emulation service
- * should be enabled while a specific Activity is in the foreground.
- *
- * <p>The specified HCE-F service is only enabled when the corresponding application is
- * in the foreground and this method has been called. When the application is moved to
- * the background, {@link #disableService(Activity)} is called, or
- * NFCID2 or System Code is replaced, the HCE-F service is disabled.
- *
- * <p>The specified Activity must currently be in resumed state. A good
- * paradigm is to call this method in your {@link Activity#onResume}, and to call
- * {@link #disableService(Activity)} in your {@link Activity#onPause}.
- *
- * <p>Note that this preference is not persisted by the OS, and hence must be
- * called every time the Activity is resumed.
- *
- * @param activity The activity which prefers this service to be invoked
- * @param service The service to be preferred while this activity is in the foreground
- * @return whether the registration was successful
- */
- public boolean enableService(Activity activity, ComponentName service) throws RuntimeException {
- if (activity == null || service == null) {
- throw new NullPointerException("activity or service is null");
- }
- // Verify the activity is in the foreground before calling into NfcService
- if (!activity.isResumed()) {
- throw new IllegalArgumentException("Activity must be resumed.");
- }
- try {
- return sService.enableNfcFForegroundService(service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.enableNfcFForegroundService(service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return false;
- }
- }
- }
-
- /**
- * Disables the service for the specified Activity.
- *
- * <p>Note that the specified Activity must still be in resumed
- * state at the time of this call. A good place to call this method
- * is in your {@link Activity#onPause} implementation.
- *
- * @param activity The activity which the service was registered for
- * @return true when successful
- */
- public boolean disableService(Activity activity) throws RuntimeException {
- if (activity == null) {
- throw new NullPointerException("activity is null");
- }
- if (!activity.isResumed()) {
- throw new IllegalArgumentException("Activity must be resumed.");
- }
- try {
- return sService.disableNfcFForegroundService();
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.disableNfcFForegroundService();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- ee.rethrowAsRuntimeException();
- return false;
- }
- }
- }
-
- /**
- * @hide
- */
- public List<NfcFServiceInfo> getNfcFServices() {
- try {
- return sService.getNfcFServices(mContext.getUser().getIdentifier());
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- return sService.getNfcFServices(mContext.getUser().getIdentifier());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return null;
- }
- }
- }
-
- /**
- * @hide
- */
- public int getMaxNumOfRegisterableSystemCodes() {
- try {
- return sService.getMaxNumOfRegisterableSystemCodes();
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return -1;
- }
- try {
- return sService.getMaxNumOfRegisterableSystemCodes();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return -1;
- }
- }
- }
-
- /**
- * @hide
- */
- public static boolean isValidSystemCode(String systemCode) {
- if (systemCode == null) {
- return false;
- }
- if (systemCode.length() != 4) {
- Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
- return false;
- }
- // check if the value is between "4000" and "4FFF" (excluding "4*FF")
- if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
- Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
- return false;
- }
- try {
- Integer.parseInt(systemCode, 16);
- } catch (NumberFormatException e) {
- Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
- return false;
- }
- return true;
- }
-
- /**
- * @hide
- */
- public static boolean isValidNfcid2(String nfcid2) {
- if (nfcid2 == null) {
- return false;
- }
- if (nfcid2.length() != 16) {
- Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
- return false;
- }
- // check if the the value starts with "02FE"
- if (!nfcid2.toUpperCase().startsWith("02FE")) {
- Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
- return false;
- }
- try {
- Long.parseLong(nfcid2, 16);
- } catch (NumberFormatException e) {
- Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
- return false;
- }
- return true;
- }
-
- void recoverService() {
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
- sService = adapter.getNfcFCardEmulationService();
- }
-
-}
-
diff --git a/nfc/java/android/nfc/cardemulation/OWNERS b/nfc/java/android/nfc/cardemulation/OWNERS
deleted file mode 100644
index 35e9713f5715..000000000000
--- a/nfc/java/android/nfc/cardemulation/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/java/android/nfc/cardemulation/OffHostApduService.java b/nfc/java/android/nfc/cardemulation/OffHostApduService.java
deleted file mode 100644
index 8d8a17270523..000000000000
--- a/nfc/java/android/nfc/cardemulation/OffHostApduService.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.IBinder;
-
-/**
- * <p>OffHostApduService is a convenience {@link Service} class that can be
- * extended to describe one or more NFC applications that are residing
- * off-host, for example on an embedded secure element or a UICC.
- *
- * <div class="special reference">
- * <h3>Developer Guide</h3>
- * For a general introduction into the topic of card emulation,
- * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
- * NFC card emulation developer guide.</a></p>
- * </div>
- *
- * <h3>NFC Protocols</h3>
- * <p>Off-host applications represented by this class are based on the NFC-Forum ISO-DEP
- * protocol (based on ISO/IEC 14443-4) and support processing
- * command Application Protocol Data Units (APDUs) as
- * defined in the ISO/IEC 7816-4 specification.
- *
- * <h3>Service selection</h3>
- * <p>When a remote NFC device wants to talk to your
- * off-host NFC application, it sends a so-called
- * "SELECT AID" APDU as defined in the ISO/IEC 7816-4 specification.
- * The AID is an application identifier defined in ISO/IEC 7816-4.
- *
- * <p>The registration procedure for AIDs is defined in the
- * ISO/IEC 7816-5 specification. If you don't want to register an
- * AID, you are free to use AIDs in the proprietary range:
- * bits 8-5 of the first byte must each be set to '1'. For example,
- * "0xF00102030405" is a proprietary AID. If you do use proprietary
- * AIDs, it is recommended to choose an AID of at least 6 bytes,
- * to reduce the risk of collisions with other applications that
- * might be using proprietary AIDs as well.
- *
- * <h3>AID groups</h3>
- * <p>In some cases, an off-host environment may need to register multiple AIDs
- * to implement a certain application, and it needs to be sure
- * that it is the default handler for all of these AIDs (as opposed
- * to some AIDs in the group going to another service).
- *
- * <p>An AID group is a list of AIDs that should be considered as
- * belonging together by the OS. For all AIDs in an AID group, the
- * OS will guarantee one of the following:
- * <ul>
- * <li>All AIDs in the group are routed to the off-host execution environment
- * <li>No AIDs in the group are routed to the off-host execution environment
- * </ul>
- * In other words, there is no in-between state, where some AIDs
- * in the group can be routed to this off-host execution environment,
- * and some to another or a host-based {@link HostApduService}.
- * <h3>AID groups and categories</h3>
- * <p>Each AID group can be associated with a category. This allows
- * the Android OS to classify services, and it allows the user to
- * set defaults at the category level instead of the AID level.
- *
- * <p>You can use
- * {@link CardEmulation#isDefaultServiceForCategory(android.content.ComponentName, String)}
- * to determine if your off-host service is the default handler for a category.
- *
- * <p>In this version of the platform, the only known categories
- * are {@link CardEmulation#CATEGORY_PAYMENT} and {@link CardEmulation#CATEGORY_OTHER}.
- * AID groups without a category, or with a category that is not recognized
- * by the current platform version, will automatically be
- * grouped into the {@link CardEmulation#CATEGORY_OTHER} category.
- *
- * <h3>Service AID registration</h3>
- * <p>To tell the platform which AIDs
- * reside off-host and are managed by this service, a {@link #SERVICE_META_DATA}
- * entry must be included in the declaration of the service. An
- * example of a OffHostApduService manifest declaration is shown below:
- * <pre> &lt;service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/&gt;
- * &lt;/intent-filter&gt;
- * &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/&gt;
- * &lt;/service&gt;</pre>
- *
- * This meta-data tag points to an apduservice.xml file.
- * An example of this file with a single AID group declaration is shown below:
- * <pre>
- * &lt;offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
- * android:description="@string/servicedesc"&gt;
- * &lt;aid-group android:description="@string/subscription" android:category="other">
- * &lt;aid-filter android:name="F0010203040506"/&gt;
- * &lt;aid-filter android:name="F0394148148100"/&gt;
- * &lt;/aid-group&gt;
- * &lt;/offhost-apdu-service&gt;
- * </pre>
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} is required
- * to contain a
- * {@link android.R.styleable#OffHostApduService_description &lt;android:description&gt;}
- * attribute that contains a user-friendly description of the service that may be shown in UI.
- *
- * <p>The {@link android.R.styleable#OffHostApduService &lt;offhost-apdu-service&gt;} must
- * contain one or more {@link android.R.styleable#AidGroup &lt;aid-group&gt;} tags.
- * Each {@link android.R.styleable#AidGroup &lt;aid-group&gt;} must contain one or
- * more {@link android.R.styleable#AidFilter &lt;aid-filter&gt;} tags, each of which
- * contains a single AID. The AID must be specified in hexadecimal format, and contain
- * an even number of characters.
- *
- * <p>This registration will allow the service to be included
- * as an option for being the default handler for categories.
- * The Android OS will take care of correctly
- * routing the AIDs to the off-host execution environment,
- * based on which service the user has selected to be the handler for a certain category.
- *
- * <p>The service may define additional actions outside of the
- * Android namespace that provide further interaction with
- * the off-host execution environment.
- *
- * <p class="note">Use of this class requires the
- * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION} to be present
- * on the device.
- */
-public abstract class OffHostApduService extends Service {
- /**
- * The {@link Intent} action that must be declared as handled by the service.
- */
- @SdkConstant(SdkConstantType.SERVICE_ACTION)
- public static final String SERVICE_INTERFACE =
- "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
-
- /**
- * The name of the meta-data element that contains
- * more information about this service.
- */
- public static final String SERVICE_META_DATA =
- "android.nfc.cardemulation.off_host_apdu_service";
-
- /**
- * The Android platform itself will not bind to this service,
- * but merely uses its declaration to keep track of what AIDs
- * the service is interested in. This information is then used
- * to present the user with a list of applications that can handle
- * an AID, as well as correctly route those AIDs either to the host (in case
- * the user preferred a {@link HostApduService}), or to an off-host
- * execution environment (in case the user preferred a {@link OffHostApduService}.
- *
- * Implementers may define additional actions outside of the
- * Android namespace that allow further interactions with
- * the off-host execution environment. Such implementations
- * would need to override this method.
- */
- public abstract IBinder onBind(Intent intent);
-}
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl b/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
deleted file mode 100644
index 8e09f8baaff2..000000000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-parcelable PollingFrame; \ No newline at end of file
diff --git a/nfc/java/android/nfc/cardemulation/PollingFrame.java b/nfc/java/android/nfc/cardemulation/PollingFrame.java
deleted file mode 100644
index 5dcc84ccf8b9..000000000000
--- a/nfc/java/android/nfc/cardemulation/PollingFrame.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.FlaggedApi;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HexFormat;
-import java.util.List;
-
-/**
- * Polling Frames represent data about individual frames of an NFC polling loop. These frames will
- * be delivered to subclasses of {@link HostApduService} that have registered filters with
- * {@link CardEmulation#registerPollingLoopFilterForService(ComponentName, String, boolean)} that
- * match a given frame in a loop and will be delivered through calls to
- * {@link HostApduService#processPollingFrames(List)}.
- */
-@FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
-public final class PollingFrame implements Parcelable {
-
- /**
- * @hide
- */
- @IntDef(prefix = { "POLLING_LOOP_TYPE_"},
- value = {
- POLLING_LOOP_TYPE_A,
- POLLING_LOOP_TYPE_B,
- POLLING_LOOP_TYPE_F,
- POLLING_LOOP_TYPE_OFF,
- POLLING_LOOP_TYPE_ON,
- POLLING_LOOP_TYPE_UNKNOWN
- })
- @Retention(RetentionPolicy.SOURCE)
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public @interface PollingFrameType {}
-
- /**
- * POLLING_LOOP_TYPE_A is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop is for NFC-A.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_A = 'A';
-
- /**
- * POLLING_LOOP_TYPE_B is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop is for NFC-B.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_B = 'B';
-
- /**
- * POLLING_LOOP_TYPE_F is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop is for NFC-F.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_F = 'F';
-
- /**
- * POLLING_LOOP_TYPE_ON is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop turns on.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_ON = 'O';
-
- /**
- * POLLING_LOOP_TYPE_OFF is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop turns off.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_OFF = 'X';
-
- /**
- * POLLING_LOOP_TYPE_UNKNOWN is the value associated with the key
- * POLLING_LOOP_TYPE in the Bundle passed to {@link HostApduService#processPollingFrames(List)}
- * when the polling loop frame isn't recognized.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- public static final int POLLING_LOOP_TYPE_UNKNOWN = 'U';
-
- /**
- * KEY_POLLING_LOOP_TYPE is the Bundle key for the type of
- * polling loop frame in the Bundle included in MSG_POLLING_LOOP.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- private static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE";
-
- /**
- * KEY_POLLING_LOOP_DATA is the Bundle key for the raw data of captured from
- * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- private static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA";
-
- /**
- * KEY_POLLING_LOOP_GAIN is the Bundle key for the field strength of
- * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- private static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN";
-
- /**
- * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for the timestamp of
- * the polling loop frame in the Bundle included in MSG_POLLING_LOOP.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- private static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP";
-
- /**
- * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for whether this polling frame triggered
- * autoTransact in the Bundle included in MSG_POLLING_LOOP.
- */
- @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
- private static final String KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT =
- "android.nfc.cardemulation.TRIGGERED_AUTOTRANSACT";
-
-
- @PollingFrameType
- private final int mType;
- private final byte[] mData;
- private final int mGain;
- private final long mTimestamp;
- private boolean mTriggeredAutoTransact;
-
- public static final @NonNull Parcelable.Creator<PollingFrame> CREATOR =
- new Parcelable.Creator<>() {
- @Override
- public PollingFrame createFromParcel(Parcel source) {
- return new PollingFrame(source.readBundle());
- }
-
- @Override
- public PollingFrame[] newArray(int size) {
- return new PollingFrame[size];
- }
- };
-
- private PollingFrame(Bundle frame) {
- mType = frame.getInt(KEY_POLLING_LOOP_TYPE);
- byte[] data = frame.getByteArray(KEY_POLLING_LOOP_DATA);
- mData = (data == null) ? new byte[0] : data;
- mGain = frame.getInt(KEY_POLLING_LOOP_GAIN, -1);
- mTimestamp = frame.getLong(KEY_POLLING_LOOP_TIMESTAMP);
- mTriggeredAutoTransact = frame.containsKey(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT)
- && frame.getBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT);
- }
-
- /**
- * Constructor for Polling Frames.
- *
- * @param type the type of the frame
- * @param data a byte array of the data contained in the frame
- * @param gain the vendor-specific gain of the field
- * @param timestampMicros the timestamp in microseconds
- * @param triggeredAutoTransact whether or not this frame triggered the device to start a
- * transaction automatically
- *
- * @hide
- */
- public PollingFrame(@PollingFrameType int type, @Nullable byte[] data,
- int gain, long timestampMicros, boolean triggeredAutoTransact) {
- mType = type;
- mData = data == null ? new byte[0] : data;
- mGain = gain;
- mTimestamp = timestampMicros;
- mTriggeredAutoTransact = triggeredAutoTransact;
- }
-
- /**
- * Returns the type of frame for this polling loop frame.
- * The possible return values are:
- * <ul>
- * <li>{@link #POLLING_LOOP_TYPE_ON}</li>
- * <li>{@link #POLLING_LOOP_TYPE_OFF}</li>
- * <li>{@link #POLLING_LOOP_TYPE_A}</li>
- * <li>{@link #POLLING_LOOP_TYPE_B}</li>
- * <li>{@link #POLLING_LOOP_TYPE_F}</li>
- * </ul>
- */
- public @PollingFrameType int getType() {
- return mType;
- }
-
- /**
- * Returns the raw data from the polling type frame.
- */
- public @NonNull byte[] getData() {
- return mData;
- }
-
- /**
- * Returns the gain representing the field strength of the NFC field when this polling loop
- * frame was observed.
- * @return the gain or -1 if there is no gain measurement associated with this frame.
- */
- public int getVendorSpecificGain() {
- return mGain;
- }
-
- /**
- * Returns the timestamp of when the polling loop frame was observed, in microseconds. These
- * timestamps are relative and should only be used for comparing the timing of frames relative
- * to each other.
- * @return the timestamp in microseconds
- */
- public long getTimestamp() {
- return mTimestamp;
- }
-
- /**
- * @hide
- */
- public void setTriggeredAutoTransact(boolean triggeredAutoTransact) {
- mTriggeredAutoTransact = triggeredAutoTransact;
- }
-
- /**
- * Returns whether this frame triggered the device to automatically disable observe mode and
- * allow one transaction.
- */
- public boolean getTriggeredAutoTransact() {
- return mTriggeredAutoTransact;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeBundle(toBundle());
- }
-
- /**
- * @return a Bundle representing this frame
- */
- private Bundle toBundle() {
- Bundle frame = new Bundle();
- frame.putInt(KEY_POLLING_LOOP_TYPE, getType());
- if (getVendorSpecificGain() != -1) {
- frame.putInt(KEY_POLLING_LOOP_GAIN, (byte) getVendorSpecificGain());
- }
- frame.putByteArray(KEY_POLLING_LOOP_DATA, getData());
- frame.putLong(KEY_POLLING_LOOP_TIMESTAMP, getTimestamp());
- frame.putBoolean(KEY_POLLING_LOOP_TRIGGERED_AUTOTRANSACT, getTriggeredAutoTransact());
- return frame;
- }
-
- @Override
- public String toString() {
- return "PollingFrame { Type: " + (char) getType()
- + ", gain: " + getVendorSpecificGain()
- + ", timestamp: " + Long.toUnsignedString(getTimestamp())
- + ", data: [" + HexFormat.ofDelimiter(" ").formatHex(getData()) + "] }";
- }
-}
diff --git a/nfc/java/android/nfc/cardemulation/Utils.java b/nfc/java/android/nfc/cardemulation/Utils.java
deleted file mode 100644
index 202e1cfb48f6..000000000000
--- a/nfc/java/android/nfc/cardemulation/Utils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.cardemulation;
-
-import android.annotation.NonNull;
-import android.content.ComponentName;
-import android.content.ComponentNameProto;
-import android.util.proto.ProtoOutputStream;
-
-/** @hide */
-public final class Utils {
- private Utils() {
- }
-
- /** Copied from {@link ComponentName#dumpDebug(ProtoOutputStream, long)} */
- public static void dumpDebugComponentName(
- @NonNull ComponentName componentName, @NonNull ProtoOutputStream proto, long fieldId) {
- final long token = proto.start(fieldId);
- proto.write(ComponentNameProto.PACKAGE_NAME, componentName.getPackageName());
- proto.write(ComponentNameProto.CLASS_NAME, componentName.getClassName());
- proto.end(token);
- }
-}
diff --git a/nfc/java/android/nfc/dta/NfcDta.java b/nfc/java/android/nfc/dta/NfcDta.java
deleted file mode 100644
index 88016623434d..000000000000
--- a/nfc/java/android/nfc/dta/NfcDta.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.dta;
-
-import android.content.Context;
-import android.nfc.INfcDta;
-import android.nfc.NfcAdapter;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.HashMap;
-
-/**
- * This class provides the primary API for DTA operations.
- * @hide
- */
-public final class NfcDta {
- private static final String TAG = "NfcDta";
-
- private static INfcDta sService;
- private static HashMap<Context, NfcDta> sNfcDtas = new HashMap<Context, NfcDta>();
-
- private final Context mContext;
-
- private NfcDta(Context context, INfcDta service) {
- mContext = context.getApplicationContext();
- sService = service;
- }
-
- /**
- * Helper to get an instance of this class.
- *
- * @param adapter A reference to an NfcAdapter object.
- * @return
- */
- public static synchronized NfcDta getInstance(NfcAdapter adapter) {
- if (adapter == null) throw new NullPointerException("NfcAdapter is null");
- Context context = adapter.getContext();
- if (context == null) {
- Log.e(TAG, "NfcAdapter context is null.");
- throw new UnsupportedOperationException();
- }
-
- NfcDta manager = sNfcDtas.get(context);
- if (manager == null) {
- INfcDta service = adapter.getNfcDtaInterface();
- if (service == null) {
- Log.e(TAG, "This device does not implement the INfcDta interface.");
- throw new UnsupportedOperationException();
- }
- manager = new NfcDta(context, service);
- sNfcDtas.put(context, manager);
- }
- return manager;
- }
-
- /**
- * Enables DTA mode
- *
- * @return true/false if enabling was successful
- */
- public boolean enableDta() {
- try {
- sService.enableDta();
- } catch (RemoteException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Disables DTA mode
- *
- * @return true/false if disabling was successful
- */
- public boolean disableDta() {
- try {
- sService.disableDta();
- } catch (RemoteException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Enables Server
- *
- * @return true/false if enabling was successful
- */
- public boolean enableServer(String serviceName, int serviceSap, int miu,
- int rwSize, int testCaseId) {
- try {
- return sService.enableServer(serviceName, serviceSap, miu, rwSize, testCaseId);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Disables Server
- *
- * @return true/false if disabling was successful
- */
- public boolean disableServer() {
- try {
- sService.disableServer();
- } catch (RemoteException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Enables Client
- *
- * @return true/false if enabling was successful
- */
- public boolean enableClient(String serviceName, int miu, int rwSize,
- int testCaseId) {
- try {
- return sService.enableClient(serviceName, miu, rwSize, testCaseId);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Disables client
- *
- * @return true/false if disabling was successful
- */
- public boolean disableClient() {
- try {
- sService.disableClient();
- } catch (RemoteException e) {
- return false;
- }
- return true;
- }
-
- /**
- * Registers Message Service
- *
- * @return true/false if registration was successful
- */
- public boolean registerMessageService(String msgServiceName) {
- try {
- return sService.registerMessageService(msgServiceName);
- } catch (RemoteException e) {
- return false;
- }
- }
-}
diff --git a/nfc/java/android/nfc/dta/OWNERS b/nfc/java/android/nfc/dta/OWNERS
deleted file mode 100644
index 35e9713f5715..000000000000
--- a/nfc/java/android/nfc/dta/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/java/android/nfc/package.html b/nfc/java/android/nfc/package.html
deleted file mode 100644
index 55c1d1650aa9..000000000000
--- a/nfc/java/android/nfc/package.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<HTML>
-<BODY>
-<p>Provides access to Near Field Communication (NFC) functionality, allowing applications to read
-NDEF message in NFC tags. A "tag" may actually be another device that appears as a tag.</p>
-
-<p>For more information, see the
-<a href="{@docRoot}guide/topics/connectivity/nfc/index.html">Near Field Communication</a> guide.</p>
-{@more}
-
-<p>Here's a summary of the classes:</p>
-
-<dl>
- <dt>{@link android.nfc.NfcManager}</dt>
- <dd>This is the high level manager, used to obtain this device's {@link android.nfc.NfcAdapter}. You can
-acquire an instance using {@link android.content.Context#getSystemService}.</dd>
- <dt>{@link android.nfc.NfcAdapter}</dt>
- <dd>This represents the device's NFC adapter, which is your entry-point to performing NFC
-operations. You can acquire an instance with {@link android.nfc.NfcManager#getDefaultAdapter}, or
-{@link android.nfc.NfcAdapter#getDefaultAdapter(android.content.Context)}.</dd>
- <dt>{@link android.nfc.NdefMessage}</dt>
- <dd>Represents an NDEF data message, which is the standard format in which "records"
-carrying data are transmitted between devices and tags. Your application can receive these
-messages from an {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED} intent.</dd>
- <dt>{@link android.nfc.NdefRecord}</dt>
- <dd>Represents a record, which is delivered in a {@link android.nfc.NdefMessage} and describes the
-type of data being shared and carries the data itself.</dd>
-</dl>
-
-<p class="note"><strong>Note:</strong>
-Not all Android-powered devices provide NFC functionality.</p>
-
-</BODY>
-</HTML>
diff --git a/nfc/java/android/nfc/tech/BasicTagTechnology.java b/nfc/java/android/nfc/tech/BasicTagTechnology.java
deleted file mode 100644
index ae468fead7a2..000000000000
--- a/nfc/java/android/nfc/tech/BasicTagTechnology.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TransceiveResult;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * A base class for tag technologies that are built on top of transceive().
- */
-abstract class BasicTagTechnology implements TagTechnology {
- private static final String TAG = "NFC";
-
- final Tag mTag;
-
- boolean mIsConnected;
- int mSelectedTechnology;
-
- BasicTagTechnology(Tag tag, int tech) throws RemoteException {
- mTag = tag;
- mSelectedTechnology = tech;
- }
-
- @Override
- public Tag getTag() {
- return mTag;
- }
-
- /** Internal helper to throw IllegalStateException if the technology isn't connected */
- void checkConnected() {
- if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
- (mTag.getConnectedTechnology() == -1)) {
- throw new IllegalStateException("Call connect() first!");
- }
- }
-
- @Override
- public boolean isConnected() {
- if (!mIsConnected) {
- return false;
- }
-
- try {
- return mTag.getTagService().isPresent(mTag.getServiceHandle());
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return false;
- }
- }
-
- @Override
- public void connect() throws IOException {
- try {
- int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
- mSelectedTechnology);
-
- if (errorCode == ErrorCodes.SUCCESS) {
- // Store this in the tag object
- if (!mTag.setConnectedTechnology(mSelectedTechnology)) {
- Log.e(TAG, "Close other technology first!");
- throw new IOException("Only one TagTechnology can be connected at a time.");
- }
- mIsConnected = true;
- } else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) {
- throw new UnsupportedOperationException("Connecting to " +
- "this technology is not supported by the NFC " +
- "adapter.");
- } else {
- throw new IOException();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- throw new IOException("NFC service died");
- }
- }
-
- /** @hide */
- @Override
- public void reconnect() throws IOException {
- if (!mIsConnected) {
- throw new IllegalStateException("Technology not connected yet");
- }
-
- try {
- int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle());
-
- if (errorCode != ErrorCodes.SUCCESS) {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- throw new IOException();
- }
- } catch (RemoteException e) {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- Log.e(TAG, "NFC service dead", e);
- throw new IOException("NFC service died");
- }
- }
-
- @Override
- public void close() throws IOException {
- try {
- /* Note that we don't want to physically disconnect the tag,
- * but just reconnect to it to reset its state
- */
- mTag.getTagService().resetTimeouts();
- mTag.getTagService().reconnect(mTag.getServiceHandle());
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- } finally {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- }
- }
-
- /** Internal getMaxTransceiveLength() */
- int getMaxTransceiveLengthInternal() {
- try {
- return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
- /** Internal transceive */
- byte[] transceive(byte[] data, boolean raw) throws IOException {
- checkConnected();
-
- try {
- TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
- data, raw);
- if (result == null) {
- throw new IOException("transceive failed");
- } else {
- return result.getResponseOrThrow();
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- throw new IOException("NFC service died");
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/IsoDep.java b/nfc/java/android/nfc/tech/IsoDep.java
deleted file mode 100644
index 0ba0c5a8d13b..000000000000
--- a/nfc/java/android/nfc/tech/IsoDep.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire an {@link IsoDep} object using {@link #get}.
- * <p>The primary ISO-DEP I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- * <p>Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList}
- * will also enumerate
- * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these).
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class IsoDep extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /** @hide */
- public static final String EXTRA_HI_LAYER_RESP = "hiresp";
- /** @hide */
- public static final String EXTRA_HIST_BYTES = "histbytes";
-
- private byte[] mHiLayerResponse = null;
- private byte[] mHistBytes = null;
-
- /**
- * Get an instance of {@link IsoDep} for the given tag.
- * <p>Does not cause any RF activity and does not block.
- * <p>Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag does not support ISO-DEP.
- *
- * @param tag an ISO-DEP compatible tag
- * @return ISO-DEP object
- */
- public static IsoDep get(Tag tag) {
- if (!tag.hasTech(TagTechnology.ISO_DEP)) return null;
- try {
- return new IsoDep(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public IsoDep(Tag tag)
- throws RemoteException {
- super(tag, TagTechnology.ISO_DEP);
- Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP);
- if (extras != null) {
- mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
- mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
- }
- }
-
- /**
- * Set the timeout of {@link #transceive} in milliseconds.
- * <p>The timeout only applies to ISO-DEP {@link #transceive}, and is
- * reset to a default value when {@link #close} is called.
- * <p>Setting a longer timeout may be useful when performing
- * transactions that require a long processing time on the tag
- * such as key generation.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param timeout timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void setTimeout(int timeout) {
- try {
- int err = mTag.getTagService().setTimeout(TagTechnology.ISO_DEP, timeout);
- if (err != ErrorCodes.SUCCESS) {
- throw new IllegalArgumentException("The supplied timeout is not valid");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Get the current timeout for {@link #transceive} in milliseconds.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public int getTimeout() {
- try {
- return mTag.getTagService().getTimeout(TagTechnology.ISO_DEP);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
-
- /**
- * Return the ISO-DEP historical bytes for {@link NfcA} tags.
- * <p>Does not cause any RF activity and does not block.
- * <p>The historical bytes can be used to help identify a tag. They are present
- * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology.
- * If this tag is not {@link NfcA} then null is returned.
- * <p>In ISO 14443-4 terminology, the historical bytes are a subset of the RATS
- * response.
- *
- * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag
- */
- public byte[] getHistoricalBytes() {
- return mHistBytes;
- }
-
- /**
- * Return the higher layer response bytes for {@link NfcB} tags.
- * <p>Does not cause any RF activity and does not block.
- * <p>The higher layer response bytes can be used to help identify a tag.
- * They are present only on {@link IsoDep} tags that are based on {@link NfcB}
- * RF technology. If this tag is not {@link NfcB} then null is returned.
- * <p>In ISO 14443-4 terminology, the higher layer bytes are a subset of the
- * ATTRIB response.
- *
- * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag
- */
- public byte[] getHiLayerResponse() {
- return mHiLayerResponse;
- }
-
- /**
- * Send raw ISO-DEP data to the tag and receive the response.
- *
- * <p>Applications must only send the INF payload, and not the start of frame and
- * end of frame indicators. Applications do not need to fragment the payload, it
- * will be automatically fragmented and defragmented by {@link #transceive} if
- * it exceeds FSD/FSC limits.
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param data command bytes to send, must not be null
- * @return response bytes received, will not be null
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or this operation is canceled
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-
- /**
- * <p>Standard APDUs have a 1-byte length field, allowing a maximum of
- * 255 payload bytes, which results in a maximum APDU length of 261 bytes.
- *
- * <p>Extended length APDUs have a 3-byte length field, allowing 65535
- * payload bytes.
- *
- * <p>Some NFC adapters, like the one used in the Nexus S and the Galaxy Nexus
- * do not support extended length APDUs. They are expected to be well-supported
- * in the future though. Use this method to check for extended length APDU
- * support.
- *
- * @return whether the NFC adapter on this device supports extended length APDUs.
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public boolean isExtendedLengthApduSupported() {
- try {
- return mTag.getTagService().getExtendedLengthApdusSupported();
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return false;
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/MifareClassic.java b/nfc/java/android/nfc/tech/MifareClassic.java
deleted file mode 100644
index 26f54e692289..000000000000
--- a/nfc/java/android/nfc/tech/MifareClassic.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-/**
- * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareClassic} object using {@link #get}.
- *
- * <p>MIFARE Classic is also known as MIFARE Standard.
- * <p>MIFARE Classic tags are divided into sectors, and each sector is sub-divided into
- * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies.
- * <ul>
- * <li>MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks.
- * <li>MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks.
- * <li>MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks.
- * <li>MIFARE Classic 4k are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks
- * and the last 8 sectors contain 16 blocks.
- * </ul>
- *
- * <p>MIFARE Classic tags require authentication on a per-sector basis before any
- * other I/O operations on that sector can be performed. There are two keys per sector,
- * and ACL bits determine what I/O operations are allowed on that sector after
- * authenticating with a key. {@see #authenticateSectorWithKeyA} and
- * {@see #authenticateSectorWithKeyB}.
- *
- * <p>Three well-known authentication keys are defined in this class:
- * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY},
- * {@link #KEY_NFC_FORUM}.
- * <ul>
- * <li>{@link #KEY_DEFAULT} is the default factory key for MIFARE Classic.
- * <li>{@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for
- * MIFARE Classic cards that have been formatted according to the
- * MIFARE Application Directory (MAD) specification.
- * <li>{@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that
- * have been formatted according to the NXP specification for NDEF on MIFARE Classic.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareClassic} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareClassic} I/O operations will be supported,
- * and {@link Ndef#MIFARE_CLASSIC} NDEF tags will also be supported. In either case,
- * {@link NfcA} will also be enumerated on the tag, because all MIFARE Classic tags are also
- * {@link NfcA}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareClassic extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /**
- * The default factory key.
- */
- public static final byte[] KEY_DEFAULT =
- {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
- /**
- * The well-known key for tags formatted according to the
- * MIFARE Application Directory (MAD) specification.
- */
- public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
- {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
- /**
- * The well-known key for tags formatted according to the
- * NDEF on MIFARE Classic specification.
- */
- public static final byte[] KEY_NFC_FORUM =
- {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
-
- /** A MIFARE Classic compatible card of unknown type */
- public static final int TYPE_UNKNOWN = -1;
- /** A MIFARE Classic tag */
- public static final int TYPE_CLASSIC = 0;
- /** A MIFARE Plus tag */
- public static final int TYPE_PLUS = 1;
- /** A MIFARE Pro tag */
- public static final int TYPE_PRO = 2;
-
- /** Tag contains 16 sectors, each with 4 blocks. */
- public static final int SIZE_1K = 1024;
- /** Tag contains 32 sectors, each with 4 blocks. */
- public static final int SIZE_2K = 2048;
- /**
- * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors
- * contain 16 blocks.
- */
- public static final int SIZE_4K = 4096;
- /** Tag contains 5 sectors, each with 4 blocks. */
- public static final int SIZE_MINI = 320;
-
- /** Size of a MIFARE Classic block (in bytes) */
- public static final int BLOCK_SIZE = 16;
-
- private static final int MAX_BLOCK_COUNT = 256;
- private static final int MAX_SECTOR_COUNT = 40;
-
- private boolean mIsEmulated;
- private int mType;
- private int mSize;
-
- /**
- * Get an instance of {@link MifareClassic} for the given tag.
- * <p>Does not cause any RF activity and does not block.
- * <p>Returns null if {@link MifareClassic} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag is not MIFARE Classic compatible, or this Android
- * device does not support MIFARE Classic.
- *
- * @param tag an MIFARE Classic compatible tag
- * @return MIFARE Classic object
- */
- public static MifareClassic get(Tag tag) {
- if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null;
- try {
- return new MifareClassic(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public MifareClassic(Tag tag) throws RemoteException {
- super(tag, TagTechnology.MIFARE_CLASSIC);
-
- NfcA a = NfcA.get(tag); // MIFARE Classic is always based on NFC a
-
- mIsEmulated = false;
-
- switch (a.getSak()) {
- case 0x01:
- case 0x08:
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- break;
- case 0x09:
- mType = TYPE_CLASSIC;
- mSize = SIZE_MINI;
- break;
- case 0x10:
- mType = TYPE_PLUS;
- mSize = SIZE_2K;
- // SecLevel = SL2
- break;
- case 0x11:
- mType = TYPE_PLUS;
- mSize = SIZE_4K;
- // Seclevel = SL2
- break;
- case 0x18:
- mType = TYPE_CLASSIC;
- mSize = SIZE_4K;
- break;
- case 0x28:
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- mIsEmulated = true;
- break;
- case 0x38:
- mType = TYPE_CLASSIC;
- mSize = SIZE_4K;
- mIsEmulated = true;
- break;
- case 0x88:
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- // NXP-tag: false
- break;
- case 0x98:
- case 0xB8:
- mType = TYPE_PRO;
- mSize = SIZE_4K;
- break;
- default:
- // Stack incorrectly reported a MifareClassic. We cannot handle this
- // gracefully - we have no idea of the memory layout. Bail.
- throw new RuntimeException(
- "Tag incorrectly enumerated as MIFARE Classic, SAK = " + a.getSak());
- }
- }
-
- /**
- * Return the type of this MIFARE Classic compatible tag.
- * <p>One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or
- * {@link #TYPE_PRO}.
- * <p>Does not cause any RF activity and does not block.
- *
- * @return type
- */
- public int getType() {
- return mType;
- }
-
- /**
- * Return the size of the tag in bytes
- * <p>One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}.
- * These constants are equal to their respective size in bytes.
- * <p>Does not cause any RF activity and does not block.
- * @return size in bytes
- */
- public int getSize() {
- return mSize;
- }
-
- /**
- * Return true if the tag is emulated, determined at discovery time.
- * These are actually smart-cards that emulate a MIFARE Classic interface.
- * They can be treated identically to a MIFARE Classic tag.
- * @hide
- */
- public boolean isEmulated() {
- return mIsEmulated;
- }
-
- /**
- * Return the number of MIFARE Classic sectors.
- * <p>Does not cause any RF activity and does not block.
- * @return number of sectors
- */
- public int getSectorCount() {
- switch (mSize) {
- case SIZE_1K:
- return 16;
- case SIZE_2K:
- return 32;
- case SIZE_4K:
- return 40;
- case SIZE_MINI:
- return 5;
- default:
- return 0;
- }
- }
-
- /**
- * Return the total number of MIFARE Classic blocks.
- * <p>Does not cause any RF activity and does not block.
- * @return total number of blocks
- */
- public int getBlockCount() {
- return mSize / BLOCK_SIZE;
- }
-
- /**
- * Return the number of blocks in the given sector.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param sectorIndex index of sector, starting from 0
- * @return number of blocks in the sector
- */
- public int getBlockCountInSector(int sectorIndex) {
- validateSector(sectorIndex);
-
- if (sectorIndex < 32) {
- return 4;
- } else {
- return 16;
- }
- }
-
- /**
- * Return the sector that contains a given block.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param blockIndex index of block to lookup, starting from 0
- * @return sector index that contains the block
- */
- public int blockToSector(int blockIndex) {
- validateBlock(blockIndex);
-
- if (blockIndex < 32 * 4) {
- return blockIndex / 4;
- } else {
- return 32 + (blockIndex - 32 * 4) / 16;
- }
- }
-
- /**
- * Return the first block of a given sector.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param sectorIndex index of sector to lookup, starting from 0
- * @return block index of first block in sector
- */
- public int sectorToBlock(int sectorIndex) {
- if (sectorIndex < 32) {
- return sectorIndex * 4;
- } else {
- return 32 * 4 + (sectorIndex - 32) * 16;
- }
- }
-
- /**
- * Authenticate a sector with key A.
- *
- * <p>Successful authentication of a sector with key A enables other
- * I/O operations on that sector. The set of operations granted by key A
- * key depends on the ACL bits set in that sector. For more information
- * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
- *
- * <p>A failed authentication attempt causes an implicit reconnection to the
- * tag, so authentication to other sectors will be lost.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param sectorIndex index of sector to authenticate, starting from 0
- * @param key 6-byte authentication key
- * @return true on success, false on authentication failure
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException {
- return authenticate(sectorIndex, key, true);
- }
-
- /**
- * Authenticate a sector with key B.
- *
- * <p>Successful authentication of a sector with key B enables other
- * I/O operations on that sector. The set of operations granted by key B
- * depends on the ACL bits set in that sector. For more information
- * see the MIFARE Classic specification on <a href="http://www.nxp.com">http://www.nxp.com</a>.
- *
- * <p>A failed authentication attempt causes an implicit reconnection to the
- * tag, so authentication to other sectors will be lost.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param sectorIndex index of sector to authenticate, starting from 0
- * @param key 6-byte authentication key
- * @return true on success, false on authentication failure
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException {
- return authenticate(sectorIndex, key, false);
- }
-
- private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException {
- validateSector(sector);
- checkConnected();
-
- byte[] cmd = new byte[12];
-
- // First byte is the command
- if (keyA) {
- cmd[0] = 0x60; // phHal_eMifareAuthentA
- } else {
- cmd[0] = 0x61; // phHal_eMifareAuthentB
- }
-
- // Second byte is block address
- // Authenticate command takes a block address. Authenticating a block
- // of a sector will authenticate the entire sector.
- cmd[1] = (byte) sectorToBlock(sector);
-
- // Next 4 bytes are last 4 bytes of UID
- byte[] uid = getTag().getId();
- System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
-
- // Next 6 bytes are key
- System.arraycopy(key, 0, cmd, 6, 6);
-
- try {
- if (transceive(cmd, false) != null) {
- return true;
- }
- } catch (TagLostException e) {
- throw e;
- } catch (IOException e) {
- // No need to deal with, will return false anyway
- }
- return false;
- }
-
- /**
- * Read 16-byte block.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to read, starting from 0
- * @return 16 byte block
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public byte[] readBlock(int blockIndex) throws IOException {
- validateBlock(blockIndex);
- checkConnected();
-
- byte[] cmd = { 0x30, (byte) blockIndex };
- return transceive(cmd, false);
- }
-
- /**
- * Write 16-byte block.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to write, starting from 0
- * @param data 16 bytes of data to write
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void writeBlock(int blockIndex, byte[] data) throws IOException {
- validateBlock(blockIndex);
- checkConnected();
- if (data.length != 16) {
- throw new IllegalArgumentException("must write 16-bytes");
- }
-
- byte[] cmd = new byte[data.length + 2];
- cmd[0] = (byte) 0xA0; // MF write command
- cmd[1] = (byte) blockIndex;
- System.arraycopy(data, 0, cmd, 2, data.length);
-
- transceive(cmd, false);
- }
-
- /**
- * Increment a value block, storing the result in the temporary block on the tag.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to increment, starting from 0
- * @param value non-negative to increment by
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void increment(int blockIndex, int value) throws IOException {
- validateBlock(blockIndex);
- validateValueOperand(value);
- checkConnected();
-
- ByteBuffer cmd = ByteBuffer.allocate(6);
- cmd.order(ByteOrder.LITTLE_ENDIAN);
- cmd.put( (byte) 0xC1 );
- cmd.put( (byte) blockIndex );
- cmd.putInt(value);
-
- transceive(cmd.array(), false);
- }
-
- /**
- * Decrement a value block, storing the result in the temporary block on the tag.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to decrement, starting from 0
- * @param value non-negative to decrement by
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void decrement(int blockIndex, int value) throws IOException {
- validateBlock(blockIndex);
- validateValueOperand(value);
- checkConnected();
-
- ByteBuffer cmd = ByteBuffer.allocate(6);
- cmd.order(ByteOrder.LITTLE_ENDIAN);
- cmd.put( (byte) 0xC0 );
- cmd.put( (byte) blockIndex );
- cmd.putInt(value);
-
- transceive(cmd.array(), false);
- }
-
- /**
- * Copy from the temporary block to a value block.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to copy to
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void transfer(int blockIndex) throws IOException {
- validateBlock(blockIndex);
- checkConnected();
-
- byte[] cmd = { (byte) 0xB0, (byte) blockIndex };
-
- transceive(cmd, false);
- }
-
- /**
- * Copy from a value block to the temporary block.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param blockIndex index of block to copy from
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void restore(int blockIndex) throws IOException {
- validateBlock(blockIndex);
- checkConnected();
-
- byte[] cmd = { (byte) 0xC2, (byte) blockIndex };
-
- transceive(cmd, false);
- }
-
- /**
- * Send raw NfcA data to a tag and receive the response.
- *
- * <p>This is equivalent to connecting to this tag via {@link NfcA}
- * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
- * tags are based on {@link NfcA} technology.
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @see NfcA#transceive
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-
- /**
- * Set the {@link #transceive} timeout in milliseconds.
- *
- * <p>The timeout only applies to {@link #transceive} on this object,
- * and is reset to a default value when {@link #close} is called.
- *
- * <p>Setting a longer timeout may be useful when performing
- * transactions that require a long processing time on the tag
- * such as key generation.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param timeout timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void setTimeout(int timeout) {
- try {
- int err = mTag.getTagService().setTimeout(TagTechnology.MIFARE_CLASSIC, timeout);
- if (err != ErrorCodes.SUCCESS) {
- throw new IllegalArgumentException("The supplied timeout is not valid");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Get the current {@link #transceive} timeout in milliseconds.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public int getTimeout() {
- try {
- return mTag.getTagService().getTimeout(TagTechnology.MIFARE_CLASSIC);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
-
- private static void validateSector(int sector) {
- // Do not be too strict on upper bounds checking, since some cards
- // have more addressable memory than they report. For example,
- // MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in
- // MIFARE Classic compatibility mode.
- // Note that issuing a command to an out-of-bounds block is safe - the
- // tag should report error causing IOException. This validation is a
- // helper to guard against obvious programming mistakes.
- if (sector < 0 || sector >= MAX_SECTOR_COUNT) {
- throw new IndexOutOfBoundsException("sector out of bounds: " + sector);
- }
- }
-
- private static void validateBlock(int block) {
- // Just looking for obvious out of bounds...
- if (block < 0 || block >= MAX_BLOCK_COUNT) {
- throw new IndexOutOfBoundsException("block out of bounds: " + block);
- }
- }
-
- private static void validateValueOperand(int value) {
- if (value < 0) {
- throw new IllegalArgumentException("value operand negative");
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/MifareUltralight.java b/nfc/java/android/nfc/tech/MifareUltralight.java
deleted file mode 100644
index c0416a39ba76..000000000000
--- a/nfc/java/android/nfc/tech/MifareUltralight.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-//TOOD: Ultralight C 3-DES authentication, one-way counter
-
-/**
- * Provides access to MIFARE Ultralight properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link MifareUltralight} object using {@link #get}.
- *
- * <p>MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}.
- * The primary operations on an Ultralight tag are {@link #readPages} and
- * {@link #writePage}.
- *
- * <p>The original MIFARE Ultralight consists of a 64 byte EEPROM. The first
- * 4 pages are for the OTP area, manufacturer data, and locking bits. They are
- * readable and some bits are writable. The final 12 pages are the user
- * read/write area. For more information see the NXP data sheet MF0ICU1.
- *
- * <p>The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages
- * are for OTP, manufacturer data, and locking bits. The next 36 pages are the
- * user read/write area. The next 4 pages are additional locking bits, counters
- * and authentication configuration and are readable. The final 4 pages are for
- * the authentication key and are not readable. For more information see the
- * NXP data sheet MF0ICU2.
- *
- * <p>Implementation of this class on a Android NFC device is optional.
- * If it is not implemented, then
- * {@link MifareUltralight} will never be enumerated in {@link Tag#getTechList}.
- * If it is enumerated, then all {@link MifareUltralight} I/O operations will be supported.
- * In either case, {@link NfcA} will also be enumerated on the tag,
- * because all MIFARE Ultralight tags are also {@link NfcA} tags.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class MifareUltralight extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /** A MIFARE Ultralight compatible tag of unknown type */
- public static final int TYPE_UNKNOWN = -1;
- /** A MIFARE Ultralight tag */
- public static final int TYPE_ULTRALIGHT = 1;
- /** A MIFARE Ultralight C tag */
- public static final int TYPE_ULTRALIGHT_C = 2;
-
- /** Size of a MIFARE Ultralight page in bytes */
- public static final int PAGE_SIZE = 4;
-
- private static final int NXP_MANUFACTURER_ID = 0x04;
- private static final int MAX_PAGE_COUNT = 256;
-
- /** @hide */
- public static final String EXTRA_IS_UL_C = "isulc";
-
- private int mType;
-
- /**
- * Get an instance of {@link MifareUltralight} for the given tag.
- * <p>Returns null if {@link MifareUltralight} was not enumerated in
- * {@link Tag#getTechList} - this indicates the tag is not MIFARE
- * Ultralight compatible, or that this Android
- * device does not implement MIFARE Ultralight.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an MIFARE Ultralight compatible tag
- * @return MIFARE Ultralight object
- */
- public static MifareUltralight get(Tag tag) {
- if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null;
- try {
- return new MifareUltralight(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public MifareUltralight(Tag tag) throws RemoteException {
- super(tag, TagTechnology.MIFARE_ULTRALIGHT);
-
- // Check if this could actually be a MIFARE
- NfcA a = NfcA.get(tag);
-
- mType = TYPE_UNKNOWN;
-
- if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) {
- Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT);
- if (extras.getBoolean(EXTRA_IS_UL_C)) {
- mType = TYPE_ULTRALIGHT_C;
- } else {
- mType = TYPE_ULTRALIGHT;
- }
- }
- }
-
- /**
- * Return the MIFARE Ultralight type of the tag.
- * <p>One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or
- * {@link #TYPE_UNKNOWN}.
- * <p>Depending on how the tag has been formatted, it can be impossible
- * to accurately classify between original MIFARE Ultralight and
- * Ultralight C. So treat this method as a hint.
- * <p>Does not cause any RF activity and does not block.
- *
- * @return the type
- */
- public int getType() {
- return mType;
- }
-
- /**
- * Read 4 pages (16 bytes).
- *
- * <p>The MIFARE Ultralight protocol always reads 4 pages at a time, to
- * reduce the number of commands required to read an entire tag.
- * <p>If a read spans past the last readable block, then the tag will
- * return pages that have been wrapped back to the first blocks. MIFARE
- * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to
- * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE
- * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to
- * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param pageOffset index of first page to read, starting from 0
- * @return 4 pages (16 bytes)
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public byte[] readPages(int pageOffset) throws IOException {
- validatePageIndex(pageOffset);
- checkConnected();
-
- byte[] cmd = { 0x30, (byte) pageOffset};
- return transceive(cmd, false);
- }
-
- /**
- * Write 1 page (4 bytes).
- *
- * <p>The MIFARE Ultralight protocol always writes 1 page at a time, to
- * minimize EEPROM write cycles.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param pageOffset index of page to write, starting from 0
- * @param data 4 bytes to write
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- */
- public void writePage(int pageOffset, byte[] data) throws IOException {
- validatePageIndex(pageOffset);
- checkConnected();
-
- byte[] cmd = new byte[data.length + 2];
- cmd[0] = (byte) 0xA2;
- cmd[1] = (byte) pageOffset;
- System.arraycopy(data, 0, cmd, 2, data.length);
-
- transceive(cmd, false);
- }
-
- /**
- * Send raw NfcA data to a tag and receive the response.
- *
- * <p>This is equivalent to connecting to this tag via {@link NfcA}
- * and calling {@link NfcA#transceive}. Note that all MIFARE Classic
- * tags are based on {@link NfcA} technology.
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @see NfcA#transceive
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-
- /**
- * Set the {@link #transceive} timeout in milliseconds.
- *
- * <p>The timeout only applies to {@link #transceive} on this object,
- * and is reset to a default value when {@link #close} is called.
- *
- * <p>Setting a longer timeout may be useful when performing
- * transactions that require a long processing time on the tag
- * such as key generation.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param timeout timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void setTimeout(int timeout) {
- try {
- int err = mTag.getTagService().setTimeout(
- TagTechnology.MIFARE_ULTRALIGHT, timeout);
- if (err != ErrorCodes.SUCCESS) {
- throw new IllegalArgumentException("The supplied timeout is not valid");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Get the current {@link #transceive} timeout in milliseconds.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public int getTimeout() {
- try {
- return mTag.getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
-
- private static void validatePageIndex(int pageIndex) {
- // Do not be too strict on upper bounds checking, since some cards
- // may have more addressable memory than they report.
- // Note that issuing a command to an out-of-bounds block is safe - the
- // tag will wrap the read to an addressable area. This validation is a
- // helper to guard against obvious programming mistakes.
- if (pageIndex < 0 || pageIndex >= MAX_PAGE_COUNT) {
- throw new IndexOutOfBoundsException("page out of bounds: " + pageIndex);
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/Ndef.java b/nfc/java/android/nfc/tech/Ndef.java
deleted file mode 100644
index 7d83f157a314..000000000000
--- a/nfc/java/android/nfc/tech/Ndef.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NDEF content and operations on a {@link Tag}.
- *
- * <p>Acquire a {@link Ndef} object using {@link #get}.
- *
- * <p>NDEF is an NFC Forum data format. The data formats are implemented in
- * {@link android.nfc.NdefMessage} and
- * {@link android.nfc.NdefRecord}. This class provides methods to
- * retrieve and modify the {@link android.nfc.NdefMessage}
- * on a tag.
- *
- * <p>There are currently four NFC Forum standardized tag types that can be
- * formatted to contain NDEF data.
- * <ul>
- * <li>NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz
- * <li>NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight
- * <li>NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica
- * <li>NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire
- * </ul>
- * It is mandatory for all Android devices with NFC to correctly enumerate
- * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations
- * as defined in this class.
- *
- * <p>Some vendors have their own well defined specifications for storing NDEF data
- * on tags that do not fall into the above categories. Android devices with NFC
- * should enumerate and implement {@link Ndef} under these vendor specifications
- * where possible, but it is not mandatory. {@link #getType} returns a String
- * describing this specification, for example {@link #MIFARE_CLASSIC} is
- * <code>com.nxp.ndef.mifareclassic</code>.
- *
- * <p>Android devices that support MIFARE Classic must also correctly
- * implement {@link Ndef} on MIFARE Classic tags formatted to NDEF.
- *
- * <p>For guaranteed compatibility across all Android devices with NFC, it is
- * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags
- * with NDEF payload. Vendor NDEF formats will not work on all Android devices.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class Ndef extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /** @hide */
- public static final int NDEF_MODE_READ_ONLY = 1;
- /** @hide */
- public static final int NDEF_MODE_READ_WRITE = 2;
- /** @hide */
- public static final int NDEF_MODE_UNKNOWN = 3;
-
- /** @hide */
- public static final String EXTRA_NDEF_MSG = "ndefmsg";
-
- /** @hide */
- public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength";
-
- /** @hide */
- public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate";
-
- /** @hide */
- public static final String EXTRA_NDEF_TYPE = "ndeftype";
-
- /** @hide */
- public static final int TYPE_OTHER = -1;
- /** @hide */
- public static final int TYPE_1 = 1;
- /** @hide */
- public static final int TYPE_2 = 2;
- /** @hide */
- public static final int TYPE_3 = 3;
- /** @hide */
- public static final int TYPE_4 = 4;
- /** @hide */
- public static final int TYPE_MIFARE_CLASSIC = 101;
- /** @hide */
- public static final int TYPE_ICODE_SLI = 102;
-
- /** @hide */
- public static final String UNKNOWN = "android.ndef.unknown";
-
- /** NFC Forum Tag Type 1 */
- public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1";
- /** NFC Forum Tag Type 2 */
- public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2";
- /** NFC Forum Tag Type 3 */
- public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3";
- /** NFC Forum Tag Type 4 */
- public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4";
- /** NDEF on MIFARE Classic */
- public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic";
- /**
- * NDEF on iCODE SLI
- * @hide
- */
- public static final String ICODE_SLI = "com.nxp.ndef.icodesli";
-
- private final int mMaxNdefSize;
- private final int mCardState;
- private final NdefMessage mNdefMsg;
- private final int mNdefType;
-
- /**
- * Get an instance of {@link Ndef} for the given tag.
- *
- * <p>Returns null if {@link Ndef} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag is not NDEF formatted, or that this tag
- * is NDEF formatted but under a vendor specification that this Android
- * device does not implement.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NDEF compatible tag
- * @return Ndef object
- */
- public static Ndef get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NDEF)) return null;
- try {
- return new Ndef(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Internal constructor, to be used by NfcAdapter
- * @hide
- */
- public Ndef(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NDEF);
- Bundle extras = tag.getTechExtras(TagTechnology.NDEF);
- if (extras != null) {
- mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
- mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
- mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG, android.nfc.NdefMessage.class);
- mNdefType = extras.getInt(EXTRA_NDEF_TYPE);
- } else {
- throw new NullPointerException("NDEF tech extras are null.");
- }
-
- }
-
- /**
- * Get the {@link NdefMessage} that was read from the tag at discovery time.
- *
- * <p>If the NDEF Message is modified by an I/O operation then it
- * will not be updated here, this function only returns what was discovered
- * when the tag entered the field.
- * <p>Note that this method may return null if the tag was in the
- * INITIALIZED state as defined by NFC Forum, as in this state the
- * tag is formatted to support NDEF but does not contain a message yet.
- * <p>Does not cause any RF activity and does not block.
- * @return NDEF Message read from the tag at discovery time, can be null
- */
- public NdefMessage getCachedNdefMessage() {
- return mNdefMsg;
- }
-
- /**
- * Get the NDEF tag type.
- *
- * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2},
- * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4},
- * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been
- * formalized in this Android API.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return a string representing the NDEF tag type
- */
- public String getType() {
- switch (mNdefType) {
- case TYPE_1:
- return NFC_FORUM_TYPE_1;
- case TYPE_2:
- return NFC_FORUM_TYPE_2;
- case TYPE_3:
- return NFC_FORUM_TYPE_3;
- case TYPE_4:
- return NFC_FORUM_TYPE_4;
- case TYPE_MIFARE_CLASSIC:
- return MIFARE_CLASSIC;
- case TYPE_ICODE_SLI:
- return ICODE_SLI;
- default:
- return UNKNOWN;
- }
- }
-
- /**
- * Get the maximum NDEF message size in bytes.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return size in bytes
- */
- public int getMaxSize() {
- return mMaxNdefSize;
- }
-
- /**
- * Determine if the tag is writable.
- *
- * <p>NFC Forum tags can be in read-only or read-write states.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @return true if the tag is writable
- */
- public boolean isWritable() {
- return (mCardState == NDEF_MODE_READ_WRITE);
- }
-
- /**
- * Read the current {@link android.nfc.NdefMessage} on this tag.
- *
- * <p>This always reads the current NDEF Message stored on the tag.
- *
- * <p>Note that this method may return null if the tag was in the
- * INITIALIZED state as defined by NFC Forum, as in that state the
- * tag is formatted to support NDEF but does not contain a message yet.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return the NDEF Message, can be null
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- * @throws FormatException if the NDEF Message on the tag is malformed
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public NdefMessage getNdefMessage() throws IOException, FormatException {
- checkConnected();
-
- try {
- INfcTag tagService = mTag.getTagService();
- if (tagService == null) {
- throw new IOException("Mock tags don't support this operation.");
- }
- int serviceHandle = mTag.getServiceHandle();
- if (tagService.isNdef(serviceHandle)) {
- NdefMessage msg = tagService.ndefRead(serviceHandle);
- if (msg == null && !tagService.isPresent(serviceHandle)) {
- throw new TagLostException();
- }
- return msg;
- } else if (!tagService.isPresent(serviceHandle)) {
- throw new TagLostException();
- } else {
- return null;
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return null;
- }
- }
-
- /**
- * Overwrite the {@link NdefMessage} on this tag.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param msg the NDEF Message to write, must not be null
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- * @throws FormatException if the NDEF Message to write is malformed
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
- checkConnected();
-
- try {
- INfcTag tagService = mTag.getTagService();
- if (tagService == null) {
- throw new IOException("Mock tags don't support this operation.");
- }
- int serviceHandle = mTag.getServiceHandle();
- if (tagService.isNdef(serviceHandle)) {
- int errorCode = tagService.ndefWrite(serviceHandle, msg);
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- break;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- throw new FormatException();
- default:
- // Should not happen
- throw new IOException();
- }
- }
- else {
- throw new IOException("Tag is not ndef");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return true if it is possible to make this tag read-only
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public boolean canMakeReadOnly() {
- INfcTag tagService = mTag.getTagService();
- if (tagService == null) {
- return false;
- }
- try {
- return tagService.canMakeReadOnly(mNdefType);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return false;
- }
- }
-
- /**
- * Make a tag read-only.
- *
- * <p>This sets the CC field to indicate the tag is read-only,
- * and where possible permanently sets the lock bits to prevent
- * any further modification of the memory.
- * <p>This is a one-way process and cannot be reverted!
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return true on success, false if it is not possible to make this tag read-only
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public boolean makeReadOnly() throws IOException {
- checkConnected();
-
- try {
- INfcTag tagService = mTag.getTagService();
- if (tagService == null) {
- return false;
- }
- if (tagService.isNdef(mTag.getServiceHandle())) {
- int errorCode = tagService.ndefMakeReadOnly(mTag.getServiceHandle());
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- return true;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- return false;
- default:
- // Should not happen
- throw new IOException();
- }
- }
- else {
- throw new IOException("Tag is not ndef");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return false;
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/NdefFormatable.java b/nfc/java/android/nfc/tech/NdefFormatable.java
deleted file mode 100644
index 2240fe7f7d3b..000000000000
--- a/nfc/java/android/nfc/tech/NdefFormatable.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.FormatException;
-import android.nfc.INfcTag;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.nfc.TagLostException;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provide access to NDEF format operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NdefFormatable} object using {@link #get}.
- *
- * <p>Android devices with NFC must only enumerate and implement this
- * class for tags for which it can format to NDEF.
- *
- * <p>Unfortunately the procedures to convert unformated tags to NDEF formatted
- * tags are not specified by NFC Forum, and are not generally well-known. So
- * there is no mandatory set of tags for which all Android devices with NFC
- * must support {@link NdefFormatable}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NdefFormatable extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /**
- * Get an instance of {@link NdefFormatable} for the given tag.
- * <p>Does not cause any RF activity and does not block.
- * <p>Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag is not NDEF formatable by this Android device.
- *
- * @param tag an NDEF formatable tag
- * @return NDEF formatable object
- */
- public static NdefFormatable get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null;
- try {
- return new NdefFormatable(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Internal constructor, to be used by NfcAdapter
- * @hide
- */
- public NdefFormatable(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NDEF_FORMATABLE);
- }
-
- /**
- * Format a tag as NDEF, and write a {@link NdefMessage}.
- *
- * <p>This is a multi-step process, an IOException is thrown
- * if any one step fails.
- * <p>The card is left in a read-write state after this operation.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param firstMessage the NDEF message to write after formatting, can be null
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- * @throws FormatException if the NDEF Message to write is malformed
- */
- public void format(NdefMessage firstMessage) throws IOException, FormatException {
- format(firstMessage, false);
- }
-
- /**
- * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only.
- *
- * <p>This is a multi-step process, an IOException is thrown
- * if any one step fails.
- * <p>The card is left in a read-only state if this method returns successfully.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param firstMessage the NDEF message to write after formatting
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or the operation is canceled
- * @throws FormatException if the NDEF Message to write is malformed
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
- format(firstMessage, true);
- }
-
- /*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException,
- FormatException {
- checkConnected();
-
- try {
- int serviceHandle = mTag.getServiceHandle();
- INfcTag tagService = mTag.getTagService();
- if (tagService == null) {
- throw new IOException();
- }
- int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT);
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- break;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- throw new FormatException();
- default:
- // Should not happen
- throw new IOException();
- }
- // Now check and see if the format worked
- if (!tagService.isNdef(serviceHandle)) {
- throw new IOException();
- }
-
- // Write a message, if one was provided
- if (firstMessage != null) {
- errorCode = tagService.ndefWrite(serviceHandle, firstMessage);
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- break;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- throw new FormatException();
- default:
- // Should not happen
- throw new IOException();
- }
- }
-
- // optionally make read-only
- if (makeReadOnly) {
- errorCode = tagService.ndefMakeReadOnly(serviceHandle);
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- break;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- throw new IOException();
- default:
- // Should not happen
- throw new IOException();
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/NfcA.java b/nfc/java/android/nfc/tech/NfcA.java
deleted file mode 100644
index 7e6648361670..000000000000
--- a/nfc/java/android/nfc/tech/NfcA.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcA} object using {@link #get}.
- * <p>The primary NFC-A I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcA extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /** @hide */
- public static final String EXTRA_SAK = "sak";
- /** @hide */
- public static final String EXTRA_ATQA = "atqa";
-
- private short mSak;
- private byte[] mAtqa;
-
- /**
- * Get an instance of {@link NfcA} for the given tag.
- * <p>Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag does not support NFC-A.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NFC-A compatible tag
- * @return NFC-A object
- */
- public static NfcA get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NFC_A)) return null;
- try {
- return new NfcA(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public NfcA(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NFC_A);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
- mSak = extras.getShort(EXTRA_SAK);
- mAtqa = extras.getByteArray(EXTRA_ATQA);
- }
-
- /**
- * Return the ATQA/SENS_RES bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return ATQA/SENS_RES bytes
- */
- public byte[] getAtqa() {
- return mAtqa;
- }
-
- /**
- * Return the SAK/SEL_RES bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return SAK bytes
- */
- public short getSak() {
- return mSak;
- }
-
- /**
- * Send raw NFC-A commands to the tag and receive the response.
- *
- * <p>Applications must not append the EoD (CRC) to the payload,
- * it will be automatically calculated.
- * <p>Applications must only send commands that are complete bytes,
- * for example a SENS_REQ is not possible (these are used to
- * manage tag polling and initialization).
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or this operation is canceled
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-
- /**
- * Set the {@link #transceive} timeout in milliseconds.
- *
- * <p>The timeout only applies to {@link #transceive} on this object,
- * and is reset to a default value when {@link #close} is called.
- *
- * <p>Setting a longer timeout may be useful when performing
- * transactions that require a long processing time on the tag
- * such as key generation.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param timeout timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void setTimeout(int timeout) {
- try {
- int err = mTag.getTagService().setTimeout(TagTechnology.NFC_A, timeout);
- if (err != ErrorCodes.SUCCESS) {
- throw new IllegalArgumentException("The supplied timeout is not valid");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Get the current {@link #transceive} timeout in milliseconds.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public int getTimeout() {
- try {
- return mTag.getTagService().getTimeout(TagTechnology.NFC_A);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/NfcB.java b/nfc/java/android/nfc/tech/NfcB.java
deleted file mode 100644
index 3ebd47f610c0..000000000000
--- a/nfc/java/android/nfc/tech/NfcB.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcB} object using {@link #get}.
- * <p>The primary NFC-B I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcB extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_APPDATA = "appdata";
- /** @hide */
- public static final String EXTRA_PROTINFO = "protinfo";
-
- private byte[] mAppData;
- private byte[] mProtInfo;
-
- /**
- * Get an instance of {@link NfcB} for the given tag.
- * <p>Returns null if {@link NfcB} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag does not support NFC-B.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NFC-B compatible tag
- * @return NFC-B object
- */
- public static NfcB get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NFC_B)) return null;
- try {
- return new NfcB(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public NfcB(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NFC_B);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_B);
- mAppData = extras.getByteArray(EXTRA_APPDATA);
- mProtInfo = extras.getByteArray(EXTRA_PROTINFO);
- }
-
- /**
- * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return Application Data bytes from ATQB/SENSB_RES bytes
- */
- public byte[] getApplicationData() {
- return mAppData;
- }
-
- /**
- * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return Protocol Info bytes from ATQB/SENSB_RES bytes
- */
- public byte[] getProtocolInfo() {
- return mProtInfo;
- }
-
- /**
- * Send raw NFC-B commands to the tag and receive the response.
- *
- * <p>Applications must not append the EoD (CRC) to the payload,
- * it will be automatically calculated.
- * <p>Applications must not send commands that manage the polling
- * loop and initialization (SENSB_REQ, SLOT_MARKER etc).
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or this operation is canceled
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-}
diff --git a/nfc/java/android/nfc/tech/NfcBarcode.java b/nfc/java/android/nfc/tech/NfcBarcode.java
deleted file mode 100644
index 421ba7827cb1..000000000000
--- a/nfc/java/android/nfc/tech/NfcBarcode.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * Provides access to tags containing just a barcode.
- *
- * <p>Acquire an {@link NfcBarcode} object using {@link #get}.
- *
- */
-public final class NfcBarcode extends BasicTagTechnology {
-
- /** Kovio Tags */
- public static final int TYPE_KOVIO = 1;
- public static final int TYPE_UNKNOWN = -1;
-
- /** @hide */
- public static final String EXTRA_BARCODE_TYPE = "barcodetype";
-
- private int mType;
-
- /**
- * Get an instance of {@link NfcBarcode} for the given tag.
- *
- * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NfcBarcode compatible tag
- * @return NfcBarcode object
- */
- public static NfcBarcode get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null;
- try {
- return new NfcBarcode(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
- * Internal constructor, to be used by NfcAdapter
- * @hide
- */
- public NfcBarcode(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NFC_BARCODE);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE);
- if (extras != null) {
- mType = extras.getInt(EXTRA_BARCODE_TYPE);
- } else {
- throw new NullPointerException("NfcBarcode tech extras are null.");
- }
- }
-
- /**
- * Returns the NFC Barcode tag type.
- *
- * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return the NFC Barcode tag type
- */
- public int getType() {
- return mType;
- }
-
- /**
- * Returns the barcode of an NfcBarcode tag.
- *
- * <p> Tags of {@link #TYPE_KOVIO} return 16 bytes:
- * <ul>
- * <p> The first byte is 0x80 ORd with a manufacturer ID, corresponding
- * to ISO/IEC 7816-6.
- * <p> The second byte describes the payload data format. Defined data
- * format types include the following:<ul>
- * <li>0x00: Reserved for manufacturer assignment</li>
- * <li>0x01: 96-bit URL with "http://www." prefix</li>
- * <li>0x02: 96-bit URL with "https://www." prefix</li>
- * <li>0x03: 96-bit URL with "http://" prefix</li>
- * <li>0x04: 96-bit URL with "https://" prefix</li>
- * <li>0x05: 96-bit GS1 EPC</li>
- * <li>0x06-0xFF: reserved</li>
- * </ul>
- * <p>The following 12 bytes are payload:<ul>
- * <li> In case of a URL payload, the payload is encoded in US-ASCII,
- * following the limitations defined in RFC3987.
- * {@see <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>}</li>
- * <li> In case of GS1 EPC data, see <a href="http://www.gs1.org/gsmp/kc/epcglobal/tds/">
- * GS1 Electronic Product Code (EPC) Tag Data Standard (TDS)</a> for more details.
- * </li>
- * </ul>
- * <p>The last 2 bytes comprise the CRC.
- * </ul>
- * <p>Does not cause any RF activity and does not block.
- *
- * @return a byte array containing the barcode
- * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-datasheet.pdf">
- * Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode)</a>
- * @see <a href="http://www.thinfilm.no/docs/thinfilm-nfc-barcode-data-format.pdf">
- * Thinfilm NFC Barcode data format (previously Kovio NFC Barcode)</a>
- */
- public byte[] getBarcode() {
- switch (mType) {
- case TYPE_KOVIO:
- // For Kovio tags the barcode matches the ID
- return mTag.getId();
- default:
- return null;
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/NfcF.java b/nfc/java/android/nfc/tech/NfcF.java
deleted file mode 100644
index 2ccd38875f07..000000000000
--- a/nfc/java/android/nfc/tech/NfcF.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.ErrorCodes;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcF} object using {@link #get}.
- * <p>The primary NFC-F I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcF extends BasicTagTechnology {
- private static final String TAG = "NFC";
-
- /** @hide */
- public static final String EXTRA_SC = "systemcode";
- /** @hide */
- public static final String EXTRA_PMM = "pmm";
-
- private byte[] mSystemCode = null;
- private byte[] mManufacturer = null;
-
- /**
- * Get an instance of {@link NfcF} for the given tag.
- * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag does not support NFC-F.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NFC-F compatible tag
- * @return NFC-F object
- */
- public static NfcF get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NFC_F)) return null;
- try {
- return new NfcF(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public NfcF(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NFC_F);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_F);
- if (extras != null) {
- mSystemCode = extras.getByteArray(EXTRA_SC);
- mManufacturer = extras.getByteArray(EXTRA_PMM);
- }
- }
-
- /**
- * Return the System Code bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return System Code bytes
- */
- public byte[] getSystemCode() {
- return mSystemCode;
- }
-
- /**
- * Return the Manufacturer bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return Manufacturer bytes
- */
- public byte[] getManufacturer() {
- return mManufacturer;
- }
-
- /**
- * Send raw NFC-F commands to the tag and receive the response.
- *
- * <p>Applications must not prefix the SoD (preamble and sync code)
- * and/or append the EoD (CRC) to the payload, it will be automatically calculated.
- *
- * <p>A typical NFC-F frame for this method looks like:
- * <pre>
- * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
- * </pre>
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or this operation is canceled
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-
- /**
- * Set the {@link #transceive} timeout in milliseconds.
- *
- * <p>The timeout only applies to {@link #transceive} on this object,
- * and is reset to a default value when {@link #close} is called.
- *
- * <p>Setting a longer timeout may be useful when performing
- * transactions that require a long processing time on the tag
- * such as key generation.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param timeout timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void setTimeout(int timeout) {
- try {
- int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout);
- if (err != ErrorCodes.SUCCESS) {
- throw new IllegalArgumentException("The supplied timeout is not valid");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- }
- }
-
- /**
- * Get the current {@link #transceive} timeout in milliseconds.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @return timeout value in milliseconds
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public int getTimeout() {
- try {
- return mTag.getTagService().getTimeout(TagTechnology.NFC_F);
- } catch (RemoteException e) {
- Log.e(TAG, "NFC service dead", e);
- return 0;
- }
- }
-}
diff --git a/nfc/java/android/nfc/tech/NfcV.java b/nfc/java/android/nfc/tech/NfcV.java
deleted file mode 100644
index 186c63bf07fd..000000000000
--- a/nfc/java/android/nfc/tech/NfcV.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link Tag}.
- *
- * <p>Acquire a {@link NfcV} object using {@link #get}.
- * <p>The primary NFC-V I/O operation is {@link #transceive}. Applications must
- * implement their own protocol stack on top of {@link #transceive}.
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public final class NfcV extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_RESP_FLAGS = "respflags";
-
- /** @hide */
- public static final String EXTRA_DSFID = "dsfid";
-
- private byte mRespFlags;
- private byte mDsfId;
-
- /**
- * Get an instance of {@link NfcV} for the given tag.
- * <p>Returns null if {@link NfcV} was not enumerated in {@link Tag#getTechList}.
- * This indicates the tag does not support NFC-V.
- * <p>Does not cause any RF activity and does not block.
- *
- * @param tag an NFC-V compatible tag
- * @return NFC-V object
- */
- public static NfcV get(Tag tag) {
- if (!tag.hasTech(TagTechnology.NFC_V)) return null;
- try {
- return new NfcV(tag);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** @hide */
- public NfcV(Tag tag) throws RemoteException {
- super(tag, TagTechnology.NFC_V);
- Bundle extras = tag.getTechExtras(TagTechnology.NFC_V);
- mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
- mDsfId = extras.getByte(EXTRA_DSFID);
- }
-
- /**
- * Return the Response Flag bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return Response Flag bytes
- */
- public byte getResponseFlags() {
- return mRespFlags;
- }
-
- /**
- * Return the DSF ID bytes from tag discovery.
- *
- * <p>Does not cause any RF activity and does not block.
- *
- * @return DSF ID bytes
- */
- public byte getDsfId() {
- return mDsfId;
- }
-
- /**
- * Send raw NFC-V commands to the tag and receive the response.
- *
- * <p>Applications must not append the CRC to the payload,
- * it will be automatically calculated. The application does
- * provide FLAGS, CMD and PARAMETER bytes.
- *
- * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes
- * that can be sent with {@link #transceive}.
- *
- * <p>This is an I/O operation and will block until complete. It must
- * not be called from the main application thread. A blocked call will be canceled with
- * {@link IOException} if {@link #close} is called from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or this operation is canceled
- */
- public byte[] transceive(byte[] data) throws IOException {
- return transceive(data, true);
- }
-
-
- /**
- * Return the maximum number of bytes that can be sent with {@link #transceive}.
- * @return the maximum number of bytes that can be sent with {@link #transceive}.
- */
- public int getMaxTransceiveLength() {
- return getMaxTransceiveLengthInternal();
- }
-}
diff --git a/nfc/java/android/nfc/tech/OWNERS b/nfc/java/android/nfc/tech/OWNERS
deleted file mode 100644
index 35e9713f5715..000000000000
--- a/nfc/java/android/nfc/tech/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
diff --git a/nfc/java/android/nfc/tech/TagTechnology.java b/nfc/java/android/nfc/tech/TagTechnology.java
deleted file mode 100644
index 839fe429b338..000000000000
--- a/nfc/java/android/nfc/tech/TagTechnology.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc.tech;
-
-import android.nfc.Tag;
-
-import java.io.Closeable;
-import java.io.IOException;
-
-/**
- * {@link TagTechnology} is an interface to a technology in a {@link Tag}.
- * <p>
- * Obtain a {@link TagTechnology} implementation by calling the static method <code>get()</code>
- * on the implementation class.
- * <p>
- * NFC tags are based on a number of independently developed technologies and offer a
- * wide range of capabilities. The
- * {@link TagTechnology} implementations provide access to these different
- * technologies and capabilities. Some sub-classes map to technology
- * specification (for example {@link NfcA}, {@link IsoDep}, others map to
- * pseudo-technologies or capabilities (for example {@link Ndef}, {@link NdefFormatable}).
- * <p>
- * It is mandatory for all Android NFC devices to provide the following
- * {@link TagTechnology} implementations.
- * <ul>
- * <li>{@link NfcA} (also known as ISO 14443-3A)
- * <li>{@link NfcB} (also known as ISO 14443-3B)
- * <li>{@link NfcF} (also known as JIS 6319-4)
- * <li>{@link NfcV} (also known as ISO 15693)
- * <li>{@link IsoDep}
- * <li>{@link Ndef} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags
- * </ul>
- * It is optional for Android NFC devices to provide the following
- * {@link TagTechnology} implementations. If it is not provided, the
- * Android device will never enumerate that class via {@link Tag#getTechList}.
- * <ul>
- * <li>{@link MifareClassic}
- * <li>{@link MifareUltralight}
- * <li>{@link NfcBarcode}
- * <li>{@link NdefFormatable} must only be enumerated on tags for which this Android device
- * is capable of formatting. Proprietary knowledge is often required to format a tag
- * to make it NDEF compatible.
- * </ul>
- * <p>
- * {@link TagTechnology} implementations provide methods that fall into two classes:
- * <em>cached getters</em> and <em>I/O operations</em>.
- * <h4>Cached getters</h4>
- * These methods (usually prefixed by <code>get</code> or <code>is</code>) return
- * properties of the tag, as determined at discovery time. These methods will never
- * block or cause RF activity, and do not require {@link #connect} to have been called.
- * They also never update, for example if a property is changed by an I/O operation with a tag
- * then the cached getter will still return the result from tag discovery time.
- * <h4>I/O operations</h4>
- * I/O operations may require RF activity, and may block. They have the following semantics.
- * <ul>
- * <li>{@link #connect} must be called before using any other I/O operation.
- * <li>{@link #close} must be called after completing I/O operations with a
- * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads
- * (including {@link #connect} with {@link IOException}.
- * <li>Only one {@link TagTechnology} can be connected at a time. Other calls to
- * {@link #connect} will return {@link IOException}.
- * <li>I/O operations may block, and should never be called on the main application
- * thread.
- * </ul>
- *
- * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
- * require the {@link android.Manifest.permission#NFC} permission.
- */
-public interface TagTechnology extends Closeable {
- /**
- * This technology is an instance of {@link NfcA}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NFC_A = 1;
-
- /**
- * This technology is an instance of {@link NfcB}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NFC_B = 2;
-
- /**
- * This technology is an instance of {@link IsoDep}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int ISO_DEP = 3;
-
- /**
- * This technology is an instance of {@link NfcF}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NFC_F = 4;
-
- /**
- * This technology is an instance of {@link NfcV}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NFC_V = 5;
-
- /**
- * This technology is an instance of {@link Ndef}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NDEF = 6;
-
- /**
- * This technology is an instance of {@link NdefFormatable}.
- * <p>Support for this technology type is mandatory.
- * @hide
- */
- public static final int NDEF_FORMATABLE = 7;
-
- /**
- * This technology is an instance of {@link MifareClassic}.
- * <p>Support for this technology type is optional. If a stack doesn't support this technology
- * type tags using it must still be discovered and present the lower level radio interface
- * technologies in use.
- * @hide
- */
- public static final int MIFARE_CLASSIC = 8;
-
- /**
- * This technology is an instance of {@link MifareUltralight}.
- * <p>Support for this technology type is optional. If a stack doesn't support this technology
- * type tags using it must still be discovered and present the lower level radio interface
- * technologies in use.
- * @hide
- */
- public static final int MIFARE_ULTRALIGHT = 9;
-
- /**
- * This technology is an instance of {@link NfcBarcode}.
- * <p>Support for this technology type is optional. If a stack doesn't support this technology
- * type tags using it must still be discovered and present the lower level radio interface
- * technologies in use.
- * @hide
- */
- public static final int NFC_BARCODE = 10;
-
- /**
- * Get the {@link Tag} object backing this {@link TagTechnology} object.
- * @return the {@link Tag} backing this {@link TagTechnology} object.
- */
- public Tag getTag();
-
- /**
- * Enable I/O operations to the tag from this {@link TagTechnology} object.
- * <p>May cause RF activity and may block. Must not be called
- * from the main application thread. A blocked call will be canceled with
- * {@link IOException} by calling {@link #close} from another thread.
- * <p>Only one {@link TagTechnology} object can be connected to a {@link Tag} at a time.
- * <p>Applications must call {@link #close} when I/O operations are complete.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @see #close()
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or connect is canceled
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void connect() throws IOException;
-
- /**
- * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be
- * used to reset the state of the tag itself.
- *
- * <p>May cause RF activity and may block. Must not be called
- * from the main application thread. A blocked call will be canceled with
- * {@link IOException} by calling {@link #close} from another thread.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @see #connect()
- * @see #close()
- * @throws TagLostException if the tag leaves the field
- * @throws IOException if there is an I/O failure, or connect is canceled
- * @throws SecurityException if the tag object is reused after the tag has left the field
- * @hide
- */
- public void reconnect() throws IOException;
-
- /**
- * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources.
- * <p>Also causes all blocked I/O operations on other thread to be canceled and
- * return with {@link IOException}.
- *
- * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
- *
- * @see #connect()
- * @throws SecurityException if the tag object is reused after the tag has left the field
- */
- public void close() throws IOException;
-
- /**
- * Helper to indicate if I/O operations should be possible.
- *
- * <p>Returns true if {@link #connect} has completed, and {@link #close} has not been
- * called, and the {@link Tag} is not known to be out of range.
- * <p>Does not cause RF activity, and does not block.
- *
- * @return true if I/O operations should be possible
- */
- public boolean isConnected();
-}
diff --git a/nfc/java/android/nfc/tech/package.html b/nfc/java/android/nfc/tech/package.html
deleted file mode 100644
index a99828f90c5b..000000000000
--- a/nfc/java/android/nfc/tech/package.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<HTML>
-<BODY>
-<p>
-These classes provide access to a tag technology's features, which vary by the type
-of tag that is scanned. A scanned tag can support multiple technologies, and you can find
-out what they are by calling {@link android.nfc.Tag#getTechList getTechList()}.</p>
-
-<p>For more information on dealing with tag technologies and handling the ones that you care about, see
-<a href="{@docRoot}guide/topics/nfc/index.html#dispatch">The Tag Dispatch System</a>.
-The {@link android.nfc.tech.TagTechnology} interface provides an overview of the
-supported technologies.</p>
-</BODY>
-</HTML>
diff --git a/nfc/lint-baseline.xml b/nfc/lint-baseline.xml
deleted file mode 100644
index 67b496e0baf3..000000000000
--- a/nfc/lint-baseline.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01">
-
- <issue
- id="FlaggedApi"
- message="Method `NfcOemExtension()` is a flagged API and should be inside an `if (Flags.nfcOemExtension())` check (or annotate the surrounding method `NfcAdapter` with `@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) to transfer requirement to caller`)"
- errorLine1=" mNfcOemExtension = new NfcOemExtension(mContext, this);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="909"
- column="28"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
- errorLine1=" &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="1917"
- column="39"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
- errorLine1=" &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="1917"
- column="65"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
- errorLine1=" || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="1918"
- column="40"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
- errorLine1=" || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
- line="1918"
- column="66"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Method `onVendorNciResponse()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorResponseReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
- errorLine1=" executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
- line="88"
- column="44"/>
- </issue>
-
- <issue
- id="FlaggedApi"
- message="Method `onVendorNciNotification()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorNotificationReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
- errorLine1=" executor.execute(() -> callback.onVendorNciNotification(gid, oid, payload));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/nfc/java/android/nfc/NfcVendorNciCallbackListener.java"
- line="106"
- column="44"/>
- </issue>
-
-</issues>
diff --git a/nfc/tests/AndroidTest.xml b/nfc/tests/AndroidTest.xml
deleted file mode 100644
index 490d6f5df197..000000000000
--- a/nfc/tests/AndroidTest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 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.
--->
-<configuration description="Config for NFC Manager test cases">
- <option name="test-suite-tag" value="apct"/>
- <option name="test-suite-tag" value="apct-instrumentation"/>
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="NfcManagerTests.apk" />
- </target_preparer>
-
- <option name="test-suite-tag" value="apct"/>
- <option name="test-tag" value="NfcManagerTests"/>
-
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.nfc" />
- <option name="hidden-api-checks" value="false"/>
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
- </test>
-</configuration>
diff --git a/nfc/tests/src/android/nfc/NdefMessageTest.java b/nfc/tests/src/android/nfc/NdefMessageTest.java
deleted file mode 100644
index 9ca295da75c3..000000000000
--- a/nfc/tests/src/android/nfc/NdefMessageTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class NdefMessageTest {
- private NdefMessage mNdefMessage;
- private NdefRecord mNdefRecord;
-
- @Before
- public void setUp() {
- mNdefRecord = NdefRecord.createUri("http://www.example.com");
- mNdefMessage = new NdefMessage(mNdefRecord);
- }
-
- @After
- public void tearDown() {
- }
-
- @Test
- public void testGetRecords() {
- NdefRecord[] records = mNdefMessage.getRecords();
- assertThat(records).isNotNull();
- assertThat(records).hasLength(1);
- assertThat(records[0]).isEqualTo(mNdefRecord);
- }
-
- @Test
- public void testToByteArray() throws FormatException {
- byte[] bytes = mNdefMessage.toByteArray();
- assertThat(bytes).isNotNull();
- assertThat(bytes.length).isGreaterThan(0);
- NdefMessage ndefMessage = new NdefMessage(bytes);
- assertThat(ndefMessage).isNotNull();
- }
-}
diff --git a/nfc/tests/src/android/nfc/NdefRecordTest.java b/nfc/tests/src/android/nfc/NdefRecordTest.java
deleted file mode 100644
index 044c67448329..000000000000
--- a/nfc/tests/src/android/nfc/NdefRecordTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Locale;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NdefRecordTest {
-
- @Test
- public void testNdefRecordConstructor() throws FormatException {
- NdefRecord applicationRecord = NdefRecord
- .createApplicationRecord("com.android.test");
- NdefRecord ndefRecord = new NdefRecord(applicationRecord.toByteArray());
- assertThat(ndefRecord).isNotNull();
- assertThat(ndefRecord.toByteArray().length).isGreaterThan(0);
- assertThat(ndefRecord.getType()).isEqualTo("android.com:pkg".getBytes());
- assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
- }
-
- @Test
- public void testCreateExternal() {
- NdefRecord ndefRecord = NdefRecord.createExternal("test",
- "android.com:pkg", "com.android.test".getBytes());
- assertThat(ndefRecord).isNotNull();
- assertThat(ndefRecord.getType()).isEqualTo("test:android.com:pkg".getBytes());
- assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
- }
-
- @Test
- public void testCreateUri() {
- NdefRecord ndefRecord = NdefRecord.createUri("http://www.example.com");
- assertThat(ndefRecord).isNotNull();
- assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
- assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_URI);
- }
-
- @Test
- public void testCreateMime() {
- NdefRecord ndefRecord = NdefRecord.createMime("text/plain", "example".getBytes());
- assertThat(ndefRecord).isNotNull();
- assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_MIME_MEDIA);
- }
-
- @Test
- public void testCreateTextRecord() {
- String languageCode = Locale.getDefault().getLanguage();
- NdefRecord ndefRecord = NdefRecord.createTextRecord(languageCode, "testdata");
- assertThat(ndefRecord).isNotNull();
- assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
- assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_TEXT);
- }
-
-}
diff --git a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java b/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
deleted file mode 100644
index 48f4288d401e..000000000000
--- a/nfc/tests/src/android/nfc/NfcControllerAlwaysOnListenerTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.nfc.NfcAdapter.ControllerAlwaysOnListener;
-import android.os.RemoteException;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * Test of {@link NfcControllerAlwaysOnListener}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NfcControllerAlwaysOnListenerTest {
-
- private INfcAdapter mNfcAdapter = mock(INfcAdapter.class);
-
- private Throwable mThrowRemoteException = new RemoteException("RemoteException");
-
- private static Executor getExecutor() {
- return new Executor() {
- @Override
- public void execute(Runnable command) {
- command.run();
- }
- };
- }
-
- private static void verifyListenerInvoked(ControllerAlwaysOnListener listener) {
- verify(listener, times(1)).onControllerAlwaysOnChanged(anyBoolean());
- }
-
- @Test
- public void testRegister_RegisterUnregisterWhenNotSupported() throws RemoteException {
- // isControllerAlwaysOnSupported() returns false, not supported.
- doReturn(false).when(mNfcAdapter).isControllerAlwaysOnSupported();
- NfcControllerAlwaysOnListener mListener =
- new NfcControllerAlwaysOnListener(mNfcAdapter);
- ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
- ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
- // Verify that the state listener will not registered with the NFC Adapter
- mListener.register(getExecutor(), mockListener1);
- verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
- // Register a second client and no any call to NFC Adapter
- mListener.register(getExecutor(), mockListener2);
- verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
-
- // Unregister first listener, and no any call to NFC Adapter
- mListener.unregister(mockListener1);
- verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
- verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
- // Unregister second listener, and no any call to NFC Adapter
- mListener.unregister(mockListener2);
- verify(mNfcAdapter, times(0)).registerControllerAlwaysOnListener(any());
- verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
- }
-
- @Test
- public void testRegister_RegisterUnregister() throws RemoteException {
- doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
- NfcControllerAlwaysOnListener mListener =
- new NfcControllerAlwaysOnListener(mNfcAdapter);
- ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
- ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
- // Verify that the state listener registered with the NFC Adapter
- mListener.register(getExecutor(), mockListener1);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
- // Register a second client and no new call to NFC Adapter
- mListener.register(getExecutor(), mockListener2);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
- // Unregister first listener
- mListener.unregister(mockListener1);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
- verify(mNfcAdapter, times(0)).unregisterControllerAlwaysOnListener(any());
-
- // Unregister second listener and the state listener registered with the NFC Adapter
- mListener.unregister(mockListener2);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
- verify(mNfcAdapter, times(1)).unregisterControllerAlwaysOnListener(any());
- }
-
- @Test
- public void testRegister_FirstRegisterFails() throws RemoteException {
- doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
- NfcControllerAlwaysOnListener mListener =
- new NfcControllerAlwaysOnListener(mNfcAdapter);
- ControllerAlwaysOnListener mockListener1 = mock(ControllerAlwaysOnListener.class);
- ControllerAlwaysOnListener mockListener2 = mock(ControllerAlwaysOnListener.class);
-
- // Throw a remote exception whenever first registering
- doThrow(mThrowRemoteException).when(mNfcAdapter).registerControllerAlwaysOnListener(
- any());
-
- mListener.register(getExecutor(), mockListener1);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
- // No longer throw an exception, instead succeed
- doNothing().when(mNfcAdapter).registerControllerAlwaysOnListener(any());
-
- // Register a different listener
- mListener.register(getExecutor(), mockListener2);
- verify(mNfcAdapter, times(2)).registerControllerAlwaysOnListener(any());
-
- // Ensure first and second listener were invoked
- mListener.onControllerAlwaysOnChanged(true);
- verifyListenerInvoked(mockListener1);
- verifyListenerInvoked(mockListener2);
- }
-
- @Test
- public void testRegister_RegisterSameListenerTwice() throws RemoteException {
- doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
- NfcControllerAlwaysOnListener mListener =
- new NfcControllerAlwaysOnListener(mNfcAdapter);
- ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
-
- // Register the same listener Twice
- mListener.register(getExecutor(), mockListener);
- mListener.register(getExecutor(), mockListener);
- verify(mNfcAdapter, times(1)).registerControllerAlwaysOnListener(any());
-
- // Invoke a state change and ensure the listener is only called once
- mListener.onControllerAlwaysOnChanged(true);
- verifyListenerInvoked(mockListener);
- }
-
- @Test
- public void testNotify_AllListenersNotified() throws RemoteException {
- doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
- NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
- List<ControllerAlwaysOnListener> mockListeners = new ArrayList<>();
- for (int i = 0; i < 10; i++) {
- ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
- listener.register(getExecutor(), mockListener);
- mockListeners.add(mockListener);
- }
-
- // Invoke a state change and ensure all listeners are invoked
- listener.onControllerAlwaysOnChanged(true);
- for (ControllerAlwaysOnListener mListener : mockListeners) {
- verifyListenerInvoked(mListener);
- }
- }
-
- @Test
- public void testStateChange_CorrectValue() throws RemoteException {
- doReturn(true).when(mNfcAdapter).isControllerAlwaysOnSupported();
- runStateChangeValue(true, true);
- runStateChangeValue(false, false);
-
- }
-
- private void runStateChangeValue(boolean isEnabledIn, boolean isEnabledOut) {
- NfcControllerAlwaysOnListener listener = new NfcControllerAlwaysOnListener(mNfcAdapter);
- ControllerAlwaysOnListener mockListener = mock(ControllerAlwaysOnListener.class);
- listener.register(getExecutor(), mockListener);
- listener.onControllerAlwaysOnChanged(isEnabledIn);
- verify(mockListener, times(1)).onControllerAlwaysOnChanged(isEnabledOut);
- verify(mockListener, times(0)).onControllerAlwaysOnChanged(!isEnabledOut);
- }
-}
diff --git a/nfc/tests/src/android/nfc/TechListParcelTest.java b/nfc/tests/src/android/nfc/TechListParcelTest.java
deleted file mode 100644
index a12bbbc6884b..000000000000
--- a/nfc/tests/src/android/nfc/TechListParcelTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-
-@RunWith(AndroidJUnit4.class)
-public class TechListParcelTest {
-
- private static final String[] TECH_LIST_1 = new String[] { "tech1.1", "tech1.2" };
- private static final String[] TECH_LIST_2 = new String[] { "tech2.1" };
- private static final String[] TECH_LIST_EMPTY = new String[] {};
-
- @Test
- public void testWriteParcel() {
- TechListParcel techListParcel = new TechListParcel(TECH_LIST_1, TECH_LIST_2);
-
- Parcel parcel = Parcel.obtain();
- techListParcel.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- TechListParcel actualTechList =
- TechListParcel.CREATOR.createFromParcel(parcel);
- parcel.recycle();
-
- assertThat(actualTechList.getTechLists().length).isEqualTo(2);
- assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_1)).isTrue();
- assertThat(Arrays.equals(actualTechList.getTechLists()[1], TECH_LIST_2)).isTrue();
- }
-
- @Test
- public void testWriteParcelArrayEmpty() {
- TechListParcel techListParcel = new TechListParcel();
-
- Parcel parcel = Parcel.obtain();
- techListParcel.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- TechListParcel actualTechList =
- TechListParcel.CREATOR.createFromParcel(parcel);
- parcel.recycle();
-
- assertThat(actualTechList.getTechLists().length).isEqualTo(0);
- }
-
- @Test
- public void testWriteParcelElementEmpty() {
- TechListParcel techListParcel = new TechListParcel(TECH_LIST_EMPTY);
-
- Parcel parcel = Parcel.obtain();
- techListParcel.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- TechListParcel actualTechList =
- TechListParcel.CREATOR.createFromParcel(parcel);
- parcel.recycle();
-
- assertThat(actualTechList.getTechLists().length).isEqualTo(1);
- assertThat(Arrays.equals(actualTechList.getTechLists()[0], TECH_LIST_EMPTY)).isTrue();
- }
-
-}
diff --git a/omapi/OWNERS b/omapi/OWNERS
index 39c5c5bdeb09..375d643f7ed1 100644
--- a/omapi/OWNERS
+++ b/omapi/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 456592
-include platform/packages/apps/Nfc:/OWNERS
+include platform/packages/modules/Nfc:/OWNERS
diff --git a/omapi/java/android/se/OWNERS b/omapi/java/android/se/OWNERS
index 39c5c5bdeb09..375d643f7ed1 100644
--- a/omapi/java/android/se/OWNERS
+++ b/omapi/java/android/se/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 456592
-include platform/packages/apps/Nfc:/OWNERS
+include platform/packages/modules/Nfc:/OWNERS
diff --git a/omapi/java/android/se/omapi/OWNERS b/omapi/java/android/se/omapi/OWNERS
index 39c5c5bdeb09..375d643f7ed1 100644
--- a/omapi/java/android/se/omapi/OWNERS
+++ b/omapi/java/android/se/omapi/OWNERS
@@ -1,2 +1,2 @@
# Bug component: 456592
-include platform/packages/apps/Nfc:/OWNERS
+include platform/packages/modules/Nfc:/OWNERS
diff --git a/opengl/java/android/opengl/OWNERS b/opengl/java/android/opengl/OWNERS
index e340bc62567a..4ec9e29c48b0 100644
--- a/opengl/java/android/opengl/OWNERS
+++ b/opengl/java/android/opengl/OWNERS
@@ -3,4 +3,3 @@
sumir@google.com
prahladk@google.com
ianelliott@google.com
-lpy@google.com
diff --git a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
index 4fea9372971d..595325ba53c4 100644
--- a/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/platform/java/com/android/server/PackageWatchdog.java
@@ -1288,8 +1288,6 @@ public class PackageWatchdog {
Slog.w(TAG, "Failed to save monitored packages, restoring backup", e);
mPolicyFile.failWrite(stream);
return false;
- } finally {
- IoUtils.closeQuietly(stream);
}
}
}
@@ -1937,15 +1935,19 @@ public class PackageWatchdog {
bootMitigationCounts.put(observer.name, observer.getBootMitigationCount());
}
+ FileOutputStream fileStream = null;
+ ObjectOutputStream objectStream = null;
try {
- FileOutputStream fileStream = new FileOutputStream(new File(filePath));
- ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
+ fileStream = new FileOutputStream(new File(filePath));
+ objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(bootMitigationCounts);
objectStream.flush();
- objectStream.close();
- fileStream.close();
} catch (Exception e) {
Slog.i(TAG, "Could not save observers metadata to file: " + e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(objectStream);
+ IoUtils.closeQuietly(fileStream);
}
}
@@ -2096,23 +2098,32 @@ public class PackageWatchdog {
void readAllObserversBootMitigationCountIfNecessary(String filePath) {
File metadataFile = new File(filePath);
if (metadataFile.exists()) {
+ FileInputStream fileStream = null;
+ ObjectInputStream objectStream = null;
+ HashMap<String, Integer> bootMitigationCounts = null;
try {
- FileInputStream fileStream = new FileInputStream(metadataFile);
- ObjectInputStream objectStream = new ObjectInputStream(fileStream);
- HashMap<String, Integer> bootMitigationCounts =
+ fileStream = new FileInputStream(metadataFile);
+ objectStream = new ObjectInputStream(fileStream);
+ bootMitigationCounts =
(HashMap<String, Integer>) objectStream.readObject();
- objectStream.close();
- fileStream.close();
-
- for (int i = 0; i < mAllObservers.size(); i++) {
- final ObserverInternal observer = mAllObservers.valueAt(i);
- if (bootMitigationCounts.containsKey(observer.name)) {
- observer.setBootMitigationCount(
- bootMitigationCounts.get(observer.name));
- }
- }
} catch (Exception e) {
Slog.i(TAG, "Could not read observer metadata file: " + e);
+ return;
+ } finally {
+ IoUtils.closeQuietly(objectStream);
+ IoUtils.closeQuietly(fileStream);
+ }
+
+ if (bootMitigationCounts == null || bootMitigationCounts.isEmpty()) {
+ Slog.i(TAG, "No observer in metadata file");
+ return;
+ }
+ for (int i = 0; i < mAllObservers.size(); i++) {
+ final ObserverInternal observer = mAllObservers.valueAt(i);
+ if (bootMitigationCounts.containsKey(observer.name)) {
+ observer.setBootMitigationCount(
+ bootMitigationCounts.get(observer.name));
+ }
}
}
}
diff --git a/packages/CredentialManager/tests/robotests/Android.bp b/packages/CredentialManager/tests/robotests/Android.bp
index 27afaaa49fdd..01f403d3719d 100644
--- a/packages/CredentialManager/tests/robotests/Android.bp
+++ b/packages/CredentialManager/tests/robotests/Android.bp
@@ -53,7 +53,6 @@ android_robolectric_test {
"android.test.mock.stubs.system",
"truth",
],
- upstream: true,
java_resource_dirs: ["config"],
instrumentation_for: "CredentialManagerRobo",
}
diff --git a/packages/CredentialManager/wear/robotests/Android.bp b/packages/CredentialManager/wear/robotests/Android.bp
index 589a3d6cc103..db3c36355dde 100644
--- a/packages/CredentialManager/wear/robotests/Android.bp
+++ b/packages/CredentialManager/wear/robotests/Android.bp
@@ -24,6 +24,5 @@ android_robolectric_test {
"framework_graphics_flags_java_lib",
],
java_resource_dirs: ["config"],
- upstream: true,
strict_mode: false,
}
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt b/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt
index fb5954ec9736..4f5a88e85457 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Autopilot.kt
@@ -43,7 +43,7 @@ class Autopilot(val ship: Spacecraft, val universe: Universe) : Entity {
get() =
listOf(
"---- AUTOPILOT ENGAGED ----",
- "TGT: " + (target?.name?.toUpperCase() ?: "SELECTING..."),
+ "TGT: " + (target?.name?.uppercase() ?: "SELECTING..."),
"EXE: $strategy" + if (debug.isNotEmpty()) " ($debug)" else "",
)
.joinToString("\n")
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
index 16ec1a933d92..927216e54b5e 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/MainActivity.kt
@@ -64,7 +64,6 @@ import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -226,7 +225,7 @@ fun Telemetry(universe: VisibleUniverse) {
val distToClosest = ((closest.pos - pos).mag() - closest.radius).toInt()
listOfNotNull(
landing?.let {
- "LND: ${it.planet.name.toUpperCase()}\nJOB: ${it.text}"
+ "LND: ${it.planet.name.uppercase()}\nJOB: ${it.text}"
}
?: if (distToClosest < 10_000) {
"ALT: $distToClosest"
diff --git a/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
index 73318077f47a..28e56d045ed9 100644
--- a/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
+++ b/packages/EasterEgg/src/com/android/egg/landroid/Namer.kt
@@ -121,6 +121,6 @@ class Namer(resources: Resources) {
else -> "unknown template tag: ${it.groupValues[0]}"
}
}
- .toUpperCase()
+ .uppercase()
}
}
diff --git a/packages/ExtShared/Android.bp b/packages/ExtShared/Android.bp
index b1fd7f64292d..58016f78782a 100644
--- a/packages/ExtShared/Android.bp
+++ b/packages/ExtShared/Android.bp
@@ -38,6 +38,7 @@ android_app {
aaptflags: ["--shared-lib"],
export_package_resources: true,
optimize: {
+ keep_runtime_invisible_annotations: true,
proguard_flags_files: ["proguard.proguard"],
},
}
diff --git a/packages/ExtShared/proguard.proguard b/packages/ExtShared/proguard.proguard
index e5dfbe1c453d..699fbdaaadad 100644
--- a/packages/ExtShared/proguard.proguard
+++ b/packages/ExtShared/proguard.proguard
@@ -1,6 +1,8 @@
-keepparameternames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
- SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
+ SourceFile,LineNumberTable,EnclosingMethod,
+ RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,
+ RuntimeVisibleTypeAnnotations,AnnotationDefault
-keep public class * {
public protected *;
diff --git a/packages/NeuralNetworks/OWNERS b/packages/NeuralNetworks/OWNERS
index 6b391503b5c4..bf3c8fe1550f 100644
--- a/packages/NeuralNetworks/OWNERS
+++ b/packages/NeuralNetworks/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 195575
sandeepbandaru@google.com
-shivanker@google.com
-shiqing@google.com \ No newline at end of file
+shiqing@google.com
diff --git a/packages/SettingsLib/DataStore/tests/Android.bp b/packages/SettingsLib/DataStore/tests/Android.bp
index 2e3b42de5b9d..6044eaba5f89 100644
--- a/packages/SettingsLib/DataStore/tests/Android.bp
+++ b/packages/SettingsLib/DataStore/tests/Android.bp
@@ -25,6 +25,5 @@ android_robolectric_test {
java_resource_dirs: ["config"],
instrumentation_for: "SettingsLibDataStoreShell",
coverage_libs: ["SettingsLibDataStore"],
- upstream: true,
strict_mode: false,
}
diff --git a/packages/SettingsLib/Ipc/Android.bp b/packages/SettingsLib/Ipc/Android.bp
index 2c7209a48bbd..bc5a9364279d 100644
--- a/packages/SettingsLib/Ipc/Android.bp
+++ b/packages/SettingsLib/Ipc/Android.bp
@@ -25,7 +25,7 @@ android_library {
name: "SettingsLibIpc-testutils",
srcs: ["testutils/**/*.kt"],
static_libs: [
- "Robolectric_all-target_upstream",
+ "Robolectric_all-target",
"SettingsLibIpc",
"androidx.test.core",
"flag-junit",
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index e4bc7b4660e1..7348920dfd3d 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -3,10 +3,12 @@ cantol@google.com
chiujason@google.com
cipson@google.com
dsandler@android.com
+dswliu@google.com
edgarwang@google.com
evanlaird@google.com
jiannan@google.com
juliacr@google.com
+millchen@google.com
ykhung@google.com
# Exempt resource files (because they are in a flat directory and too hard to manage via OWNERS)
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/Android.bp b/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
index f6477e2f052a..dd6743b8595c 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
+++ b/packages/SettingsLib/Spa/screenshot/robotests/Android.bp
@@ -68,7 +68,6 @@ android_robolectric_test {
"android.test.mock.stubs.system",
"truth",
],
- upstream: true,
java_resource_dirs: ["config"],
instrumentation_for: "SpaRoboApp",
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
index 0d73cb3e63c9..798e2d49ff57 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPageTest.kt
@@ -160,23 +160,25 @@ class TogglePermissionAppInfoPageTest {
@Test
fun infoPage_whenChangeableAndClick() {
val listModel = TestTogglePermissionAppListModel(isAllowed = false, isChangeable = true)
+ val switchTitle = context.getString(listModel.switchTitleResId)
setTogglePermissionAppInfoPage(listModel)
- composeTestRule.onNodeWithText(context.getString(listModel.switchTitleResId)).performClick()
+ composeTestRule.waitUntilExists(hasText(switchTitle))
+ composeTestRule.onNodeWithText(switchTitle).performClick()
- composeTestRule.waitUntilExists(
- hasText(context.getString(listModel.switchTitleResId)) and isOn())
+ composeTestRule.waitUntilExists(hasText(switchTitle) and isOn())
}
@Test
fun infoPage_whenNotChangeableAndClick() {
val listModel = TestTogglePermissionAppListModel(isAllowed = false, isChangeable = false)
+ val switchTitle = context.getString(listModel.switchTitleResId)
setTogglePermissionAppInfoPage(listModel)
- composeTestRule.onNodeWithText(context.getString(listModel.switchTitleResId)).performClick()
+ composeTestRule.waitUntilExists(hasText(switchTitle))
+ composeTestRule.onNodeWithText(switchTitle).performClick()
- composeTestRule.waitUntilExists(
- hasText(context.getString(listModel.switchTitleResId)) and isOff())
+ composeTestRule.waitUntilExists(hasText(switchTitle) and isOff())
}
@Test
diff --git a/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS b/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS
index 9f15c1bb5081..b676d8daad52 100644
--- a/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/connectivity/OWNERS
@@ -1,6 +1,5 @@
# Default reviewers for this and subdirectories.
andychou@google.com
-arcwang@google.com
changbetty@google.com
qal@google.com
wengsu@google.com
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/OWNERS b/packages/SettingsLib/src/com/android/settingslib/media/OWNERS
index d58add4bb5eb..a34876dd1e0e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/media/OWNERS
@@ -3,5 +3,8 @@ ethibodeau@google.com
michaelmikhil@google.com
apotapov@google.com
+# Output Switcher OWNERS
+file:/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
+
#Android Media - For minor changes and renames only.
aquilescanta@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/packages/SettingsLib/src/com/android/settingslib/qrcode/OWNERS b/packages/SettingsLib/src/com/android/settingslib/qrcode/OWNERS
index 372eb81fdee2..921ffedb337c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/qrcode/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/qrcode/OWNERS
@@ -1,5 +1,4 @@
# Default reviewers for this and subdirectories.
-bonianchen@google.com
changbetty@google.com
wengsu@google.com
zoeychen@google.com
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
index b9449acc6f7d..50bfe8c7cd78 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/OWNERS
@@ -1,6 +1,5 @@
# Default reviewers for this and subdirectories.
andychou@google.com
-arcwang@google.com
asapperstein@google.com
changbetty@google.com
qal@google.com
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index f380e7f7e7a6..117ca85c2761 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -65,7 +65,6 @@ android_robolectric_test {
test_options: {
timeout: 36000,
},
- upstream: true,
strict_mode: false,
}
@@ -76,7 +75,6 @@ java_genrule {
tools: ["soong_zip"],
cmd: "mkdir -p $(genDir)/META-INF/services/ && touch $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider &&" +
"echo -e 'org.robolectric.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
- "echo -e 'org.robolectric.shadows.multidex.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
"echo -e 'org.robolectric.shadows.httpclient.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
//"echo -e 'com.android.settings.testutils.shadow.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
"echo -e 'com.android.settingslib.testutils.shadow.Shadows' >> $(genDir)/META-INF/services/org.robolectric.internal.ShadowProvider && " +
@@ -101,10 +99,10 @@ java_library {
plugins: [
"auto_value_plugin_1.9",
"auto_value_builder_plugin_1.9",
- "Robolectric_processor_upstream",
+ "Robolectric_processor",
],
libs: [
- "Robolectric_all-target_upstream",
+ "Robolectric_all-target",
"mockito-robolectric-prebuilt",
"truth",
],
diff --git a/packages/SettingsLib/tests/robotests/fragment/Android.bp b/packages/SettingsLib/tests/robotests/fragment/Android.bp
index 3e67156af0c4..0214874979f3 100644
--- a/packages/SettingsLib/tests/robotests/fragment/Android.bp
+++ b/packages/SettingsLib/tests/robotests/fragment/Android.bp
@@ -28,13 +28,13 @@ java_library {
//"-J-verbose",
],
libs: [
- "Robolectric_all-target_upstream",
+ "Robolectric_all-target",
"androidx.fragment_fragment",
],
plugins: [
"auto_value_plugin_1.9",
"auto_value_builder_plugin_1.9",
- "Robolectric_processor_upstream",
+ "Robolectric_processor",
],
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index 1eff0eee606d..de7c450d8d39 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -72,7 +72,6 @@ import java.util.regex.Pattern;
public final class DeviceConfigService extends Binder {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
- "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
@@ -149,27 +148,7 @@ public final class DeviceConfigService extends Binder {
// TODO(b/364399200): use filter to skip instead?
return;
}
-
- ArrayList<String> missingFiles = new ArrayList<String>();
- for (String fileName : sAconfigTextProtoFilesOnDevice) {
- File aconfigFile = new File(fileName);
- if (!aconfigFile.exists()) {
- missingFiles.add(fileName);
- }
- }
-
- if (missingFiles.isEmpty()) {
- pw.println("\nAconfig flags:");
- for (String name : MyShellCommand.listAllAconfigFlags(iprovider)) {
- pw.println(name);
- }
- } else {
- pw.println("\nFailed to dump aconfig flags due to missing files:");
- for (String fileName : missingFiles) {
- pw.println(fileName);
- }
- }
- }
+ }
private static HashSet<String> getAconfigFlagNamesInDeviceConfig() {
HashSet<String> nameSet = new HashSet<String>();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 7aed61533aac..99c4e21c6053 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -18,10 +18,13 @@ package com.android.providers.settings;
import static android.os.Process.FIRST_APPLICATION_UID;
+import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
+
import android.aconfig.Aconfig.flag_permission;
import android.aconfig.Aconfig.flag_state;
import android.aconfig.Aconfig.parsed_flag;
import android.aconfig.Aconfig.parsed_flags;
+import android.aconfigd.AconfigdFlagInfo;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -65,14 +68,10 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
-import java.io.InputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.PosixFileAttributes;
-import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -84,18 +83,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
-// FOR ACONFIGD TEST MISSION AND ROLLOUT
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import android.util.proto.ProtoInputStream;
-import android.aconfigd.Aconfigd.StorageRequestMessage;
-import android.aconfigd.Aconfigd.StorageRequestMessages;
-import android.aconfigd.Aconfigd.StorageReturnMessage;
-import android.aconfigd.Aconfigd.StorageReturnMessages;
-import android.aconfigd.AconfigdClientSocket;
-import android.aconfigd.AconfigdFlagInfo;
-import android.aconfigd.AconfigdJavaUtils;
-import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
/**
* This class contains the state for one type of settings. It is responsible
* for saving the state asynchronously to an XML file after a mutation and
@@ -107,7 +94,7 @@ import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
* the same lock to grab the current state to write to disk.
* </p>
*/
-final class SettingsState {
+public class SettingsState {
private static final boolean DEBUG = false;
private static final boolean DEBUG_PERSISTENCE = false;
@@ -171,7 +158,6 @@ final class SettingsState {
private static final List<String> sAconfigTextProtoFilesOnDevice = List.of(
"/system/etc/aconfig_flags.pb",
- "/system_ext/etc/aconfig_flags.pb",
"/product/etc/aconfig_flags.pb",
"/vendor/etc/aconfig_flags.pb");
@@ -394,94 +380,9 @@ final class SettingsState {
getAllAconfigFlagsFromSettings(mAconfigDefaultFlags);
}
}
-
- if (isConfigSettingsKey(mKey)) {
- requests = handleBulkSyncToNewStorage(mAconfigDefaultFlags);
- }
- }
-
- if (enableAconfigStorageDaemon()) {
- if (isConfigSettingsKey(mKey)){
- AconfigdClientSocket localSocket = AconfigdJavaUtils.getAconfigdClientSocket();
- if (requests != null) {
- InputStream res = localSocket.send(requests.getBytes());
- if (res == null) {
- Slog.w(LOG_TAG, "Bulk sync request to acongid failed.");
- }
- }
-
- if (Flags.disableBulkCompare()) {
- return;
- }
-
- // TOBO(b/312444587): remove the comparison logic after Test Mission 2.
- if (requests == null) {
- Map<String, AconfigdFlagInfo> aconfigdFlagMap =
- AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
- compareFlagValueInNewStorage(
- mAconfigDefaultFlags,
- aconfigdFlagMap);
- }
- }
}
}
- // TODO(b/312444587): remove the comparison logic after Test Mission 2.
- public int compareFlagValueInNewStorage(
- Map<String, AconfigdFlagInfo> defaultFlagMap,
- Map<String, AconfigdFlagInfo> aconfigdFlagMap) {
-
- // Get all defaults from the default map. The mSettings may not contain
- // all flags, since it only contains updated flags.
- int diffNum = 0;
- for (Map.Entry<String, AconfigdFlagInfo> entry : defaultFlagMap.entrySet()) {
- String key = entry.getKey();
- AconfigdFlagInfo flag = entry.getValue();
-
- AconfigdFlagInfo aconfigdFlag = aconfigdFlagMap.get(key);
- if (aconfigdFlag == null) {
- Slog.w(LOG_TAG, String.format("Flag %s is missing from aconfigd", key));
- diffNum++;
- continue;
- }
- String diff = flag.dumpDiff(aconfigdFlag);
- if (!diff.isEmpty()) {
- Slog.w(
- LOG_TAG,
- String.format(
- "Flag %s is different in Settings and aconfig: %s", key, diff));
- diffNum++;
- }
- }
-
- for (String key : aconfigdFlagMap.keySet()) {
- if (defaultFlagMap.containsKey(key)) continue;
- Slog.w(LOG_TAG, String.format("Flag %s is missing from Settings", key));
- diffNum++;
- }
-
- String compareMarkerName = "aconfigd_marker/compare_diff_num";
- synchronized (mLock) {
- Setting markerSetting = mSettings.get(compareMarkerName);
- if (markerSetting == null) {
- markerSetting =
- new Setting(
- compareMarkerName,
- String.valueOf(diffNum),
- false,
- "aconfig",
- "aconfig");
- mSettings.put(compareMarkerName, markerSetting);
- }
- markerSetting.value = String.valueOf(diffNum);
- }
-
- if (diffNum == 0) {
- Slog.w(LOG_TAG, "Settings and new storage have same flags.");
- }
- return diffNum;
- }
-
@GuardedBy("mLock")
public int getAllAconfigFlagsFromSettings(
@NonNull Map<String, AconfigdFlagInfo> flagInfoDefault) {
@@ -552,95 +453,19 @@ final class SettingsState {
return flag;
}
-
- // TODO(b/341764371): migrate aconfig flag push to GMS core
- @VisibleForTesting
- @GuardedBy("mLock")
- public ProtoOutputStream handleBulkSyncToNewStorage(
- Map<String, AconfigdFlagInfo> aconfigFlagMap) {
- // get marker or add marker if it does not exist
- Setting markerSetting = mSettings.get(BULK_SYNC_MARKER);
- int localCounter = 0;
- if (markerSetting == null) {
- markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig");
- mSettings.put(BULK_SYNC_MARKER, markerSetting);
- }
- try {
- localCounter = Integer.parseInt(markerSetting.value);
- } catch (NumberFormatException e) {
- // reset local counter
- markerSetting.value = "0";
- }
-
- if (enableAconfigStorageDaemon()) {
- Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER);
- int serverCounter = 0;
- if (bulkSyncCounter != null) {
- try {
- serverCounter = Integer.parseInt(bulkSyncCounter.value);
- } catch (NumberFormatException e) {
- // reset the local value of server counter
- bulkSyncCounter.value = "0";
- }
- }
-
- boolean shouldSync = localCounter < serverCounter;
- if (!shouldSync) {
- // CASE 1, flag is on, bulk sync marker true, nothing to do
- return null;
- } else {
- // CASE 2, flag is on, bulk sync marker false. Do following two tasks
- // (1) Do bulk sync here.
- // (2) After bulk sync, set marker to true.
-
- // first add storage reset request
- ProtoOutputStream requests = new ProtoOutputStream();
- AconfigdJavaUtils.writeResetStorageRequest(requests);
-
- // loop over all settings and add flag override requests
- for (AconfigdFlagInfo flag : aconfigFlagMap.values()) {
- // don't sync read_only flags
- if (!flag.getIsReadWrite()) {
- continue;
- }
-
- if (flag.getHasServerOverride()) {
- AconfigdJavaUtils.writeFlagOverrideRequest(
- requests,
- flag.getPackageName(),
- flag.getFlagName(),
- flag.getServerFlagValue(),
- StorageRequestMessage.SERVER_ON_REBOOT);
- }
-
- if (flag.getHasLocalOverride()) {
- AconfigdJavaUtils.writeFlagOverrideRequest(
- requests,
- flag.getPackageName(),
- flag.getFlagName(),
- flag.getLocalFlagValue(),
- StorageRequestMessage.LOCAL_ON_REBOOT);
- }
- }
-
- // mark sync has been done
- markerSetting.value = String.valueOf(serverCounter);
- scheduleWriteIfNeededLocked();
- return requests;
- }
- } else {
- return null;
- }
- }
-
@GuardedBy("mLock")
private void loadAconfigDefaultValuesLocked(List<String> filePaths) {
for (String fileName : filePaths) {
- try (FileInputStream inputStream = new FileInputStream(fileName)) {
- loadAconfigDefaultValues(
- inputStream.readAllBytes(), mNamespaceDefaults, mAconfigDefaultFlags);
- } catch (IOException e) {
- Slog.e(LOG_TAG, "failed to read protobuf", e);
+ File f = new File(fileName);
+ if (f.isFile() && f.canRead()) {
+ try (FileInputStream inputStream = new FileInputStream(fileName)) {
+ loadAconfigDefaultValues(
+ inputStream.readAllBytes(), mNamespaceDefaults, mAconfigDefaultFlags);
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "failed to read protobuf", e);
+ }
+ } else {
+ Slog.d(LOG_TAG, "No protobuf file at " + fileName);
}
}
}
@@ -1839,7 +1664,7 @@ final class SettingsState {
}
}
- class Setting {
+ public class Setting {
private String name;
private String value;
private String defaultValue;
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 276b206cd6a1..13eb1d4b2603 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -31,19 +31,20 @@ import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Xml;
-import android.util.proto.ProtoOutputStream;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.TypedXmlSerializer;
-import android.platform.test.annotations.EnableFlags;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.flag.junit.SetFlagsRule;
-
import com.google.common.base.Strings;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -52,11 +53,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class SettingsStateTest {
@@ -1085,124 +1081,6 @@ public class SettingsStateTest {
assertTrue(flag1.getHasLocalOverride());
}
- @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
- @Test
- @EnableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON)
- public void testHandleBulkSyncWithAconfigdEnabled() {
- int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
- Object lock = new Object();
- SettingsState settingsState =
- new SettingsState(
- InstrumentationRegistry.getContext(),
- lock,
- mSettingsFile,
- configKey,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED,
- Looper.getMainLooper());
-
- Map<String, AconfigdFlagInfo> flags = new HashMap<>();
- flags.put(
- "com.android.flags/flag1",
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag1")
- .setBootFlagValue("true")
- .setIsReadWrite(true)
- .build());
-
- flags.put(
- "com.android.flags/flag2",
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag2")
- .setBootFlagValue("true")
- .setIsReadWrite(false)
- .build());
-
- String bulkSyncMarker = "aconfigd_marker/bulk_synced";
- String bulkSyncCounter =
- "core_experiments_team_internal/" +
- "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
-
- synchronized (lock) {
- settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
- settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
- "com.google.android.platform.core_experiments_team_internal");
-
- // first bulk sync
- ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertTrue(requests != null);
- String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("1", value);
-
- // send time should no longer bulk sync
- requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("1", value);
-
- // won't sync if the marker is string
- settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig");
- settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false,
- "com.google.android.platform.core_experiments_team_internal");
- requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("0", value);
-
- // won't sync if the marker and counter value are the same
- settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig");
- settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
- "com.google.android.platform.core_experiments_team_internal");
- requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("1", value);
- }
- }
-
- @Test
- @DisableFlags(com.android.aconfig_new_storage.Flags.FLAG_ENABLE_ACONFIG_STORAGE_DAEMON)
- public void testHandleBulkSyncWithAconfigdDisabled() {
- int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
- Object lock = new Object();
- SettingsState settingsState = new SettingsState(
- InstrumentationRegistry.getContext(), lock, mSettingsFile, configKey,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
-
- Map<String, AconfigdFlagInfo> flags = new HashMap<>();
- String bulkSyncMarker = "aconfigd_marker/bulk_synced";
- String bulkSyncCounter =
- "core_experiments_team_internal/" +
- "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
- synchronized (lock) {
- settingsState.insertSettingLocked("aconfigd_marker/bulk_synced",
- "true", null, false, "aconfig");
-
- // when aconfigd is off, should change the marker to false
- ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("0", value);
-
- // marker started with false value, after call, it should remain false
- requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("0", value);
-
- // won't sync
- settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
- settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
- "com.google.android.platform.core_experiments_team_internal");
- requests = settingsState.handleBulkSyncToNewStorage(flags);
- assertNull(requests);
- value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
- assertEquals("0", value);
- }
- }
-
@Test
public void testGetAllAconfigFlagsFromSettings() throws Exception {
final Object lock = new Object();
@@ -1303,85 +1181,4 @@ public class SettingsStateTest {
assertFalse(flag3.getHasServerOverride());
assertFalse(flag3.getHasLocalOverride());
}
-
- @Test
- @RequiresFlagsDisabled(Flags.FLAG_DISABLE_BULK_COMPARE)
- public void testCompareFlagValueInNewStorage() {
- int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
- Object lock = new Object();
- SettingsState settingsState =
- new SettingsState(
- InstrumentationRegistry.getContext(),
- lock,
- mSettingsFile,
- configKey,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED,
- Looper.getMainLooper());
-
- AconfigdFlagInfo defaultFlag1 =
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag1")
- .setDefaultFlagValue("false")
- .setServerFlagValue("true")
- .setHasServerOverride(true)
- .setIsReadWrite(true)
- .build();
-
- AconfigdFlagInfo expectedFlag1 =
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag1")
- .setServerFlagValue("true")
- .setDefaultFlagValue("false")
- .setHasServerOverride(true)
- .setIsReadWrite(true)
- .build();
-
- Map<String, AconfigdFlagInfo> aconfigdMap = new HashMap<>();
- Map<String, AconfigdFlagInfo> defaultMap = new HashMap<>();
-
- defaultMap.put("com.android.flags.flag1", defaultFlag1);
- aconfigdMap.put("com.android.flags.flag1", expectedFlag1);
-
- int ret = settingsState.compareFlagValueInNewStorage(defaultMap, aconfigdMap);
- assertEquals(0, ret);
-
- String value =
- settingsState.getSettingLocked("aconfigd_marker/compare_diff_num").getValue();
- assertEquals("0", value);
-
- AconfigdFlagInfo defaultFlag2 =
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag2")
- .setDefaultFlagValue("false")
- .build();
- defaultMap.put("com.android.flags.flag2", defaultFlag2);
-
- ret = settingsState.compareFlagValueInNewStorage(defaultMap, aconfigdMap);
- // missing from new storage
- assertEquals(1, ret);
- value =
- settingsState.getSettingLocked("aconfigd_marker/compare_diff_num").getValue();
- assertEquals("1", value);
-
- AconfigdFlagInfo expectedFlag2 =
- AconfigdFlagInfo.newBuilder()
- .setPackageName("com.android.flags")
- .setFlagName("flag2")
- .setServerFlagValue("true")
- .setLocalFlagValue("true")
- .setDefaultFlagValue("false")
- .setHasServerOverride(true)
- .setHasLocalOverride(true)
- .build();
- aconfigdMap.put("com.android.flags.flag2", expectedFlag2);
- ret = settingsState.compareFlagValueInNewStorage(defaultMap, aconfigdMap);
- // skip the server and local value comparison when the flag is read_only
- assertEquals(0, ret);
- value =
- settingsState.getSettingLocked("aconfigd_marker/compare_diff_num").getValue();
- assertEquals("0", value);
- }
}
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index d4b5b86223ea..897c1fe7639e 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -4,12 +4,13 @@ ronish@google.com
jsharkey@android.com
felipeal@google.com
nandana@google.com
-svetoslavganov@google.com
hackbod@google.com
yamasani@google.com
-toddke@google.com
patb@google.com
-cbrubaker@google.com
omakoto@google.com
michaelwr@google.com
ronish@google.com
+
+# Wear Bugreport Owners
+ranamouawi@google.com
+yashasvig@google.com
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 0694b6123c11..c6555041164d 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -257,6 +257,9 @@ public class BugreportProgressService extends Service {
/** Always keep remote bugreport files created in the last day. */
private static final long REMOTE_MIN_KEEP_AGE = DateUtils.DAY_IN_MILLIS;
+ /** Minimum delay for sending last update notification */
+ private static final int DELAY_NOTIFICATION_MS = 250;
+
private final Object mLock = new Object();
/** Managed bugreport info (keyed by id) */
@@ -927,6 +930,7 @@ public class BugreportProgressService extends Service {
Log.d(TAG, "Progress #" + info.id + ": " + percentageText);
}
info.lastProgress.set(progress);
+ info.lastUpdate.set(System.currentTimeMillis());
sendForegroundabledNotification(info.id, builder.build());
}
@@ -1455,6 +1459,16 @@ public class BugreportProgressService extends Service {
*/
private void sendBugreportNotification(BugreportInfo info, boolean takingScreenshot) {
+ final long lastUpdate = System.currentTimeMillis() - info.lastUpdate.longValue();
+ if (lastUpdate < DELAY_NOTIFICATION_MS) {
+ Log.d(TAG, "Delaying final notification for "
+ + (DELAY_NOTIFICATION_MS - lastUpdate) + " ms ");
+ mMainThreadHandler.postDelayed(() -> {
+ sendBugreportNotification(info, takingScreenshot);
+ }, DELAY_NOTIFICATION_MS - lastUpdate);
+ return;
+ }
+
// Since adding the details can take a while, do it before notifying user.
addDetailsToZipFile(info);
@@ -1475,6 +1489,7 @@ public class BugreportProgressService extends Service {
final Notification.Builder builder = newBaseNotification(mContext)
.setContentTitle(title)
.setTicker(title)
+ .setProgress(100 /* max value of progress percentage */, 100, false)
.setOnlyAlertOnce(false)
.setContentText(content);
@@ -2743,7 +2758,6 @@ public class BugreportProgressService extends Service {
}
}
info.progress.set(progress);
- info.lastUpdate.set(System.currentTimeMillis());
updateProgress(info);
}
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 050a3704df1f..7bda2ea790b0 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -193,7 +193,7 @@ public class BugreportReceiverTest {
mService.mScreenshotDelaySec = SCREENSHOT_DELAY_SECONDS;
// Dup the fds which are passing to startBugreport function.
Mockito.doAnswer(invocation -> {
- final boolean isScreenshotRequested = invocation.getArgument(6);
+ final boolean isScreenshotRequested = invocation.getArgument(7);
if (isScreenshotRequested) {
mScreenshotFd = ParcelFileDescriptor.dup(invocation.getArgument(3));
}
@@ -250,7 +250,22 @@ public class BugreportReceiverTest {
mIDumpstateListener.onProgress(300);
assertProgressNotification(mProgressTitle, 99);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 1);
+ assertActionSendMultiple(extras);
+
+ assertServiceNotRunning();
+ }
+
+ @Test
+ public void testStressProgress() throws Exception {
+ sendBugreportStarted();
+ waitForScreenshotButtonEnabled(true);
+
+ for (int i = 0; i <= 1000; i++) {
+ mIDumpstateListener.onProgress(i);
+ }
+ sendBugreportFinished();
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1);
assertActionSendMultiple(extras);
assertServiceNotRunning();
@@ -277,7 +292,7 @@ public class BugreportReceiverTest {
assertScreenshotButtonEnabled(false);
waitForScreenshotButtonEnabled(true);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 2);
assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1);
assertServiceNotRunning();
@@ -294,7 +309,7 @@ public class BugreportReceiverTest {
// There's no indication in the UI about the screenshot finish, so just sleep like a baby...
sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS);
- Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 2);
assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1);
assertServiceNotRunning();
@@ -328,7 +343,7 @@ public class BugreportReceiverTest {
assertProgressNotification(NEW_NAME, 00.00f);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE, 1);
assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
@@ -363,7 +378,7 @@ public class BugreportReceiverTest {
assertProgressNotification(NEW_NAME, 00.00f);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE, 1);
assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
@@ -390,7 +405,7 @@ public class BugreportReceiverTest {
detailsUi.descField.setText(mDescription);
detailsUi.clickOk();
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId, 1);
assertActionSendMultiple(extras, NO_NAME, NO_TITLE, mDescription, 0);
assertServiceNotRunning();
@@ -441,7 +456,7 @@ public class BugreportReceiverTest {
detailsUi.clickOk();
// Finally, share bugreport.
- Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1);
assertActionSendMultiple(extras, NO_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
@@ -504,7 +519,7 @@ public class BugreportReceiverTest {
mUiBot.click(ok, "ok");
// Share the bugreport.
- mUiBot.chooseActivity(UI_NAME);
+ mUiBot.chooseActivity(UI_NAME, mContext, 1);
Bundle extras = mListener.getExtras();
assertActionSendMultiple(extras);
@@ -531,7 +546,7 @@ public class BugreportReceiverTest {
sendBugreportFinished();
killService();
assertServiceNotRunning();
- Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId, 1);
assertActionSendMultiple(extras);
}
@@ -618,45 +633,49 @@ public class BugreportReceiverTest {
* Sends a "bugreport finished" event and waits for the result.
*
* @param id The bugreport id for finished notification string title substitution.
+ * @param count Number of files to be shared
* @return extras sent in the shared intent.
*/
- private Bundle sendBugreportFinishedAndGetSharedIntent(int id) throws Exception {
+ private Bundle sendBugreportFinishedAndGetSharedIntent(int id, int count) throws Exception {
sendBugreportFinished();
- return acceptBugreportAndGetSharedIntent(id);
+ return acceptBugreportAndGetSharedIntent(id, count);
}
/**
* Sends a "bugreport finished" event and waits for the result.
*
* @param notificationTitle The title of finished notification.
+ * @param count Number of files to be shared
* @return extras sent in the shared intent.
*/
- private Bundle sendBugreportFinishedAndGetSharedIntent(String notificationTitle)
+ private Bundle sendBugreportFinishedAndGetSharedIntent(String notificationTitle, int count)
throws Exception {
sendBugreportFinished();
- return acceptBugreportAndGetSharedIntent(notificationTitle);
+ return acceptBugreportAndGetSharedIntent(notificationTitle, count);
}
/**
* Accepts the notification to share the finished bugreport and waits for the result.
*
* @param id The bugreport id for finished notification string title substitution.
+ * @param count Number of files to be shared
* @return extras sent in the shared intent.
*/
- private Bundle acceptBugreportAndGetSharedIntent(int id) {
+ private Bundle acceptBugreportAndGetSharedIntent(int id, int count) {
final String notificationTitle = mContext.getString(R.string.bugreport_finished_title, id);
- return acceptBugreportAndGetSharedIntent(notificationTitle);
+ return acceptBugreportAndGetSharedIntent(notificationTitle, count);
}
/**
* Accepts the notification to share the finished bugreport and waits for the result.
*
* @param notificationTitle The title of finished notification.
+ * @param count Number of files to be shared
* @return extras sent in the shared intent.
*/
- private Bundle acceptBugreportAndGetSharedIntent(String notificationTitle) {
+ private Bundle acceptBugreportAndGetSharedIntent(String notificationTitle, int count) {
mUiBot.clickOnNotification(notificationTitle);
- mUiBot.chooseActivity(UI_NAME);
+ mUiBot.chooseActivity(UI_NAME, mContext, count);
return mListener.getExtras();
}
diff --git a/packages/Shell/tests/src/com/android/shell/UiBot.java b/packages/Shell/tests/src/com/android/shell/UiBot.java
index ce9f70d8b977..60008a353d81 100644
--- a/packages/Shell/tests/src/com/android/shell/UiBot.java
+++ b/packages/Shell/tests/src/com/android/shell/UiBot.java
@@ -18,9 +18,12 @@ package com.android.shell;
import android.app.Instrumentation;
import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.res.Resources;
import android.os.SystemClock;
import android.text.format.DateUtils;
import android.util.Log;
+import android.util.PluralsMessageFormatter;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
@@ -34,7 +37,9 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* A helper class for UI-related testing tasks.
@@ -206,11 +211,26 @@ final class UiBot {
*
* @param name name of the activity as displayed in the UI (typically the value set by
* {@code android:label} in the manifest).
+ * @param context Context of the target application
+ * @param count Number of files to be shared
*/
- public void chooseActivity(String name) {
+ public void chooseActivity(String name, Context context, int count) {
// It uses an intent chooser now, so just getting the activity by text is enough...
- final String share = mInstrumentation.getContext().getString(
- com.android.internal.R.string.share);
+ Resources res = null;
+ try {
+ res = context.getPackageManager()
+ .getResourcesForApplication("com.android.intentresolver");
+ } catch (Exception e) {
+ assertNotNull("could not get resources for com.android.intentresolver", res);
+ }
+ /* Resource read is defined as a string which contains a plural
+ * which needs some formatting */
+ Map<String, Object> arguments = new HashMap<>();
+ arguments.put("count", count);
+ final String share = PluralsMessageFormatter.format(
+ res,
+ arguments,
+ res.getIdentifier("sharing_files", "string", "com.android.intentresolver"));
boolean gotIt = mDevice.wait(Until.hasObject(By.text(share)), mTimeout);
assertTrue("could not get share activity (" + share + ")", gotIt);
swipeUp();
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 3d250fd82473..465652ed36b9 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -522,6 +522,7 @@ android_library {
"-Adagger.fastInit=enabled",
"-Adagger.explicitBindingConflictsWithInject=ERROR",
"-Adagger.strictMultibindingValidation=enabled",
+ "-Adagger.useBindingGraphFix=ENABLED",
"-Aroom.schemaLocation=frameworks/base/packages/SystemUI/schemas",
],
kotlincflags: ["-Xjvm-default=all"],
@@ -701,6 +702,9 @@ android_library {
use_resource_processor: true,
manifest: "tests/AndroidManifest-base.xml",
resource_dirs: [],
+
+ kotlin_lang_version: "1.9",
+
additional_manifests: ["tests/AndroidManifest.xml"],
srcs: [
"tests/src/**/*.kt",
@@ -747,6 +751,10 @@ android_library {
// TODO(b/352363800): Why do we need this?
"-J-Xmx8192M",
],
+ javacflags: [
+ "-Adagger.useBindingGraphFix=ENABLED",
+ ],
+
aaptflags: [
"--extra-packages",
"com.android.systemui",
@@ -837,8 +845,6 @@ android_robolectric_test {
"androidx.test.ext.truth",
],
- upstream: true,
-
instrumentation_for: "SystemUIRobo-stub",
java_resource_dirs: ["tests/robolectric/config"],
plugins: [
@@ -875,8 +881,6 @@ android_robolectric_test {
"androidx.test.ext.truth",
],
- upstream: true,
-
instrumentation_for: "SystemUIRobo-stub",
java_resource_dirs: ["tests/robolectric/config"],
plugins: [
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 795b39576391..236654deefb5 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -13,7 +13,6 @@ alexflo@google.com
andonian@google.com
amiko@google.com
austindelgado@google.com
-aroederer@google.com
arteiro@google.com
asc@google.com
awickham@google.com
@@ -24,6 +23,7 @@ bhinegardner@google.com
bhnm@google.com
brycelee@google.com
brzezinski@google.com
+burakov@google.com
caitlinshk@google.com
cameronyee@google.com
chandruis@google.com
@@ -39,6 +39,7 @@ florenceyang@google.com
gallmann@google.com
graciecheng@google.com
gwasserman@google.com
+helencheuk@google.com
hwwang@google.com
hyunyoungs@google.com
ikateryna@google.com
@@ -102,7 +103,6 @@ stwu@google.com
syeonlee@google.com
sunnygoyal@google.com
thiruram@google.com
-tkachenkoi@google.com
tracyzhou@google.com
tsuji@google.com
twickham@google.com
@@ -119,4 +119,5 @@ xuqiu@google.com
yeinj@google.com
yuandizhou@google.com
yurilin@google.com
+yuzhechen@google.com
zakcohen@google.com
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
index 0ff856e0b91e..1d74774c7c11 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
@@ -5,7 +5,7 @@ package {
aconfig_declarations {
name: "com_android_a11y_menu_flags",
package: "com.android.systemui.accessibility.accessibilitymenu",
- container: "system",
+ container: "system_ext",
srcs: [
"accessibility.aconfig",
],
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
index 6d790114803a..bdf6d4242e68 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/accessibility.aconfig
@@ -1,5 +1,5 @@
package: "com.android.systemui.accessibility.accessibilitymenu"
-container: "system"
+container: "system_ext"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
diff --git a/packages/SystemUI/compose/core/tests/AndroidManifest.xml b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
index 28f80d4af265..7c721b97ee47 100644
--- a/packages/SystemUI/compose/core/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
@@ -15,6 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.compose.core.tests" >
<application>
@@ -23,7 +24,8 @@
<activity
android:name="androidx.activity.ComponentActivity"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
- android:exported="true" />
+ android:exported="true"
+ tools:replace="android:theme" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/OWNERS b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/OWNERS
new file mode 100644
index 000000000000..739d2ac2e87b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/dialog/OWNERS
@@ -0,0 +1 @@
+file:/packages/SystemUI/src/com/android/systemui/media/dialog/OWNERS
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
index 9e4cf94df3de..0bb86da5d955 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
@@ -141,7 +141,7 @@ class DeviceControlsTileTest(flags: FlagsParameterization) : SysuiTestCase() {
if (featureEnabled) {
Optional.of(controlsController)
} else {
- Optional.empty()
+ Optional.empty<ControlsController>()
}
}
@@ -149,7 +149,7 @@ class DeviceControlsTileTest(flags: FlagsParameterization) : SysuiTestCase() {
if (featureEnabled) {
Optional.of(controlsListingController)
} else {
- Optional.empty()
+ Optional.empty<ControlsController>()
}
}
@@ -157,7 +157,7 @@ class DeviceControlsTileTest(flags: FlagsParameterization) : SysuiTestCase() {
if (featureEnabled) {
Optional.of(controlsUiController)
} else {
- Optional.empty()
+ Optional.empty<ControlsController>()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index e56b965d9402..3187cca6ca45 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -37,7 +37,6 @@ import com.android.systemui.authentication.shared.model.AuthenticationMethodMode
import com.android.systemui.bouncer.ui.viewmodel.PasswordBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.PinBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.bouncerSceneContentViewModel
-import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
@@ -48,9 +47,9 @@ import com.android.systemui.keyguard.ui.viewmodel.lockscreenUserActionsViewModel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.currentValue
-import com.android.systemui.kosmos.runCurrent
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.verifyCurrent
import com.android.systemui.lifecycle.activateIn
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
@@ -77,12 +76,9 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.verify
/**
* Integration test cases for the Scene Framework.
@@ -137,10 +133,10 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
sceneContainerViewModel.activateIn(testScope)
assertWithMessage("Initial scene key mismatch!")
- .that(sceneContainerViewModel.currentScene.value)
+ .that(currentValue(sceneContainerViewModel.currentScene))
.isEqualTo(sceneContainerConfig.initialSceneKey)
assertWithMessage("Initial scene container visibility mismatch!")
- .that(sceneContainerViewModel.isVisible)
+ .that(currentValue { sceneContainerViewModel.isVisible })
.isTrue()
}
@@ -337,7 +333,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
.that(bouncerActionButton)
.isNotNull()
kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
- runCurrent()
// TODO(b/369765704): Assert that an activity was started once we use ActivityStarter.
}
@@ -358,9 +353,8 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
.that(bouncerActionButton)
.isNotNull()
kosmos.bouncerSceneContentViewModel.onActionButtonClicked(bouncerActionButton!!)
- runCurrent()
- verify(mockTelecomManager).showInCallScreen(any())
+ verifyCurrent(mockTelecomManager).showInCallScreen(any())
}
@Test
@@ -413,7 +407,7 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
* the UI must gradually transition between scenes.
*/
private fun Kosmos.getCurrentSceneInUi(): SceneKey {
- return when (val state = transitionState.value) {
+ return when (val state = currentValue(transitionState)) {
is ObservableTransitionState.Idle -> state.currentScene
is ObservableTransitionState.Transition.ChangeScene -> state.fromScene
is ObservableTransitionState.Transition.ShowOrHideOverlay -> state.currentScene
@@ -436,7 +430,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
// is not an observable that can trigger a new evaluation.
fakeDeviceEntryRepository.setLockscreenEnabled(enableLockscreen)
fakeAuthenticationRepository.setAuthenticationMethod(authMethod)
- testScope.runCurrent()
}
/** Emulates a phone call in progress. */
@@ -447,7 +440,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
setIsInCall(true)
setCallState(TelephonyManager.CALL_STATE_OFFHOOK)
}
- testScope.runCurrent()
}
/**
@@ -480,24 +472,21 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
isInitiatedByUserInput = false,
isUserInputOngoing = flowOf(false),
)
- testScope.runCurrent()
// Report progress of transition.
- while (progressFlow.value < 1f) {
+ while (currentValue(progressFlow) < 1f) {
progressFlow.value += 0.2f
- testScope.runCurrent()
}
// End the transition and report the change.
transitionState.value = ObservableTransitionState.Idle(to)
fakeSceneDataSource.unpause(force = true)
- testScope.runCurrent()
assertWithMessage("Visibility mismatch after scene transition from $from to $to!")
- .that(sceneContainerViewModel.isVisible)
+ .that(currentValue { sceneContainerViewModel.isVisible })
.isEqualTo(expectedVisible)
- assertThat(sceneContainerViewModel.currentScene.value).isEqualTo(to)
+ assertThat(currentValue(sceneContainerViewModel.currentScene)).isEqualTo(to)
bouncerSceneJob =
if (to == Scenes.Bouncer) {
@@ -510,7 +499,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
bouncerSceneJob?.cancel()
null
}
- testScope.runCurrent()
}
/**
@@ -556,13 +544,12 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
)
powerInteractor.setAwakeForTest()
- testScope.runCurrent()
}
/** Unlocks the device by entering the correct PIN. Ends up in the Gone scene. */
private fun Kosmos.unlockDevice() {
assertWithMessage("Cannot unlock a device that's already unlocked!")
- .that(deviceEntryInteractor.isUnlocked.value)
+ .that(currentValue(deviceEntryInteractor.isUnlocked))
.isFalse()
emulateUserDrivenTransition(Scenes.Bouncer)
@@ -595,7 +582,6 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
pinBouncerViewModel.onPinButtonClicked(digit)
}
pinBouncerViewModel.onAuthenticateButtonClicked()
- testScope.runCurrent()
}
/**
@@ -625,26 +611,23 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
}
pinBouncerViewModel.onAuthenticateButtonClicked()
fakeMobileConnectionsRepository.isAnySimSecure.value = false
- testScope.runCurrent()
setAuthMethod(authMethodAfterSimUnlock, enableLockscreen)
- testScope.runCurrent()
}
/** Changes device wakefulness state from asleep to awake, going through intermediary states. */
private fun Kosmos.wakeUpDevice() {
- val wakefulnessModel = powerInteractor.detailedWakefulness.value
+ val wakefulnessModel = currentValue(powerInteractor.detailedWakefulness)
assertWithMessage("Cannot wake up device as it's already awake!")
.that(wakefulnessModel.isAwake())
.isFalse()
powerInteractor.setAwakeForTest()
- testScope.runCurrent()
}
/** Changes device wakefulness state from awake to asleep, going through intermediary states. */
private suspend fun Kosmos.putDeviceToSleep(waitForLock: Boolean = true) {
- val wakefulnessModel = powerInteractor.detailedWakefulness.value
+ val wakefulnessModel = currentValue(powerInteractor.detailedWakefulness)
assertWithMessage("Cannot put device to sleep as it's already asleep!")
.that(wakefulnessModel.isAwake())
.isTrue()
@@ -659,22 +642,18 @@ class SceneFrameworkIntegrationTest : SysuiTestCase() {
)
.toLong()
)
- } else {
- testScope.runCurrent()
}
}
/** Emulates the dismissal of the IME (soft keyboard). */
private fun Kosmos.dismissIme() {
- (bouncerSceneContentViewModel.authMethodViewModel.value as? PasswordBouncerViewModel)?.let {
- it.onImeDismissed()
- testScope.runCurrent()
- }
+ (currentValue(bouncerSceneContentViewModel.authMethodViewModel)
+ as? PasswordBouncerViewModel)
+ ?.let { it.onImeDismissed() }
}
private fun Kosmos.introduceLockedSim() {
setAuthMethod(AuthenticationMethodModel.Sim)
fakeMobileConnectionsRepository.isAnySimSecure.value = true
- testScope.runCurrent()
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
index 611318acde96..dea3d1f68ce5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
@@ -197,7 +197,7 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() {
if (
(it.arguments[0] as Intent).`package` == CAST_TO_OTHER_DEVICES_PACKAGE
) {
- emptyList()
+ emptyList<ResolveInfo>()
} else {
listOf(mock<ResolveInfo>())
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
index 1b7b47f49af2..2eac39e25759 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
@@ -66,7 +66,7 @@ class CastDeviceTest : SysuiTestCase() {
doAnswer {
// See Utils.isHeadlessRemoteDisplayProvider
if ((it.arguments[0] as Intent).`package` == HEADLESS_REMOTE_PACKAGE) {
- emptyList()
+ emptyList<ResolveInfo>()
} else {
listOf(mock<ResolveInfo>())
}
diff --git a/packages/SystemUI/plugin_core/processor/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt b/packages/SystemUI/plugin_core/processor/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt
index 6b54d8936254..9e704e2dc9b8 100644
--- a/packages/SystemUI/plugin_core/processor/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt
+++ b/packages/SystemUI/plugin_core/processor/src/com/android/systemui/plugins/processor/ProtectedPluginProcessor.kt
@@ -24,6 +24,7 @@ import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind
import javax.lang.model.element.ExecutableElement
+import javax.lang.model.element.Modifier
import javax.lang.model.element.PackageElement
import javax.lang.model.element.TypeElement
import javax.lang.model.type.TypeKind
@@ -165,11 +166,17 @@ class ProtectedPluginProcessor : AbstractProcessor() {
// Method implementations
for (method in methods) {
val methodName = method.simpleName
+ if (methods.any { methodName.startsWith("${it.simpleName}\$") }) {
+ continue
+ }
val returnTypeName = method.returnType.toString()
val callArgs = StringBuilder()
var isFirst = true
+ val isStatic = method.modifiers.contains(Modifier.STATIC)
- line("@Override")
+ if (!isStatic) {
+ line("@Override")
+ }
parenBlock("public $returnTypeName $methodName") {
// While copying the method signature for the proxy type, we also
// accumulate arguments for the nested callsite.
@@ -184,7 +191,8 @@ class ProtectedPluginProcessor : AbstractProcessor() {
}
val isVoid = method.returnType.kind == TypeKind.VOID
- val nestedCall = "mInstance.$methodName($callArgs)"
+ val methodContainer = if (isStatic) sourceName else "mInstance"
+ val nestedCall = "$methodContainer.$methodName($callArgs)"
val callStatement =
when {
isVoid -> "$nestedCall;"
diff --git a/packages/SystemUI/plugin_core/proguard.flags b/packages/SystemUI/plugin_core/proguard.flags
index 6240898b3b93..8b78ba47fdfc 100644
--- a/packages/SystemUI/plugin_core/proguard.flags
+++ b/packages/SystemUI/plugin_core/proguard.flags
@@ -8,4 +8,7 @@
-keep interface com.android.systemui.plugins.annotations.** {
*;
}
--keep,allowshrinking,allowoptimization,allowobfuscation,allowaccessmodification @com.android.systemui.plugins.annotations.** class *
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keep,allowshrinking,allowoptimization,allowobfuscation,allowaccessmodification @com.android.systemui.plugins.annotations.** class * {
+ void <init>();
+}
diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags
index 162d8aebfc62..2224837748a1 100644
--- a/packages/SystemUI/proguard_common.flags
+++ b/packages/SystemUI/proguard_common.flags
@@ -1,13 +1,25 @@
-include proguard_kotlin.flags
--keep class com.android.systemui.VendorServices
+
+# VendorServices implements CoreStartable and may be instantiated reflectively in
+# SystemUIApplication#startAdditionalStartable.
+# TODO(b/373579455): Rewrite this to a @UsesReflection keep annotation.
+-keep class com.android.systemui.VendorServices {
+ public void <init>();
+}
# Needed to ensure callback field references are kept in their respective
# owning classes when the downstream callback registrars only store weak refs.
# Note that we restrict this to SysUISingleton classes, as other registering
# classes should either *always* unregister or *never* register from their
# constructor. We also keep callback class names for easier debugging.
--keepnames @com.android.systemui.util.annotations.WeaklyReferencedCallback class *
--keepnames class * extends @com.android.systemui.util.annotations.WeaklyReferencedCallback **
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keepnames @com.android.systemui.util.annotations.WeaklyReferencedCallback class * {
+ void <init>();
+}
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keepnames class * extends @com.android.systemui.util.annotations.WeaklyReferencedCallback ** {
+ void <init>();
+}
-if @com.android.systemui.util.annotations.WeaklyReferencedCallback class *
-keepclassmembers,allowaccessmodification @com.android.systemui.dagger.SysUISingleton class * {
<1> *;
@@ -17,10 +29,16 @@
<1> *;
}
--keep class androidx.core.app.CoreComponentFactory
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keep class androidx.core.app.CoreComponentFactory {
+ void <init>();
+}
# Keep the wm shell lib
--keep class com.android.wm.shell.*
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keep class com.android.wm.shell.* {
+ void <init>();
+}
# Keep the protolog group methods that are called by the generated code
-keepclassmembers class com.android.wm.shell.protolog.ShellProtoLogGroup {
*;
diff --git a/packages/SystemUI/res-product/values/strings.xml b/packages/SystemUI/res-product/values/strings.xml
index 42733a20ffae..0c29bb4b2279 100644
--- a/packages/SystemUI/res-product/values/strings.xml
+++ b/packages/SystemUI/res-product/values/strings.xml
@@ -179,6 +179,8 @@
<!-- Text informing the user that their media is now playing on this tablet device. [CHAR LIMIT=50] -->
<string name="media_transfer_playing_this_device" product="tablet">Playing on this tablet</string>
-
+ <!-- Message shown during shutdown when Find My Device with Dead Battery Finder is active [CHAR LIMIT=300] -->
+ <string name="finder_active" product="default">You can locate this phone with Find My Device even when powered off</string>
+ <string name="finder_active" product="tablet">You can locate this tablet with Find My Device even when powered off</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 05c13f20f6d2..2eac7afa7cb2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2575,8 +2575,6 @@
<!-- Tuner string -->
<!-- Tuner string -->
- <!-- Message shown during shutdown when Find My Device with Dead Battery Finder is active [CHAR LIMIT=300] -->
- <string name="finder_active">You can locate this phone with Find My Device even when powered off</string>
<!-- Shutdown Progress Dialog. This is shown if the user chooses to power off the phone. [CHAR LIMIT=60] -->
<string name="shutdown_progress">Shutting down\u2026</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a703b027b691..9b0051ae7e67 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -193,7 +193,7 @@ import javax.inject.Provider;
* to be updated.
*/
@SysUISingleton
-public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpable, CoreStartable {
+public class KeyguardUpdateMonitor implements TrustManager.TrustListener, CoreStartable {
private static final String TAG = "KeyguardUpdateMonitor";
private static final int BIOMETRIC_LOCKOUT_RESET_DELAY_MS = 600;
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 66b3e189b6c9..90c9ac0df6f2 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -112,7 +112,7 @@ import javax.inject.Inject;
*/
@SysUISingleton
public class ScreenDecorations implements
- CoreStartable, ConfigurationController.ConfigurationListener, Dumpable {
+ CoreStartable, ConfigurationController.ConfigurationListener {
private static final boolean DEBUG_LOGGING = false;
private static final String TAG = "ScreenDecorations";
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
index 1f66c91b3573..5a59b7aaef56 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/OWNERS
@@ -1,3 +1,7 @@
-# Bug component: 44215
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
-include /core/java/android/view/accessibility/OWNERS \ No newline at end of file
+include /core/java/android/view/accessibility/OWNERS
+jonesriley@google.com \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/ailabs/OWNERS b/packages/SystemUI/src/com/android/systemui/ailabs/OWNERS
index b65d29c6a0bb..329aa07fdd9e 100644
--- a/packages/SystemUI/src/com/android/systemui/ailabs/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/ailabs/OWNERS
@@ -3,7 +3,5 @@
dupin@google.com
linyuh@google.com
pauldpong@google.com
-praveenj@google.com
vicliang@google.com
-mfolkerts@google.com
yuklimko@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt
index a9f8f37fffa9..4246430e8034 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingStartModule.kt
@@ -27,5 +27,5 @@ interface FalsingStartModule {
@Binds
@IntoMap
@ClassKey(FalsingCoreStartable::class)
- fun bindFalsingCoreStartable(falsingCoreStartable: FalsingCoreStartable?): CoreStartable?
+ fun bindFalsingCoreStartable(falsingCoreStartable: FalsingCoreStartable): CoreStartable
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index 91b44e7a6202..fdda2ad23457 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -452,6 +452,9 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mTelephonyListenerManager.removeServiceStateListener(mPhoneStateListener);
mGlobalSettings.unregisterContentObserverSync(mAirplaneModeObserver);
mConfigurationController.removeCallback(this);
+ if (mShowSilentToggle) {
+ mRingerModeTracker.getRingerMode().removeObservers(this);
+ }
}
protected Context getContext() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9f131607cb99..f27ea20194e8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -234,7 +234,7 @@ import java.util.function.Consumer;
* directly to the keyguard UI is posted to a {@link android.os.Handler} to ensure it is taken on the UI
* thread of the keyguard.
*/
-public class KeyguardViewMediator implements CoreStartable, Dumpable,
+public class KeyguardViewMediator implements CoreStartable,
StatusBarStateController.StateListener {
private static final boolean ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
index 208a17c0a220..ebe603b7428c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
@@ -2,6 +2,8 @@ set noparent
# Bug component: 78010
+include /services/core/java/com/android/server/biometrics/OWNERS
+
amiko@google.com
beverlyt@google.com
bhinegardner@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
index beb4d4103b11..df0e1adee968 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
@@ -22,6 +22,7 @@ import android.content.Context
import android.graphics.drawable.Icon
import android.media.session.MediaController
import android.media.session.PlaybackState
+import android.os.BadParcelableException
import android.util.Log
import com.android.systemui.Flags.mediaControlsPostsOptimization
import com.android.systemui.biometrics.Utils.toBitmap
@@ -109,7 +110,12 @@ private fun areCustomActionsEqual(
}
if (firstAction.extras != null) {
firstAction.extras.keySet().forEach { key ->
- if (firstAction.extras[key] != secondAction.extras[key]) {
+ try {
+ if (firstAction.extras[key] != secondAction.extras[key]) {
+ return false
+ }
+ } catch (e: BadParcelableException) {
+ Log.e(TAG, "Cannot unparcel extras", e)
return false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
index 6ca04710d74c..469bec7eb4ea 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt
@@ -24,7 +24,6 @@ import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.CoreStartable
-import com.android.systemui.Dumpable
import com.android.systemui.common.shared.model.Text
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
@@ -53,7 +52,7 @@ constructor(
private val dumpManager: DumpManager,
private val logger: MediaTttSenderLogger,
private val uiEventLogger: MediaTttSenderUiEventLogger,
-) : CoreStartable, Dumpable {
+) : CoreStartable {
// Since the media transfer display is similar to a heads-up notification, use the same timeout.
private val defaultTimeout = context.resources.getInteger(R.integer.heads_up_notification_decay)
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
index 0ec996be72de..9b4902a9e7b2 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
@@ -6,5 +6,4 @@ madym@google.com
mgalhardo@google.com
petrcermak@google.com
stevenckng@google.com
-tkachenkoi@google.com
-vanjan@google.com \ No newline at end of file
+vanjan@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
index 3fd87689b169..e2a39160defc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
@@ -54,11 +54,11 @@ interface QSModuleBase {
/** A map of internal QS tiles. Ensures that this can be injected even if it is empty */
@Multibinds fun tileMap(): Map<String?, QSTileImpl<*>?>?
- @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl?): QSSceneAdapter?
+ @Binds fun bindsQsSceneAdapter(impl: QSSceneAdapterImpl): QSSceneAdapter
/** Dims the screen */
@Binds
fun bindReduceBrightColorsController(
- impl: ReduceBrightColorsControllerImpl?
- ): ReduceBrightColorsController?
+ impl: ReduceBrightColorsControllerImpl
+ ): ReduceBrightColorsController
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
index 378d553065e0..675063a75139 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegate.java
@@ -571,8 +571,10 @@ public class InternetDialogDelegate implements
}
mSecondaryMobileNetworkLayout = mDialogView.findViewById(
R.id.secondary_mobile_network_layout);
- mSecondaryMobileNetworkLayout.setOnClickListener(
- this::onClickConnectedSecondarySub);
+ if (mCanConfigMobileData) {
+ mSecondaryMobileNetworkLayout.setOnClickListener(
+ this::onClickConnectedSecondarySub);
+ }
mSecondaryMobileNetworkLayout.setBackground(mBackgroundOn);
TextView mSecondaryMobileTitleText = mDialogView.requireViewById(
@@ -605,7 +607,8 @@ public class InternetDialogDelegate implements
mDialogView.requireViewById(R.id.secondary_settings_icon);
mSecondaryMobileSettingsIcon.setColorFilter(
dialog.getContext().getColor(R.color.connected_network_primary_color));
-
+ mSecondaryMobileSettingsIcon.setVisibility(mCanConfigMobileData ?
+ View.VISIBLE : View.INVISIBLE);
// set secondary visual for default data sub
mMobileNetworkLayout.setBackground(mBackgroundOff);
mMobileTitleText.setTextAppearance(R.style.TextAppearance_InternetDialog);
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
index ea4e065be84b..3a5245d9b9a5 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
@@ -65,8 +65,8 @@ abstract class SmartspaceModule {
@Binds
@Named(LOCKSCREEN_SMARTSPACE_PRECONDITION)
abstract fun bindSmartspacePrecondition(
- lockscreenPrecondition: LockscreenPrecondition?
- ): SmartspacePrecondition?
+ lockscreenPrecondition: LockscreenPrecondition
+ ): SmartspacePrecondition
@BindsOptionalOf
@Named(GLANCEABLE_HUB_SMARTSPACE_DATA_PLUGIN)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
index 0a7f08d5860b..d06f24fdb81b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
@@ -6,7 +6,6 @@ jeffdq@google.com
juliacr@google.com
aioana@google.com
-aroederer@google.com
asc@google.com
iyz@google.com
juliatuttle@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index d25889820629..45910d16b00c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -161,10 +161,12 @@ public class FooterView extends StackScrollerDecorView {
DumpUtilsKt.withIncreasedIndent(pw, () -> {
pw.println("visibility: " + DumpUtilsKt.visibilityString(getVisibility()));
pw.println("manageButton showHistory: " + mShowHistory);
- pw.println("manageButton visibility: "
- + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility()));
- pw.println("dismissButton visibility: "
- + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility()));
+ if (mManageOrHistoryButton != null)
+ pw.println("mManageOrHistoryButton visibility: "
+ + DumpUtilsKt.visibilityString(mManageOrHistoryButton.getVisibility()));
+ if (mClearAllButton != null)
+ pw.println("mClearAllButton visibility: "
+ + DumpUtilsKt.visibilityString(mClearAllButton.getVisibility()));
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 2433b78fc183..eb5d5fa84233 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -420,6 +420,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
mAnimationScheduler.addCallback(mAnimationCallback);
mUserInfoController.addCallback(mOnUserInfoChangedListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
+ mStatusBarState = mStatusBarStateController.getState();
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
mDisableStateTracker.startTracking(mCommandQueue, mView.getDisplay().getDisplayId());
if (mTintedIconManager == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
index 34c7059ec991..b695d9bf0034 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
@@ -23,7 +23,6 @@ import android.os.Handler
import android.os.RemoteException
import android.view.IWindowManager
import com.android.systemui.CoreStartable
-import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -40,7 +39,7 @@ constructor(
@Background private val backgroundExecutor: Executor,
private val wallpaperManager: WallpaperManager,
@Main private val mainHandler: Handler,
-) : CoreStartable, Dumpable {
+) : CoreStartable {
@ColorInt
var letterboxBackgroundColor: Int = Color.BLACK
private set
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index c57cede754d3..291f66c75727 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -82,7 +82,7 @@ constructor(
private val swipeStatusBarAwayGestureHandler: SwipeStatusBarAwayGestureHandler,
private val statusBarModeRepository: StatusBarModeRepositoryStore,
@OngoingCallLog private val logger: LogBuffer,
-) : CallbackController<OngoingCallListener>, Dumpable, CoreStartable {
+) : CallbackController<OngoingCallListener>, CoreStartable {
private var isFullscreen: Boolean = false
/** Non-null if there's an active call notification. */
private var callNotificationInfo: CallNotificationInfo? = null
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
index 0ec996be72de..9b4902a9e7b2 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
@@ -6,5 +6,4 @@ madym@google.com
mgalhardo@google.com
petrcermak@google.com
stevenckng@google.com
-tkachenkoi@google.com
-vanjan@google.com \ No newline at end of file
+vanjan@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
index 3c53d2d05fb8..635576743462 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayController.kt
@@ -34,7 +34,6 @@ import androidx.annotation.CallSuper
import androidx.annotation.VisibleForTesting
import com.android.app.viewcapture.ViewCaptureAwareWindowManager
import com.android.systemui.CoreStartable
-import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.ConfigurationController
@@ -81,7 +80,7 @@ abstract class TemporaryViewDisplayController<T : TemporaryViewInfo, U : Tempora
private val wakeLockBuilder: WakeLock.Builder,
private val systemClock: SystemClock,
internal val tempViewUiEventLogger: TemporaryViewUiEventLogger,
-) : CoreStartable, Dumpable {
+) : CoreStartable {
/**
* Window layout params that will be used as a starting point for the [windowLayoutParams] of
* all subclasses.
diff --git a/packages/SystemUI/src/com/android/systemui/util/EventLogModule.kt b/packages/SystemUI/src/com/android/systemui/util/EventLogModule.kt
index ca0876ca32cc..27ada236fa19 100644
--- a/packages/SystemUI/src/com/android/systemui/util/EventLogModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/EventLogModule.kt
@@ -22,5 +22,5 @@ import dagger.Module
@Module
interface EventLogModule {
- @SysUISingleton @Binds fun bindEventLog(eventLogImpl: EventLogImpl?): EventLog?
+ @SysUISingleton @Binds fun bindEventLog(eventLogImpl: EventLogImpl): EventLog
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
index 0ec996be72de..9b4902a9e7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
@@ -6,5 +6,4 @@ madym@google.com
mgalhardo@google.com
petrcermak@google.com
stevenckng@google.com
-tkachenkoi@google.com
-vanjan@google.com \ No newline at end of file
+vanjan@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
index 0ec996be72de..9b4902a9e7b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
@@ -6,5 +6,4 @@ madym@google.com
mgalhardo@google.com
petrcermak@google.com
stevenckng@google.com
-tkachenkoi@google.com
-vanjan@google.com \ No newline at end of file
+vanjan@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index 516541dcaf50..242865bc731b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -28,6 +28,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.never
import com.android.dx.mockito.inline.extended.ExtendedMockito.times
import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
+import com.android.dx.mockito.inline.extended.MockedVoidMethod
import com.android.dx.mockito.inline.extended.StaticMockitoSession
import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
@@ -245,7 +246,7 @@ class StylusManagerTest : SysuiTestCase() {
@Test
fun onInputDeviceAdded_btStylus_firstUsed_setsFlag() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
- verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1))
+ verify(MockedVoidMethod { InputSettings.setStylusEverUsed(mContext, true) }, times(1))
}
@Test
@@ -511,7 +512,7 @@ class StylusManagerTest : SysuiTestCase() {
stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
- verify({ InputSettings.setStylusEverUsed(mContext, true) }, times(1))
+ verify(MockedVoidMethod { InputSettings.setStylusEverUsed(mContext, true) }, times(1))
}
@Test
@@ -612,7 +613,7 @@ class StylusManagerTest : SysuiTestCase() {
stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
- verify({ InputSettings.setStylusEverUsed(mContext, true) }, never())
+ verify(MockedVoidMethod { InputSettings.setStylusEverUsed(mContext, true) }, never())
}
@Test
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
index 7ee9d84d84fb..43835607c77d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/GeneralKosmos.kt
@@ -17,6 +17,7 @@ import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
+import org.mockito.kotlin.verify
var Kosmos.testDispatcher by Fixture { StandardTestDispatcher() }
@@ -54,7 +55,7 @@ var Kosmos.brightnessWarningToast: BrightnessWarningToast by
* that kosmos instance
*/
fun Kosmos.runTest(testBody: suspend Kosmos.() -> Unit) =
- testScope.runTest { this@runTest.testBody() }
+ testScope.runTest testBody@{ this@runTest.testBody() }
fun Kosmos.runCurrent() = testScope.runCurrent()
@@ -82,6 +83,32 @@ fun <T> TestScope.currentValue(stateFlow: StateFlow<T>): T {
}
/** Retrieve the current value of this [StateFlow] safely. See `currentValue(TestScope)`. */
+fun <T> Kosmos.currentValue(fn: () -> T) = testScope.currentValue(fn)
+
+/**
+ * Retrieve the result of [fn] after running all pending tasks. Do not use to retrieve the value of
+ * a flow directly; for that, use either `currentValue(StateFlow)` or [collectLastValue]
+ */
+@OptIn(ExperimentalCoroutinesApi::class)
+fun <T> TestScope.currentValue(fn: () -> T): T {
+ runCurrent()
+ return fn()
+}
+
+/** Retrieve the result of [fn] after running all pending tasks. See `TestScope.currentValue(fn)` */
fun <T> Kosmos.currentValue(stateFlow: StateFlow<T>): T {
return testScope.currentValue(stateFlow)
}
+
+/** Safely verify that a mock has been called after the test scope has caught up */
+@OptIn(ExperimentalCoroutinesApi::class)
+fun <T> TestScope.verifyCurrent(mock: T): T {
+ runCurrent()
+ return verify(mock)
+}
+
+/**
+ * Safely verify that a mock has been called after the test scope has caught up. See
+ * `TestScope.verifyCurrent`
+ */
+fun <T> Kosmos.verifyCurrent(mock: T) = testScope.verifyCurrent(mock)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
index f52572a9e42d..f5eebb46c2ec 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/FakeSceneDataSource.kt
@@ -19,13 +19,13 @@ package com.android.systemui.scene.shared.model
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.compose.animation.scene.TransitionKey
+import com.android.systemui.kosmos.currentValue
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.test.TestScope
-class FakeSceneDataSource(
- initialSceneKey: SceneKey,
-) : SceneDataSource {
+class FakeSceneDataSource(initialSceneKey: SceneKey, val testScope: TestScope) : SceneDataSource {
private val _currentScene = MutableStateFlow(initialSceneKey)
override val currentScene: StateFlow<SceneKey> = _currentScene.asStateFlow()
@@ -33,18 +33,20 @@ class FakeSceneDataSource(
private val _currentOverlays = MutableStateFlow<Set<OverlayKey>>(emptySet())
override val currentOverlays: StateFlow<Set<OverlayKey>> = _currentOverlays.asStateFlow()
- var isPaused = false
- private set
+ private var _isPaused = false
+ val isPaused
+ get() = testScope.currentValue { _isPaused }
- var pendingScene: SceneKey? = null
- private set
+ private var _pendingScene: SceneKey? = null
+ val pendingScene
+ get() = testScope.currentValue { _pendingScene }
var pendingOverlays: Set<OverlayKey>? = null
private set
override fun changeScene(toScene: SceneKey, transitionKey: TransitionKey?) {
- if (isPaused) {
- pendingScene = toScene
+ if (_isPaused) {
+ _pendingScene = toScene
} else {
_currentScene.value = toScene
}
@@ -55,7 +57,7 @@ class FakeSceneDataSource(
}
override fun showOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) {
- if (isPaused) {
+ if (_isPaused) {
pendingOverlays = (pendingOverlays ?: currentOverlays.value) + overlay
} else {
_currentOverlays.value += overlay
@@ -63,7 +65,7 @@ class FakeSceneDataSource(
}
override fun hideOverlay(overlay: OverlayKey, transitionKey: TransitionKey?) {
- if (isPaused) {
+ if (_isPaused) {
pendingOverlays = (pendingOverlays ?: currentOverlays.value) - overlay
} else {
_currentOverlays.value -= overlay
@@ -82,9 +84,9 @@ class FakeSceneDataSource(
* last one will be remembered.
*/
fun pause() {
- check(!isPaused) { "Can't pause what's already paused!" }
+ check(!_isPaused) { "Can't pause what's already paused!" }
- isPaused = true
+ _isPaused = true
}
/**
@@ -100,15 +102,12 @@ class FakeSceneDataSource(
*
* If [expectedScene] is provided, will assert that it's indeed the latest called.
*/
- fun unpause(
- force: Boolean = false,
- expectedScene: SceneKey? = null,
- ) {
- check(force || isPaused) { "Can't unpause what's already not paused!" }
-
- isPaused = false
- pendingScene?.let { _currentScene.value = it }
- pendingScene = null
+ fun unpause(force: Boolean = false, expectedScene: SceneKey? = null) {
+ check(force || _isPaused) { "Can't unpause what's already not paused!" }
+
+ _isPaused = false
+ _pendingScene?.let { _currentScene.value = it }
+ _pendingScene = null
pendingOverlays?.let { _currentOverlays.value = it }
pendingOverlays = null
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/SceneDataSourceKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/SceneDataSourceKosmos.kt
index f5196866ae6f..7eebfc305682 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/SceneDataSourceKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/shared/model/SceneDataSourceKosmos.kt
@@ -19,13 +19,12 @@ package com.android.systemui.scene.shared.model
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.initialSceneKey
import com.android.systemui.scene.sceneContainerConfig
val Kosmos.fakeSceneDataSource by Fixture {
- FakeSceneDataSource(
- initialSceneKey = initialSceneKey,
- )
+ FakeSceneDataSource(initialSceneKey = initialSceneKey, testScope = testScope)
}
val Kosmos.sceneDataSourceDelegator by Fixture {
diff --git a/packages/Vcn/TEST_MAPPING b/packages/Vcn/TEST_MAPPING
index 9722a838ab8e..9ca5304eb8d9 100644
--- a/packages/Vcn/TEST_MAPPING
+++ b/packages/Vcn/TEST_MAPPING
@@ -14,5 +14,13 @@
{
"name": "CtsVcnTestCases"
}
+ ],
+ "tethering-mainline-presubmit": [
+ {
+ "name": "FrameworksVcnTests"
+ },
+ {
+ "name": "CtsVcnTestCases"
+ }
]
} \ No newline at end of file
diff --git a/packages/Vcn/flags/Android.bp b/packages/Vcn/flags/Android.bp
index 3943c6f7fe24..8d09fdbfa3de 100644
--- a/packages/Vcn/flags/Android.bp
+++ b/packages/Vcn/flags/Android.bp
@@ -29,10 +29,24 @@ aconfig_declarations {
],
}
+// TODO: b/374174952 Remove this library when VCN modularization is done
java_aconfig_library {
name: "android.net.vcn.flags-aconfig-java-export",
aconfig_declarations: "android.net.vcn.flags-aconfig",
mode: "exported",
min_sdk_version: "35",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ apex_available: [
+ "//apex_available:platform",
+ ],
+}
+
+java_aconfig_library {
+ name: "android.net.vcn.flags-aconfig-java",
+ aconfig_declarations: "android.net.vcn.flags-aconfig",
+ min_sdk_version: "35",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ apex_available: [
+ "com.android.tethering",
+ ],
}
diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp
index c3121162b7f2..edb22c0e7aa0 100644
--- a/packages/Vcn/framework-b/Android.bp
+++ b/packages/Vcn/framework-b/Android.bp
@@ -32,9 +32,9 @@ filegroup {
}
java_defaults {
- name: "framework-connectivity-b-defaults",
+ name: "framework-connectivity-b-defaults-base",
sdk_version: "module_current",
- min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+
defaults: ["framework-module-defaults"], // This is a boot jar
srcs: [
@@ -44,14 +44,10 @@ java_defaults {
libs: [
"android.net.ipsec.ike.stubs.module_lib",
- "app-compat-annotations",
"framework-wifi.stubs.module_lib",
"unsupportedappusage",
],
- static_libs: [
- //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
- "android.net.vcn.flags-aconfig-java-export",
- ],
+
aidl: {
include_dirs: [
// For connectivity-framework classes such as Network.aidl, NetworkCapabilities.aidl
@@ -60,16 +56,83 @@ java_defaults {
},
}
+soong_config_module_type {
+ name: "framework_connectivity_b_defaults_soong_config",
+ module_type: "java_defaults",
+ config_namespace: "ANDROID",
+ bool_variables: [
+ "is_vcn_in_mainline",
+ ],
+ properties: [
+ "min_sdk_version",
+ "static_libs",
+ "apex_available",
+ ],
+}
+
+framework_connectivity_b_defaults_soong_config {
+ name: "framework-connectivity-b-defaults",
+ defaults: [
+ "framework-connectivity-b-defaults-base",
+ ],
+ soong_config_variables: {
+ is_vcn_in_mainline: {
+ //TODO: b/380155299 Make it Baklava when aidl tool can understand it
+ min_sdk_version: "current",
+ static_libs: ["android.net.vcn.flags-aconfig-java"],
+ apex_available: ["com.android.tethering"],
+
+ conditions_default: {
+ min_sdk_version: "35",
+ static_libs: ["android.net.vcn.flags-aconfig-java-export"],
+ apex_available: ["//apex_available:platform"],
+ },
+ },
+ },
+}
+
+soong_config_module_type {
+ name: "framework_connectivity_b_java_sdk_library_defaults_soong_config",
+ module_type: "java_defaults",
+ config_namespace: "ANDROID",
+ bool_variables: [
+ "is_vcn_in_mainline",
+ ],
+ properties: [
+ "aconfig_declarations",
+ "jarjar_rules",
+ ],
+}
+
+framework_connectivity_b_java_sdk_library_defaults_soong_config {
+ name: "framework-connectivity-b-java-sdk-library-defaults",
+ soong_config_variables: {
+ is_vcn_in_mainline: {
+ aconfig_declarations: ["android.net.vcn.flags-aconfig-java"],
+
+ // TODO: b/375213246 Use the connectivity jarjar rule generator to create the
+ // jarjar rules. In the end state, use "framework-connectivity-jarjar-rules"
+ // after VCN code is moved to the Connectivity folder
+ jarjar_rules: "framework-vcn-jarjar-rules.txt",
+
+ conditions_default: {
+ aconfig_declarations: ["android.net.vcn.flags-aconfig-java-export"],
+
+ // Use "android.net.connectivity" as prefix would trigger
+ // "Hidden API flags are inconsistent" build error
+ jarjar_rules: "framework-vcn-jarjar-rules-platform.txt",
+ },
+ },
+ },
+}
+
java_sdk_library {
name: "framework-connectivity-b",
defaults: [
"framework-connectivity-b-defaults",
+ "framework-connectivity-b-java-sdk-library-defaults",
],
- //TODO: b/375213246 Use "framework-connectivity-jarjar-rules" when VCN is
- // in mainline
- jarjar_rules: "framework-vcn-jarjar-rules.txt",
-
permitted_packages: [
"android.net",
"android.net.vcn",
@@ -92,11 +155,6 @@ java_sdk_library {
"framework-connectivity-pre-jarjar",
],
- aconfig_declarations: [
- //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
- "android.net.vcn.flags-aconfig-java-export",
- ],
-
impl_library_visibility: [
// Using for test only
"//cts/tests/netlegacy22.api",
@@ -120,17 +178,13 @@ java_sdk_library {
"//packages/modules/Wifi/service/tests/wifitests",
],
- apex_available: [
- // TODO: b/374174952 Remove it when VCN modularization is released
- "//apex_available:platform",
-
- "com.android.tethering",
- ],
+ visibility: ["//packages/modules/Connectivity:__subpackages__"],
}
java_library {
name: "framework-connectivity-b-pre-jarjar",
defaults: ["framework-connectivity-b-defaults"],
+ installable: false,
libs: [
"framework-connectivity-pre-jarjar",
],
diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt
new file mode 100644
index 000000000000..757043bdbbc0
--- /dev/null
+++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules-platform.txt
@@ -0,0 +1,2 @@
+rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1
+rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1 \ No newline at end of file
diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
index 757043bdbbc0..33287b7f3449 100644
--- a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
+++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
@@ -1,2 +1,3 @@
-rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1
-rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1 \ No newline at end of file
+rule android.net.vcn.persistablebundleutils.** android.net.connectivity.android.net.vcn.persistablebundleutils.@1
+rule android.net.vcn.util.** android.net.connectivity.android.net.vcn.util.@1
+rule android.util.IndentingPrintWriter android.net.connectivity.android.util.IndentingPrintWriter \ No newline at end of file
diff --git a/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
index 1f0fa92d7976..de22ca684871 100644
--- a/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
+++ b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
@@ -23,8 +23,6 @@ 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;
@@ -40,17 +38,15 @@ import android.os.SystemProperties;
@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
- * that depend on them. If the feature is missing, {@link Context#getSystemService} will return
- * null.
- *
- * <p>This change is specific to VcnManager.
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
- private static final long ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN = 330902016;
+
+ // This is a copy of TelephonyFrameworkInitializer.ENABLE_CHECKING_TELEPHONY_FEATURES. This
+ // ChangeId will replace ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN to gate VcnManager
+ // feature flag enforcement.
+ // This replacement is safe because both ChangeIds have been enabled since Android V and serve
+ // the same purpose: enforcing telephony feature flag checks before using telephony-based
+ // features. This also simplifies VCN modularization by avoiding the need to handle different
+ // states, such as: SDK < B vs. SDK >= B; VCN in platform vs. VCN in the apex.
+ private static final long ENABLE_CHECKING_TELEPHONY_FEATURES = 330583731;
/**
* The corresponding vendor API for Android V
@@ -71,7 +67,7 @@ public final class ConnectivityFrameworkInitializerBaklava {
private static String getVcnFeatureDependency() {
// Check SDK version of the client app. Apps targeting pre-V SDK might
// have not checked for existence of these features.
- if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES_FOR_VCN)) {
+ if (!Compatibility.isChangeEnabled(ENABLE_CHECKING_TELEPHONY_FEATURES)) {
return null;
}
diff --git a/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java
index 3638429f33fb..a760b12ac8a1 100644
--- a/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java
+++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java
@@ -161,7 +161,14 @@ public final class VcnTransportInfo implements TransportInfo, Parcelable {
return 0;
}
- /** @hide */
+ /**
+ * Create a copy of a {@link VcnTransportInfo} with some fields redacted based on the
+ * permissions held by the receiving app.
+ *
+ * @param redactions bitmask of redactions that needs to be performed on this instance.
+ * @return the copy of this instance with the necessary redactions.
+ * @hide
+ */
@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@Override
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
index c1a1ee7875d0..97574e6e35e3 100644
--- a/packages/Vcn/service-b/Android.bp
+++ b/packages/Vcn/service-b/Android.bp
@@ -32,46 +32,42 @@ filegroup {
visibility: ["//frameworks/base/services/core"],
}
-// Do not static include this lib in VCN because these files exist in
-// both service-connectivity.jar and framework.jar
-// TODO: b/374174952 After VCN moves to Connectivity/ and the modularization is done
-// this lib can be removed and "service-connectivity-b-pre-jarjar" can include
-// "service-connectivity-pre-jarjar"
+// TODO: b/374174952 This library is only used in "service-connectivity-b-platform"
+// After VCN moves to Connectivity/ and the modularization is done, this lib and
+// "service-connectivity-b-platform" can both be removed
java_library {
name: "connectivity-utils-service-vcn-internal",
sdk_version: "module_current",
min_sdk_version: "30",
- srcs: [
- ":framework-connectivity-shared-srcs",
- ],
+ srcs: ["service-utils/**/*.java"],
libs: [
"framework-annotations-lib",
"unsupportedappusage",
],
- visibility: [
- "//visibility:private",
- ],
- apex_available: [
- // TODO: b/374174952 Remove it when VCN modularization is released
- "//apex_available:platform",
+ visibility: ["//visibility:private"],
+}
- "com.android.tethering",
+filegroup {
+ name: "service-vcn-sources",
+ srcs: ["src/**/*.java"],
+ path: "src",
+ visibility: [
+ "//packages/modules/Connectivity/service-b",
],
}
-java_library {
- name: "service-connectivity-b-pre-jarjar",
- sdk_version: "system_server_current",
- min_sdk_version: "35", // TODO: Make it Android 25Q2 when this is included in mainline
+// This java_defaults will be used for "service-connectivity-b-platform" and
+// "service-connectivity-b-pre-jarjar"
+java_defaults {
+ name: "service-connectivity-b-pre-jarjar-defaults",
defaults: ["framework-system-server-module-defaults"], // This is a system server jar
srcs: [
- "src/**/*.java",
+ ":service-vcn-sources",
],
libs: [
"android.net.ipsec.ike.stubs.module_lib",
- "connectivity-utils-service-vcn-internal",
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
"framework-connectivity-t-pre-jarjar",
@@ -89,13 +85,30 @@ java_library {
"modules-utils-handlerexecutor",
],
+ defaults_visibility: [
+ "//packages/modules/Connectivity/service-b",
+ ],
+}
+
+// This library is only used to be included into services.jar when the build system
+// flag RELEASE_MOVE_VCN_TO_MAINLINE is disabled. When the flag is enabled, a module
+// version of this library will be included in Tethering module
+java_library {
+ name: "service-connectivity-b-platform",
+ defaults: ["service-connectivity-b-pre-jarjar-defaults"],
+ static_libs: ["connectivity-utils-service-vcn-internal"],
+
+ sdk_version: "system_server_current",
+ min_sdk_version: "35",
+
+ // TODO (b/374174952 ): This file is for jarjaring files in
+ // "connectivity-utils-service-vcn-internal".
+ jarjar_rules: "service-vcn-platform-jarjar-rules.txt",
+
visibility: [
"//frameworks/base/services",
],
apex_available: [
- // TODO: b/374174952 Remove it when VCN modularization is released
"//apex_available:platform",
-
- "com.android.tethering",
],
}
diff --git a/packages/Vcn/service-b/service-utils/android/util/LocalLog.java b/packages/Vcn/service-b/service-utils/android/util/LocalLog.java
new file mode 100644
index 000000000000..5955d930aab1
--- /dev/null
+++ b/packages/Vcn/service-b/service-utils/android/util/LocalLog.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.SystemClock;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+
+/**
+ * @hide
+ */
+// Exported to Mainline modules; cannot use annotations
+// @android.ravenwood.annotation.RavenwoodKeepWholeClass
+// TODO: b/374174952 This is an exact copy of frameworks/base/core/java/android/util/LocalLog.java.
+// This file is only used in "service-connectivity-b-platform" before the VCN modularization flag
+// is fully ramped. When the flag is fully ramped and the development is finalized, this file can
+// be removed.
+public final class LocalLog {
+
+ private final Deque<String> mLog;
+ private final int mMaxLines;
+
+ /**
+ * {@code true} to use log timestamps expressed in local date/time, {@code false} to use log
+ * timestamped expressed with the elapsed realtime clock and UTC system clock. {@code false} is
+ * useful when logging behavior that modifies device time zone or system clock.
+ */
+ private final boolean mUseLocalTimestamps;
+
+ @UnsupportedAppUsage
+ public LocalLog(int maxLines) {
+ this(maxLines, true /* useLocalTimestamps */);
+ }
+
+ public LocalLog(int maxLines, boolean useLocalTimestamps) {
+ mMaxLines = Math.max(0, maxLines);
+ mLog = new ArrayDeque<>(mMaxLines);
+ mUseLocalTimestamps = useLocalTimestamps;
+ }
+
+ @UnsupportedAppUsage
+ public void log(String msg) {
+ if (mMaxLines <= 0) {
+ return;
+ }
+ final String logLine;
+ if (mUseLocalTimestamps) {
+ logLine = LocalDateTime.now() + " - " + msg;
+ } else {
+ logLine = Duration.ofMillis(SystemClock.elapsedRealtime())
+ + " / " + Instant.now() + " - " + msg;
+ }
+ append(logLine);
+ }
+
+ private synchronized void append(String logLine) {
+ while (mLog.size() >= mMaxLines) {
+ mLog.remove();
+ }
+ mLog.add(logLine);
+ }
+
+ @UnsupportedAppUsage
+ public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ dump(pw);
+ }
+
+ public synchronized void dump(PrintWriter pw) {
+ dump("", pw);
+ }
+
+ /**
+ * Dumps the content of local log to print writer with each log entry predeced with indent
+ *
+ * @param indent indent that precedes each log entry
+ * @param pw printer writer to write into
+ */
+ public synchronized void dump(String indent, PrintWriter pw) {
+ Iterator<String> itr = mLog.iterator();
+ while (itr.hasNext()) {
+ pw.printf("%s%s\n", indent, itr.next());
+ }
+ }
+
+ public synchronized void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ reverseDump(pw);
+ }
+
+ public synchronized void reverseDump(PrintWriter pw) {
+ Iterator<String> itr = mLog.descendingIterator();
+ while (itr.hasNext()) {
+ pw.println(itr.next());
+ }
+ }
+
+ // @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public synchronized void clear() {
+ mLog.clear();
+ }
+
+ public static class ReadOnlyLocalLog {
+ private final LocalLog mLog;
+ ReadOnlyLocalLog(LocalLog log) {
+ mLog = log;
+ }
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mLog.dump(pw);
+ }
+ public void dump(PrintWriter pw) {
+ mLog.dump(pw);
+ }
+ public void reverseDump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mLog.reverseDump(pw);
+ }
+ public void reverseDump(PrintWriter pw) {
+ mLog.reverseDump(pw);
+ }
+ }
+
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ public ReadOnlyLocalLog readOnlyLocalLog() {
+ return new ReadOnlyLocalLog(this);
+ }
+} \ No newline at end of file
diff --git a/packages/Vcn/service-b/service-utils/com/android/internal/util/WakeupMessage.java b/packages/Vcn/service-b/service-utils/com/android/internal/util/WakeupMessage.java
new file mode 100644
index 000000000000..7db62f8e9ffc
--- /dev/null
+++ b/packages/Vcn/service-b/service-utils/com/android/internal/util/WakeupMessage.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import android.app.AlarmManager;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+ /**
+ * An AlarmListener that sends the specified message to a Handler and keeps the system awake until
+ * the message is processed.
+ *
+ * This is useful when using the AlarmManager direct callback interface to wake up the system and
+ * request that an object whose API consists of messages (such as a StateMachine) perform some
+ * action.
+ *
+ * In this situation, using AlarmManager.onAlarmListener by itself will wake up the system to send
+ * the message, but does not guarantee that the system will be awake until the target object has
+ * processed it. This is because as soon as the onAlarmListener sends the message and returns, the
+ * AlarmManager releases its wakelock and the system is free to go to sleep again.
+ */
+// TODO: b/374174952 This is an exact copy of
+// frameworks/base/core/java/com/android/internal/util/WakeupMessage.java.
+// This file is only used in "service-connectivity-b-platform" before the VCN modularization flag
+// is fully ramped. When the flag is fully ramped and the development is finalized, this file can
+// be removed.
+public class WakeupMessage implements AlarmManager.OnAlarmListener {
+ private final AlarmManager mAlarmManager;
+
+ @VisibleForTesting
+ protected final Handler mHandler;
+ @VisibleForTesting
+ protected final String mCmdName;
+ @VisibleForTesting
+ protected final int mCmd, mArg1, mArg2;
+ @VisibleForTesting
+ protected final Object mObj;
+ private final Runnable mRunnable;
+ private boolean mScheduled;
+
+ public WakeupMessage(Context context, Handler handler,
+ String cmdName, int cmd, int arg1, int arg2, Object obj) {
+ mAlarmManager = getAlarmManager(context);
+ mHandler = handler;
+ mCmdName = cmdName;
+ mCmd = cmd;
+ mArg1 = arg1;
+ mArg2 = arg2;
+ mObj = obj;
+ mRunnable = null;
+ }
+
+ public WakeupMessage(Context context, Handler handler, String cmdName, int cmd, int arg1) {
+ this(context, handler, cmdName, cmd, arg1, 0, null);
+ }
+
+ public WakeupMessage(Context context, Handler handler,
+ String cmdName, int cmd, int arg1, int arg2) {
+ this(context, handler, cmdName, cmd, arg1, arg2, null);
+ }
+
+ public WakeupMessage(Context context, Handler handler, String cmdName, int cmd) {
+ this(context, handler, cmdName, cmd, 0, 0, null);
+ }
+
+ public WakeupMessage(Context context, Handler handler, String cmdName, Runnable runnable) {
+ mAlarmManager = getAlarmManager(context);
+ mHandler = handler;
+ mCmdName = cmdName;
+ mCmd = 0;
+ mArg1 = 0;
+ mArg2 = 0;
+ mObj = null;
+ mRunnable = runnable;
+ }
+
+ private static AlarmManager getAlarmManager(Context context) {
+ return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ }
+
+ /**
+ * Schedule the message to be delivered at the time in milliseconds of the
+ * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()} clock and wakeup
+ * the device when it goes off. If schedule is called multiple times without the message being
+ * dispatched then the alarm is rescheduled to the new time.
+ */
+ public synchronized void schedule(long when) {
+ mAlarmManager.setExact(
+ AlarmManager.ELAPSED_REALTIME_WAKEUP, when, mCmdName, this, mHandler);
+ mScheduled = true;
+ }
+
+ /**
+ * Cancel all pending messages. This includes alarms that may have been fired, but have not been
+ * run on the handler yet.
+ */
+ public synchronized void cancel() {
+ if (mScheduled) {
+ mAlarmManager.cancel(this);
+ mScheduled = false;
+ }
+ }
+
+ @Override
+ public void onAlarm() {
+ // Once this method is called the alarm has already been fired and removed from
+ // AlarmManager (it is still partially tracked, but only for statistics). The alarm can now
+ // be marked as unscheduled so that it can be rescheduled in the message handler.
+ final boolean stillScheduled;
+ synchronized (this) {
+ stillScheduled = mScheduled;
+ mScheduled = false;
+ }
+ if (stillScheduled) {
+ Message msg;
+ if (mRunnable == null) {
+ msg = mHandler.obtainMessage(mCmd, mArg1, mArg2, mObj);
+ } else {
+ msg = Message.obtain(mHandler, mRunnable);
+ }
+ mHandler.dispatchMessage(msg);
+ msg.recycle();
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt b/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt
new file mode 100644
index 000000000000..6ec39d953266
--- /dev/null
+++ b/packages/Vcn/service-b/service-vcn-platform-jarjar-rules.txt
@@ -0,0 +1,2 @@
+rule android.util.LocalLog android.net.vcn.module.repackaged.android.util.LocalLog
+rule com.android.internal.util.WakeupMessage android.net.vcn.module.repackaged.com.android.internal.util.WakeupMessage \ No newline at end of file
diff --git a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
index 02c8ce4f29e9..81c7edf4adf1 100644
--- a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
+++ b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
@@ -16,7 +16,9 @@
package com.android.server;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.os.Build;
import android.util.Log;
import com.android.tools.r8.keepanno.annotations.KeepItemKind;
@@ -30,6 +32,8 @@ import com.android.tools.r8.keepanno.annotations.UsedByReflection;
// Without this annotation, this class will be treated as unused class and be removed during build
// time.
@UsedByReflection(kind = KeepItemKind.CLASS_AND_METHODS)
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public final class ConnectivityServiceInitializerB extends SystemService {
private static final String TAG = ConnectivityServiceInitializerB.class.getSimpleName();
private final VcnManagementService mVcnManagementService;
diff --git a/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
index 26db6a988e31..c9a99d729e91 100644
--- a/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
+++ b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
@@ -37,6 +37,7 @@ import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.app.AppOpsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -164,6 +165,8 @@ import java.util.concurrent.TimeUnit;
* @hide
*/
// TODO(b/180451994): ensure all incoming + outgoing calls have a cleared calling identity
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class VcnManagementService extends IVcnManagementService.Stub {
@NonNull private static final String TAG = VcnManagementService.class.getSimpleName();
@NonNull private static final String CONTEXT_ATTRIBUTION_TAG = "VCN";
@@ -297,8 +300,10 @@ public class VcnManagementService extends IVcnManagementService.Stub {
});
}
- // Package-visibility for SystemServer to create instances.
- static VcnManagementService create(@NonNull Context context) {
+ /** Called by ConnectivityServiceInitializerB to create instances. */
+ // VcnManagementService will be jarjared but ConnectivityServiceInitializerB will not. Thus this
+ // method needs to be public for ConnectivityServiceInitializerB to access
+ public static VcnManagementService create(@NonNull Context context) {
return new VcnManagementService(context, new Dependencies());
}
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
index b448f7595b3b..b04e25dff276 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -22,12 +22,14 @@ import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.vcn.VcnManager;
import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -77,6 +79,8 @@ import java.util.Set;
*
* @hide
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class TelephonySubscriptionTracker extends BroadcastReceiver {
@NonNull private static final String TAG = TelephonySubscriptionTracker.class.getSimpleName();
private static final boolean LOG_DBG = false; // STOPSHIP if true
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
index 2524d0eedac3..97f86b1bff5b 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
@@ -29,6 +29,7 @@ import static com.android.server.VcnManagementService.VDBG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.NetworkCapabilities;
@@ -39,6 +40,7 @@ import android.net.vcn.VcnConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.util.LogUtils;
+import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
@@ -75,6 +77,8 @@ import java.util.Set;
*
* @hide
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class Vcn extends Handler {
private static final String TAG = Vcn.class.getSimpleName();
@@ -205,6 +209,8 @@ public class Vcn extends Handler {
this(vcnContext, subscriptionGroup, config, snapshot, vcnCallback, new Dependencies());
}
+ // WARNING: This constructor executes on the binder thread. Thread safety MUST be ensured when
+ // accessing data within this constructor and any methods called from here.
@VisibleForTesting(visibility = Visibility.PRIVATE)
public Vcn(
@NonNull VcnContext vcnContext,
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
index e50fc3a6e8b9..300b80f942ef 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
@@ -37,6 +37,8 @@ import static com.android.server.VcnManagementService.VDBG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
@@ -82,6 +84,7 @@ import android.net.vcn.util.LogUtils;
import android.net.vcn.util.MtuUtils;
import android.net.vcn.util.OneWayBoolean;
import android.net.wifi.WifiInfo;
+import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
@@ -171,6 +174,8 @@ import java.util.function.Consumer;
*
* @hide
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class VcnGatewayConnection extends StateMachine {
private static final String TAG = VcnGatewayConnection.class.getSimpleName();
@@ -2942,6 +2947,10 @@ public class VcnGatewayConnection extends StateMachine {
*
* <p>Synchronize this action to minimize locking around WakeLock use.
*/
+ // WakelockTimeout suppressed because the time the wake lock is needed for is unknown. The
+ // wakelock is only acquired when a Message is sent to this state machine and will be
+ // released when the message is processed or the state machin quits
+ @SuppressLint("WakelockTimeout")
public synchronized void acquire() {
mImpl.acquire();
}
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
index 4552f509b59a..38fcf09145d9 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
@@ -25,6 +25,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.server.VcnManagementService.VDBG;
import android.annotation.NonNull;
+import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
@@ -32,9 +33,9 @@ import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.NetworkScore;
import android.net.vcn.VcnGatewayConnectionConfig;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
-import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -44,6 +45,7 @@ import com.android.modules.utils.HandlerExecutor;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
/**
@@ -54,10 +56,14 @@ import java.util.concurrent.Executor;
*
* @hide
*/
+// TODO(b/388919146): Implement a more generic solution to prevent concurrent modifications on
+// mListeners and mRequests
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class VcnNetworkProvider extends NetworkProvider {
private static final String TAG = VcnNetworkProvider.class.getSimpleName();
- private final Set<NetworkRequestListener> mListeners = new ArraySet<>();
+ private final Set<NetworkRequestListener> mListeners = ConcurrentHashMap.newKeySet();
private final Context mContext;
private final Handler mHandler;
@@ -68,7 +74,7 @@ public class VcnNetworkProvider extends NetworkProvider {
*
* <p>NetworkRequests are immutable once created, and therefore can be used as stable keys.
*/
- private final Set<NetworkRequest> mRequests = new ArraySet<>();
+ private final Set<NetworkRequest> mRequests = ConcurrentHashMap.newKeySet();
public VcnNetworkProvider(@NonNull Context context, @NonNull Looper looper) {
this(context, looper, new Dependencies());
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index 72de61363d26..c8c645f1276d 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -23,6 +23,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -31,6 +32,7 @@ import android.net.ConnectivityManager;
import android.net.IpSecTransformState;
import android.net.Network;
import android.net.vcn.VcnManager;
+import android.os.Build;
import android.os.Handler;
import android.os.OutcomeReceiver;
import android.os.PowerManager;
@@ -59,6 +61,8 @@ import java.util.concurrent.TimeUnit;
*
* <p>This class is flag gated by "network_metric_monitor" and "ipsec_tramsform_state"
*/
+// TODO(b/374174952) Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class IpSecPacketLossDetector extends NetworkMetricMonitor {
private static final String TAG = IpSecPacketLossDetector.class.getSimpleName();
@@ -134,6 +138,8 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
@NonNull private final Object mCancellationToken = new Object();
@NonNull private final PacketLossCalculator mPacketLossCalculator;
+ @Nullable private BroadcastReceiver mDeviceIdleReceiver;
+
@Nullable private IpSecTransformWrapper mInboundTransform;
@Nullable private IpSecTransformState mLastIpSecTransformState;
@@ -164,19 +170,21 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
// Register for system broadcasts to monitor idle mode change
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
+
+ mDeviceIdleReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(
+ intent.getAction())
+ && mPowerManager.isDeviceIdleMode()) {
+ mLastIpSecTransformState = null;
+ }
+ }
+ };
getVcnContext()
.getContext()
.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(
- intent.getAction())
- && mPowerManager.isDeviceIdleMode()) {
- mLastIpSecTransformState = null;
- }
- }
- },
+ mDeviceIdleReceiver,
intentFilter,
null /* broadcastPermission not required */,
mHandler);
@@ -334,7 +342,12 @@ public class IpSecPacketLossDetector extends NetworkMetricMonitor {
super.close();
if (mInboundTransform != null) {
- mInboundTransform.close();
+ mInboundTransform = null;
+ }
+
+ if (mDeviceIdleReceiver != null) {
+ getVcnContext().getContext().unregisterReceiver(mDeviceIdleReceiver);
+ mDeviceIdleReceiver = null;
}
}
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
index 86cee554be6f..55829a5fe978 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
@@ -22,9 +22,11 @@ import static com.android.server.VcnManagementService.LOCAL_LOG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.net.IpSecTransform;
import android.net.IpSecTransformState;
import android.net.Network;
+import android.os.Build;
import android.os.OutcomeReceiver;
import android.util.CloseGuard;
import android.util.Slog;
@@ -42,6 +44,8 @@ import java.util.concurrent.Executor;
*
* <p>This class is flag gated by "network_metric_monitor"
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public abstract class NetworkMetricMonitor implements AutoCloseable {
private static final String TAG = NetworkMetricMonitor.class.getSimpleName();
@@ -161,7 +165,7 @@ public abstract class NetworkMetricMonitor implements AutoCloseable {
}
}
- /** Set the IpSecTransform that applied to the Network being monitored */
+ /** Set the IpSecTransform that is applied to the Network being monitored */
public void setInboundTransform(@NonNull IpSecTransform inTransform) {
setInboundTransformInternal(new IpSecTransformWrapper(inTransform));
}
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
index 79c4116d0cd4..705141f3f1b4 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
@@ -29,12 +29,14 @@ import static com.android.server.VcnManagementService.LOCAL_LOG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.ParcelUuid;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
@@ -50,6 +52,8 @@ import java.util.Map;
import java.util.Set;
/** @hide */
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
class NetworkPriorityClassifier {
@NonNull private static final String TAG = NetworkPriorityClassifier.class.getSimpleName();
/**
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
index 29a0762f5fe8..bc552e7e6afd 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
@@ -28,6 +28,7 @@ import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.ge
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IpSecTransform;
@@ -40,6 +41,7 @@ import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.util.LogUtils;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.telephony.TelephonyCallback;
@@ -73,6 +75,8 @@ import java.util.TreeSet;
*
* @hide
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class UnderlyingNetworkController {
@NonNull private static final String TAG = UnderlyingNetworkController.class.getSimpleName();
diff --git a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
index 30f4ed1b9f0b..776931bad73b 100644
--- a/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
@@ -22,12 +22,14 @@ import static com.android.server.VcnManagementService.LOCAL_LOG;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TargetApi;
import android.net.IpSecTransform;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.util.IndentingPrintWriter;
@@ -50,6 +52,8 @@ import java.util.concurrent.TimeUnit;
*
* @hide
*/
+// TODO(b/374174952): Replace VANILLA_ICE_CREAM with BAKLAVA after Android B finalization
+@TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
public class UnderlyingNetworkEvaluator {
private static final String TAG = UnderlyingNetworkEvaluator.class.getSimpleName();
diff --git a/proto/src/metrics_constants/OWNERS b/proto/src/metrics_constants/OWNERS
index 7009282b66e1..169f887ede56 100644
--- a/proto/src/metrics_constants/OWNERS
+++ b/proto/src/metrics_constants/OWNERS
@@ -1,4 +1,2 @@
cwren@android.com
-yanglu@google.com
yaochen@google.com
-yro@google.com
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 59043a8356ae..ccbc46fdb03b 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -121,6 +121,7 @@ java_library {
name: "ravenwood-helper-framework-runtime",
srcs: [
"runtime-helper-src/framework/**/*.java",
+ ":framework-graphics-srcs",
],
static_libs: [
"ravenwood-runtime-common",
@@ -175,9 +176,9 @@ java_library {
}
java_device_for_host {
- name: "ravenwood-junit-impl-for-ravenizer",
+ name: "ravenwood-junit-for-ravenizer",
libs: [
- "ravenwood-junit-impl",
+ "ravenwood-junit",
],
visibility: [":__subpackages__"],
}
@@ -278,6 +279,7 @@ cc_library_host_shared {
cc_library_host_shared {
name: "libravenwood_runtime",
defaults: ["ravenwood_jni_defaults"],
+ header_libs: ["libicuuc_headers"],
srcs: [
"runtime-jni/ravenwood_runtime.cpp",
"runtime-jni/ravenwood_os_constants.cpp",
@@ -345,14 +347,48 @@ java_library {
],
}
+// We define our own version of platform_compat_config's here, because:
+// - The original version (e.g. "framework-platform-compat-config) is built from
+// the output file of the device side jar, rather than the host jar, meaning
+// they're slow to build because they depend on D8/R8 output.
+// - The original services one ("services-platform-compat-config") is built from services.jar,
+// which includes service.permission, which is very slow to rebuild because of kotlin.
+//
+// Because we're re-defining the same compat-IDs that are defined elsewhere,
+// they should all have `include_in_merged_xml: false`. Otherwise, generating
+// merged_compat_config.xml would fail due to duplicate IDs.
+//
+// These module names must end with "compat-config" because these will be used as the filename,
+// and at runtime, we only loads files that match `*compat-config.xml`.
+platform_compat_config {
+ name: "ravenwood-framework-platform-compat-config",
+ src: ":framework-minus-apex-for-host",
+ include_in_merged_xml: false,
+ visibility: ["//visibility:private"],
+}
+
+platform_compat_config {
+ name: "ravenwood-services.core-platform-compat-config",
+ src: ":services.core-for-host",
+ include_in_merged_xml: false,
+ visibility: ["//visibility:private"],
+}
+
+java_library {
+ name: "ext-ravenwood",
+ installable: false,
+ static_libs: ["ext"],
+ visibility: ["//visibility:private"],
+}
+
filegroup {
name: "ravenwood-data",
device_common_srcs: [
":system-build.prop",
":framework-res",
":ravenwood-empty-res",
- ":framework-platform-compat-config",
- ":services-platform-compat-config",
+ ":ravenwood-framework-platform-compat-config",
+ ":ravenwood-services.core-platform-compat-config",
"texts/ravenwood-build.prop",
],
device_first_srcs: [
@@ -610,12 +646,17 @@ android_ravenwood_libgroup {
libs: [
"100-framework-minus-apex.ravenwood",
"200-kxml2-android",
+ "ext-ravenwood",
"ravenwood-runtime-common-ravenwood",
"android.test.mock.ravenwood",
"ravenwood-helper-runtime",
"hoststubgen-helper-runtime.ravenwood",
+
+ // Note, when we include other services.* jars, we'll need to add
+ // platform_compat_config for that module too.
+ // See ravenwood-services.core-platform-compat-config above.
"services.core.ravenwood-jarjar",
"services.fakes.ravenwood-jarjar",
@@ -630,6 +671,9 @@ android_ravenwood_libgroup {
// StatsD
"framework-statsd.ravenwood",
+ // Graphics
+ "framework-graphics.ravenwood",
+
// Provide runtime versions of utils linked in below
"junit",
"truth",
diff --git a/ravenwood/CleanSpec.mk b/ravenwood/CleanSpec.mk
new file mode 100644
index 000000000000..50d2fab40326
--- /dev/null
+++ b/ravenwood/CleanSpec.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# *****************************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER
+# *****************************************************************
+
+$(call add-clean-step, rm -rf $(OUT_DIR)/host/linux-x86/testcases/ravenwood-runtime)
+
+# ******************************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
+# ******************************************************************
diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp
index 99fc31b258e9..e36677189e02 100644
--- a/ravenwood/Framework.bp
+++ b/ravenwood/Framework.bp
@@ -399,3 +399,57 @@ java_genrule {
"framework-statsd.ravenwood.jar",
],
}
+
+//////////////////////
+// framework-graphics
+//////////////////////
+
+java_genrule {
+ name: "framework-graphics.ravenwood-base",
+ tools: ["hoststubgen"],
+ cmd: "$(location hoststubgen) " +
+ "@$(location :ravenwood-standard-options) " +
+
+ "--debug-log $(location framework-graphics.log) " +
+ "--stats-file $(location framework-graphics_stats.csv) " +
+ "--supported-api-list-file $(location framework-graphics_apis.csv) " +
+ "--gen-keep-all-file $(location framework-graphics_keep_all.txt) " +
+ "--gen-input-dump-file $(location framework-graphics_dump.txt) " +
+
+ "--out-impl-jar $(location ravenwood.jar) " +
+ "--in-jar $(location :framework-graphics.impl{.jar}) " +
+
+ "--policy-override-file $(location :ravenwood-common-policies) " +
+ "--policy-override-file $(location :framework-graphics-ravenwood-policies) ",
+ srcs: [
+ ":framework-graphics.impl{.jar}",
+
+ ":ravenwood-common-policies",
+ ":framework-graphics-ravenwood-policies",
+ ":ravenwood-standard-options",
+ ],
+ out: [
+ "ravenwood.jar",
+
+ // Following files are created just as FYI.
+ "framework-graphics_keep_all.txt",
+ "framework-graphics_dump.txt",
+
+ "framework-graphics.log",
+ "framework-graphics_stats.csv",
+ "framework-graphics_apis.csv",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule {
+ name: "framework-graphics.ravenwood",
+ defaults: ["ravenwood-internal-only-visibility-genrule"],
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":framework-graphics.ravenwood-base{ravenwood.jar}",
+ ],
+ out: [
+ "framework-graphics.ravenwood.jar",
+ ],
+}
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index cb54e9f56c0c..df63cb9dfc50 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -2,6 +2,7 @@
"presubmit": [
{ "name": "tiny-framework-dump-test" },
{ "name": "hoststubgentest" },
+ { "name": "ravenhelpertest" },
{ "name": "hoststubgen-test-tiny-test" },
{ "name": "hoststubgen-invoke-test" },
{ "name": "RavenwoodMockitoTest_device" },
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 3ebef02284d6..b6167665c985 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -23,13 +23,10 @@ import static org.junit.Assume.assumeTrue;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.Bundle;
import android.platform.test.annotations.RavenwoodTestRunnerInitializing;
import android.platform.test.annotations.internal.InnerRunner;
import android.util.Log;
-import androidx.test.platform.app.InstrumentationRegistry;
-
import com.android.ravenwood.common.RavenwoodCommonUtils;
import org.junit.rules.TestRule;
@@ -285,11 +282,6 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
private boolean onBefore(Description description, Scope scope, Order order) {
Log.v(TAG, "onBefore: description=" + description + ", " + scope + ", " + order);
- if (scope == Scope.Instance && order == Order.Outer) {
- // Start of a test method.
- mState.enterTestMethod(description);
- }
-
final var classDescription = getDescription();
// Class-level annotations are checked by the runner already, so we only check
@@ -299,6 +291,12 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
return false;
}
}
+
+ if (scope == Scope.Instance && order == Order.Outer) {
+ // Start of a test method.
+ mState.enterTestMethod(description);
+ }
+
return true;
}
@@ -314,8 +312,7 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
if (scope == Scope.Instance && order == Order.Outer) {
// End of a test method.
- mState.exitTestMethod();
-
+ mState.exitTestMethod(description);
}
// If RUN_DISABLED_TESTS is set, and the method did _not_ throw, make it an error.
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
index a3326337d485..9e6b12f60add 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
@@ -230,6 +230,16 @@ public class RavenwoodContext extends RavenwoodBaseContext {
return mAppContext;
}
+ @Override
+ public boolean isRestricted() {
+ return false;
+ }
+
+ @Override
+ public boolean canLoadUnsafeResources() {
+ return true;
+ }
+
/**
* Wrap the given {@link Supplier} to become memoized.
*
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java
new file mode 100644
index 000000000000..7ee9d7a8a5c6
--- /dev/null
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodMethodCallLogger.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.platform.test.ravenwood;
+
+import com.android.ravenwood.RavenwoodRuntimeNative;
+
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Objects;
+
+/**
+ * Provides a method call hook that prints almost all (see below) the framework methods being
+ * called with indentation.
+ *
+ * We don't log methods that are trivial, uninteresting, or would be too noisy.
+ * e.g. we don't want to log any logging related methods, or collection APIs.
+ *
+ */
+public class RavenwoodMethodCallLogger {
+ private RavenwoodMethodCallLogger() {
+ }
+
+ /** We don't want to log anything before ravenwood is initialized. This flag controls it.*/
+ private static volatile boolean sEnabled = false;
+
+ private static volatile PrintStream sOut = System.out;
+
+ /** Return the current thread's call nest level. */
+ private static int getNestLevel() {
+ return Thread.currentThread().getStackTrace().length;
+ }
+
+ private static class ThreadInfo {
+ /**
+ * We save the current thread's nest call level here and use that as the initial level.
+ * We do it because otherwise the nest level would be too deep by the time test
+ * starts.
+ */
+ public final int mInitialNestLevel = getNestLevel();
+
+ /**
+ * A nest level where shouldLog() returned false.
+ * Once it's set, we ignore all calls deeper than this.
+ */
+ public int mDisabledNestLevel = Integer.MAX_VALUE;
+ }
+
+ private static final ThreadLocal<ThreadInfo> sThreadInfo = new ThreadLocal<>() {
+ @Override
+ protected ThreadInfo initialValue() {
+ return new ThreadInfo();
+ }
+ };
+
+ /** Classes that should be logged. Uses a map for fast lookup. */
+ private static final HashSet<Class> sIgnoreClasses = new HashSet<>();
+ static {
+ // The following classes are not interesting...
+ sIgnoreClasses.add(android.util.Log.class);
+ sIgnoreClasses.add(android.util.Slog.class);
+ sIgnoreClasses.add(android.util.EventLog.class);
+ sIgnoreClasses.add(android.util.TimingsTraceLog.class);
+
+ sIgnoreClasses.add(android.util.SparseArray.class);
+ sIgnoreClasses.add(android.util.SparseIntArray.class);
+ sIgnoreClasses.add(android.util.SparseLongArray.class);
+ sIgnoreClasses.add(android.util.SparseBooleanArray.class);
+ sIgnoreClasses.add(android.util.SparseDoubleArray.class);
+ sIgnoreClasses.add(android.util.SparseSetArray.class);
+ sIgnoreClasses.add(android.util.SparseArrayMap.class);
+ sIgnoreClasses.add(android.util.LongSparseArray.class);
+ sIgnoreClasses.add(android.util.LongSparseLongArray.class);
+ sIgnoreClasses.add(android.util.LongArray.class);
+
+ sIgnoreClasses.add(android.text.FontConfig.class);
+
+ sIgnoreClasses.add(android.os.SystemClock.class);
+ sIgnoreClasses.add(android.os.Trace.class);
+ sIgnoreClasses.add(android.os.LocaleList.class);
+ sIgnoreClasses.add(android.os.Build.class);
+ sIgnoreClasses.add(android.os.SystemProperties.class);
+
+ sIgnoreClasses.add(com.android.internal.util.Preconditions.class);
+
+ sIgnoreClasses.add(android.graphics.FontListParser.class);
+ sIgnoreClasses.add(android.graphics.ColorSpace.class);
+
+ sIgnoreClasses.add(android.graphics.fonts.FontStyle.class);
+ sIgnoreClasses.add(android.graphics.fonts.FontVariationAxis.class);
+
+ sIgnoreClasses.add(com.android.internal.compat.CompatibilityChangeInfo.class);
+ sIgnoreClasses.add(com.android.internal.os.LoggingPrintStream.class);
+
+ sIgnoreClasses.add(android.os.ThreadLocalWorkSource.class);
+
+ // Following classes *may* be interesting for some purposes, but the initialization is
+ // too noisy...
+ sIgnoreClasses.add(android.graphics.fonts.SystemFonts.class);
+
+ }
+
+ /**
+ * Return if a class should be ignored. Uses {link #sIgnoreCladsses}, but
+ * we ignore more classes.
+ */
+ private static boolean shouldIgnoreClass(Class<?> clazz) {
+ if (sIgnoreClasses.contains(clazz)) {
+ return true;
+ }
+ // Let's also ignore collection-ish classes in android.util.
+ if (java.util.Collection.class.isAssignableFrom(clazz)
+ || java.util.Map.class.isAssignableFrom(clazz)
+ ) {
+ if ("android.util".equals(clazz.getPackageName())) {
+ return true;
+ }
+ return false;
+ }
+
+ switch (clazz.getSimpleName()) {
+ case "EventLogTags":
+ return false;
+ }
+
+ // Following are classes that can't be referred to here directly.
+ // e.g. AndroidPrintStream is package-private, so we can't use its "class" here.
+ switch (clazz.getName()) {
+ case "com.android.internal.os.AndroidPrintStream":
+ return false;
+ }
+ return false;
+ }
+
+ private static boolean shouldLog(
+ Class<?> methodClass,
+ String methodName,
+ @SuppressWarnings("UnusedVariable") String methodDescriptor
+ ) {
+ // Should we ignore this class?
+ if (shouldIgnoreClass(methodClass)) {
+ return false;
+ }
+ // Is it a nested class in a class that should be ignored?
+ var host = methodClass.getNestHost();
+ if (host != methodClass && shouldIgnoreClass(host)) {
+ return false;
+ }
+
+ var className = methodClass.getName();
+
+ // Ad-hoc ignore list. They'd be too noisy.
+ if ("create".equals(methodName)
+ // We may apply jarjar, so use endsWith().
+ && className.endsWith("com.android.server.compat.CompatConfig")) {
+ return false;
+ }
+
+ var pkg = methodClass.getPackageName();
+ if (pkg.startsWith("android.icu")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Call this to enable logging.
+ */
+ public static void enable(PrintStream out) {
+ sEnabled = true;
+ sOut = Objects.requireNonNull(out);
+
+ // It's called from the test thread (Java's main thread). Because we're already
+ // in deep nest calls, we initialize the initial nest level here.
+ sThreadInfo.get();
+ }
+
+ /** Actual method hook entry point.*/
+ public static void logMethodCall(
+ Class<?> methodClass,
+ String methodName,
+ String methodDescriptor
+ ) {
+ if (!sEnabled) {
+ return;
+ }
+ final var ti = sThreadInfo.get();
+ final int nestLevel = getNestLevel() - ti.mInitialNestLevel;
+
+ // Once shouldLog() returns false, we just ignore all deeper calls.
+ if (ti.mDisabledNestLevel < nestLevel) {
+ return; // Still ignore.
+ }
+ final boolean shouldLog = shouldLog(methodClass, methodName, methodDescriptor);
+
+ if (!shouldLog) {
+ ti.mDisabledNestLevel = nestLevel;
+ return;
+ }
+ ti.mDisabledNestLevel = Integer.MAX_VALUE;
+
+ var out = sOut;
+ out.print("# [");
+ out.print(RavenwoodRuntimeNative.gettid());
+ out.print(": ");
+ out.print(Thread.currentThread().getName());
+ out.print("]: ");
+ out.print("[@");
+ out.printf("%2d", nestLevel);
+ out.print("] ");
+ for (int i = 0; i < nestLevel; i++) {
+ out.print(" ");
+ }
+ out.println(methodClass.getName() + "." + methodName + methodDescriptor);
+ }
+}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
index a208d6dce2ce..7e935d0451ae 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodNativeLoader.java
@@ -48,6 +48,7 @@ public final class RavenwoodNativeLoader {
android.content.res.AssetManager.class,
android.content.res.StringBlock.class,
android.content.res.XmlBlock.class,
+ android.text.AndroidCharacter.class,
};
/**
@@ -61,15 +62,49 @@ public final class RavenwoodNativeLoader {
android.graphics.Path.class,
android.graphics.Color.class,
android.graphics.ColorSpace.class,
+ android.graphics.Bitmap.class,
+ android.graphics.BitmapFactory.class,
+ android.graphics.BitmapRegionDecoder.class,
+ android.graphics.Camera.class,
+ android.graphics.Canvas.class,
+ android.graphics.CanvasProperty.class,
+ android.graphics.ColorFilter.class,
+ android.graphics.DrawFilter.class,
+ android.graphics.FontFamily.class,
+ android.graphics.Gainmap.class,
+ android.graphics.ImageDecoder.class,
+ android.graphics.MaskFilter.class,
+ android.graphics.NinePatch.class,
+ android.graphics.Paint.class,
+ android.graphics.PathEffect.class,
+ android.graphics.PathIterator.class,
+ android.graphics.PathMeasure.class,
+ android.graphics.Picture.class,
+ android.graphics.RecordingCanvas.class,
+ android.graphics.Region.class,
+ android.graphics.RenderNode.class,
+ android.graphics.Shader.class,
+ android.graphics.RenderEffect.class,
+ android.graphics.Typeface.class,
+ android.graphics.YuvImage.class,
+ android.graphics.fonts.Font.class,
+ android.graphics.fonts.FontFamily.class,
+ android.graphics.text.LineBreaker.class,
+ android.graphics.text.MeasuredText.class,
+ android.graphics.text.TextRunShaper.class,
+ android.graphics.text.GraphemeBreak.class,
+ android.util.PathParser.class,
};
/**
* Extra strings needed to pass to register_android_graphics_classes().
*
- * `android.graphics.Graphics` is not actually a class, so we just hardcode it here.
+ * Several entries are not actually a class, so we just hardcode them here.
*/
public final static String[] GRAPHICS_EXTRA_INIT_PARAMS = new String[] {
- "android.graphics.Graphics"
+ "android.graphics.Graphics",
+ "android.graphics.ByteBufferStreamAdaptor",
+ "android.graphics.CreateJavaOutputStreamAdaptor"
};
private RavenwoodNativeLoader() {
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
index 70bc52bdaa12..705186edba00 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
@@ -81,12 +81,15 @@ public final class RavenwoodRunnerState {
RavenwoodRuntimeEnvironmentController.exitTestClass();
}
+ /** Called when a test method is about to start */
public void enterTestMethod(Description description) {
mMethodDescription = description;
- RavenwoodRuntimeEnvironmentController.initForMethod();
+ RavenwoodRuntimeEnvironmentController.enterTestMethod(description);
}
- public void exitTestMethod() {
+ /** Called when a test method finishes */
+ public void exitTestMethod(Description description) {
+ RavenwoodRuntimeEnvironmentController.exitTestMethod(description);
mMethodDescription = null;
}
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 3cb6c5a6bd16..33c4e86d885d 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -23,7 +23,6 @@ import static android.platform.test.ravenwood.RavenwoodSystemServer.ANDROID_PACK
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_EMPTY_RESOURCES_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_RESOURCE_APK;
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;
@@ -44,12 +43,15 @@ import android.app.UiAutomation;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.icu.util.ULocale;
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;
+import android.os.Message;
import android.os.Process_ravenwood;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -73,6 +75,7 @@ import com.android.ravenwood.common.SneakyThrow;
import com.android.server.LocalServices;
import com.android.server.compat.PlatformCompat;
+import org.junit.AssumptionViolatedException;
import org.junit.internal.management.ManagementFactory;
import org.junit.runner.Description;
@@ -80,7 +83,9 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
@@ -91,6 +96,7 @@ import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
/**
* Responsible for initializing and the environment.
@@ -101,32 +107,64 @@ public class RavenwoodRuntimeEnvironmentController {
private RavenwoodRuntimeEnvironmentController() {
}
- private static final String MAIN_THREAD_NAME = "RavenwoodMain";
+ private static final PrintStream sStdOut = System.out;
+ @SuppressWarnings("UnusedVariable")
+ private static final PrintStream sStdErr = System.err;
+
+ private static final String MAIN_THREAD_NAME = "Ravenwood:Main";
+ private static final String TESTS_THREAD_NAME = "Ravenwood:Test";
+
private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer";
private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";
private static final String ANDROID_LOG_TAGS = "ANDROID_LOG_TAGS";
private static final String RAVENWOOD_ANDROID_LOG_TAGS = "RAVENWOOD_" + ANDROID_LOG_TAGS;
+ static volatile Thread sTestThread;
+ static volatile Thread sMainThread;
+
/**
* When enabled, attempt to dump all thread stacks just before we hit the
* overall Tradefed timeout, to aid in debugging deadlocks.
+ *
+ * Note, this timeout will _not_ stop the test, as there isn't really a clean way to do it.
+ * It'll merely print stacktraces.
*/
private static final boolean ENABLE_TIMEOUT_STACKS =
- "1".equals(System.getenv("RAVENWOOD_ENABLE_TIMEOUT_STACKS"));
+ !"0".equals(System.getenv("RAVENWOOD_ENABLE_TIMEOUT_STACKS"));
+
+ private static final boolean TOLERATE_LOOPER_ASSERTS =
+ !"0".equals(System.getenv("RAVENWOOD_TOLERATE_LOOPER_ASSERTS"));
+
+ static final int DEFAULT_TIMEOUT_SECONDS = 10;
+ private static final int TIMEOUT_MILLIS = getTimeoutSeconds() * 1000;
+
+ static int getTimeoutSeconds() {
+ var e = System.getenv("RAVENWOOD_TIMEOUT_SECONDS");
+ if (e == null || e.isEmpty()) {
+ return DEFAULT_TIMEOUT_SECONDS;
+ }
+ return Integer.parseInt(e);
+ }
- private static final int TIMEOUT_MILLIS = 9_000;
private static final ScheduledExecutorService sTimeoutExecutor =
- Executors.newScheduledThreadPool(1);
+ Executors.newScheduledThreadPool(1, (Runnable r) -> {
+ Thread t = Executors.defaultThreadFactory().newThread(r);
+ t.setName("Ravenwood:TimeoutMonitor");
+ t.setDaemon(true);
+ return t;
+ });
- private static ScheduledFuture<?> sPendingTimeout;
+ private static volatile ScheduledFuture<?> sPendingTimeout;
/**
* When enabled, attempt to detect uncaught exceptions from background threads.
*/
private static final boolean ENABLE_UNCAUGHT_EXCEPTION_DETECTION =
- "1".equals(System.getenv("RAVENWOOD_ENABLE_UNCAUGHT_EXCEPTION_DETECTION"));
+ !"0".equals(System.getenv("RAVENWOOD_ENABLE_UNCAUGHT_EXCEPTION_DETECTION"));
+
+ private static final boolean DIE_ON_UNCAUGHT_EXCEPTION = true;
/**
* When set, an unhandled exception was discovered (typically on a background thread), and we
@@ -135,12 +173,6 @@ public class RavenwoodRuntimeEnvironmentController {
private static final AtomicReference<Throwable> sPendingUncaughtException =
new AtomicReference<>();
- private static final Thread.UncaughtExceptionHandler sUncaughtExceptionHandler =
- (thread, throwable) -> {
- // Remember the first exception we discover
- sPendingUncaughtException.compareAndSet(null, throwable);
- };
-
// TODO: expose packCallingIdentity function in libbinder and use it directly
// See: packCallingIdentity in frameworks/native/libs/binder/IPCThreadState.cpp
private static long packBinderIdentityToken(
@@ -181,6 +213,8 @@ public class RavenwoodRuntimeEnvironmentController {
* Initialize the global environment.
*/
public static void globalInitOnce() {
+ sTestThread = Thread.currentThread();
+ Thread.currentThread().setName(TESTS_THREAD_NAME);
synchronized (sInitializationLock) {
if (!sInitialized) {
// globalInitOnce() is called from class initializer, which cause
@@ -188,6 +222,7 @@ public class RavenwoodRuntimeEnvironmentController {
sInitialized = true;
// This is the first call.
+ final long start = System.currentTimeMillis();
try {
globalInitInner();
} catch (Throwable th) {
@@ -196,6 +231,9 @@ public class RavenwoodRuntimeEnvironmentController {
sExceptionFromGlobalInit = th;
SneakyThrow.sneakyThrow(th);
}
+ final long end = System.currentTimeMillis();
+ // TODO Show user/system time too
+ Log.e(TAG, "globalInit() took " + (end - start) + "ms");
} else {
// Subsequent calls. If the first call threw, just throw the same error, to prevent
// the test from running.
@@ -210,11 +248,12 @@ public class RavenwoodRuntimeEnvironmentController {
}
private static void globalInitInner() throws IOException {
- if (RAVENWOOD_VERBOSE_LOGGING) {
- Log.v(TAG, "globalInit() called here...", new RuntimeException("NOT A CRASH"));
- }
+ // We haven't initialized liblog yet, so directly write to System.out here.
+ RavenwoodCommonUtils.log(TAG, "globalInitInner()");
+
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
- Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
+ Thread.setDefaultUncaughtExceptionHandler(
+ RavenwoodRuntimeEnvironmentController::reportUncaughtExceptions);
}
// Some process-wide initialization:
@@ -228,9 +267,9 @@ public class RavenwoodRuntimeEnvironmentController {
RuntimeInit.redirectLogStreams();
dumpCommandLineArgs();
-
- // We haven't initialized liblog yet, so directly write to System.out here.
- RavenwoodCommonUtils.log(TAG, "globalInitInner()");
+ dumpEnvironment();
+ dumpJavaProperties();
+ dumpOtherInfo();
// Make sure libravenwood_runtime is loaded.
System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));
@@ -241,6 +280,13 @@ public class RavenwoodRuntimeEnvironmentController {
// Do the basic set up for the android sysprops.
RavenwoodSystemProperties.initialize();
+ // Set ICU data file
+ String icuData = RavenwoodCommonUtils.getRavenwoodRuntimePath()
+ + "ravenwood-data/"
+ + RavenwoodRuntimeNative.getIcuDataName()
+ + ".dat";
+ RavenwoodRuntimeNative.setSystemProperty("ro.icu.data.path", icuData);
+
// Enable all log levels for native logging, until we'll have a way to change the native
// side log level at runtime.
// Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()),
@@ -256,10 +302,19 @@ public class RavenwoodRuntimeEnvironmentController {
// Make sure libandroid_runtime is loaded.
RavenwoodNativeLoader.loadFrameworkNativeCode();
+ // Start method logging.
+ RavenwoodMethodCallLogger.enable(sStdOut);
+
// Touch some references early to ensure they're <clinit>'ed
Objects.requireNonNull(Build.TYPE);
Objects.requireNonNull(Build.VERSION.SDK);
+ // Fonts can only be initialized once
+ // AOSP only: typeface is not supported on AOSP.
+ // Typeface.init();
+ // Typeface.loadPreinstalledSystemFontMap();
+ // Typeface.loadNativeSystemFonts();
+
System.setProperty(RAVENWOOD_VERSION_JAVA_SYSPROP, "1");
// This will let AndroidJUnit4 use the original runner.
System.setProperty("android.junit.runner",
@@ -283,6 +338,7 @@ public class RavenwoodRuntimeEnvironmentController {
ActivityManager.init$ravenwood(SYSTEM.getIdentifier());
final var main = new HandlerThread(MAIN_THREAD_NAME);
+ sMainThread = main;
main.start();
Looper.setMainLooperForTest(main.getLooper());
@@ -329,9 +385,20 @@ public class RavenwoodRuntimeEnvironmentController {
var systemServerContext =
new RavenwoodContext(ANDROID_PACKAGE_NAME, main, systemResourcesLoader);
- sInstrumentation = new Instrumentation();
- sInstrumentation.basicInit(instContext, targetContext, null);
- InstrumentationRegistry.registerInstance(sInstrumentation, Bundle.EMPTY);
+ var instArgs = Bundle.EMPTY;
+ RavenwoodUtils.runOnMainThreadSync(() -> {
+ try {
+ // TODO We should get the instrumentation class name from the build file or
+ // somewhere.
+ var InstClass = Class.forName("android.app.Instrumentation");
+ sInstrumentation = (Instrumentation) InstClass.getConstructor().newInstance();
+ sInstrumentation.basicInit(instContext, targetContext, null);
+ sInstrumentation.onCreate(instArgs);
+ } catch (Exception e) {
+ SneakyThrow.sneakyThrow(e);
+ }
+ });
+ InstrumentationRegistry.registerInstance(sInstrumentation, instArgs);
RavenwoodSystemServer.init(systemServerContext);
@@ -378,22 +445,46 @@ public class RavenwoodRuntimeEnvironmentController {
SystemProperties.clearChangeCallbacksForTest();
- if (ENABLE_TIMEOUT_STACKS) {
- sPendingTimeout = sTimeoutExecutor.schedule(
- RavenwoodRuntimeEnvironmentController::dumpStacks,
- TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- }
- if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
- maybeThrowPendingUncaughtException(false);
- }
+ maybeThrowPendingUncaughtException();
}
/**
- * Partially reset and initialize before each test method invocation
+ * Called when a test method is about to be started.
*/
- public static void initForMethod() {
+ public static void enterTestMethod(Description description) {
// TODO(b/375272444): this is a hacky workaround to ensure binder identity
Binder.restoreCallingIdentity(sCallingIdentity);
+
+ scheduleTimeout();
+ }
+
+ /**
+ * Called when a test method finished.
+ */
+ public static void exitTestMethod(Description description) {
+ cancelTimeout();
+ maybeThrowPendingUncaughtException();
+ }
+
+ private static void scheduleTimeout() {
+ if (!ENABLE_TIMEOUT_STACKS) {
+ return;
+ }
+ cancelTimeout();
+
+ sPendingTimeout = sTimeoutExecutor.schedule(
+ RavenwoodRuntimeEnvironmentController::onTestTimedOut,
+ TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+ }
+
+ private static void cancelTimeout() {
+ if (!ENABLE_TIMEOUT_STACKS) {
+ return;
+ }
+ var pt = sPendingTimeout;
+ if (pt != null) {
+ pt.cancel(false);
+ }
}
private static void initializeCompatIds() {
@@ -452,15 +543,36 @@ public class RavenwoodRuntimeEnvironmentController {
}
/**
+ * Return if an exception is benign and okay to continue running the main looper even
+ * if we detect it.
+ */
+ private static boolean isThrowableBenign(Throwable th) {
+ return th instanceof AssertionError || th instanceof AssumptionViolatedException;
+ }
+
+ static void dispatchMessage(Message msg) {
+ try {
+ msg.getTarget().dispatchMessage(msg);
+ } catch (Throwable th) {
+ var desc = String.format("Detected %s on looper thread %s", th.getClass().getName(),
+ Thread.currentThread());
+ sStdErr.println(desc);
+ if (TOLERATE_LOOPER_ASSERTS && isThrowableBenign(th)) {
+ sStdErr.printf("*** Continuing the test because it's %s ***\n",
+ th.getClass().getSimpleName());
+ var e = new Exception(desc, th);
+ sPendingUncaughtException.compareAndSet(null, e);
+ return;
+ }
+ throw th;
+ }
+ }
+
+ /**
* A callback when a test class finishes its execution, mostly only for debugging.
*/
public static void exitTestClass() {
- if (ENABLE_TIMEOUT_STACKS) {
- sPendingTimeout.cancel(false);
- }
- if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
- maybeThrowPendingUncaughtException(true);
- }
+ maybeThrowPendingUncaughtException();
}
public static void logTestRunner(String label, Description description) {
@@ -470,35 +582,70 @@ public class RavenwoodRuntimeEnvironmentController {
+ "(" + description.getTestClass().getName() + ")");
}
- private static void dumpStacks() {
- final PrintStream out = System.err;
- out.println("-----BEGIN ALL THREAD STACKS-----");
- final Map<Thread, StackTraceElement[]> stacks = Thread.getAllStackTraces();
- for (Map.Entry<Thread, StackTraceElement[]> stack : stacks.entrySet()) {
- out.println();
- Thread t = stack.getKey();
- out.println(t.toString() + " ID=" + t.getId());
- for (StackTraceElement e : stack.getValue()) {
- out.println("\tat " + e);
- }
+ private static void maybeThrowPendingUncaughtException() {
+ final Throwable pending = sPendingUncaughtException.getAndSet(null);
+ if (pending != null) {
+ throw new IllegalStateException("Found an uncaught exception", pending);
}
- out.println("-----END ALL THREAD STACKS-----");
}
/**
- * If there's a pending uncaught exception, consume and throw it now. Typically used to
- * report an exception on a background thread as a failure for the currently running test.
+ * Prints the stack trace from all threads.
*/
- private static void maybeThrowPendingUncaughtException(boolean duringReset) {
- final Throwable pending = sPendingUncaughtException.getAndSet(null);
- if (pending != null) {
- if (duringReset) {
- throw new IllegalStateException(
- "Found an uncaught exception during this test", pending);
- } else {
- throw new IllegalStateException(
- "Found an uncaught exception before this test started", pending);
+ private static void onTestTimedOut() {
+ sStdErr.println("********* SLOW TEST DETECTED ********");
+ dumpStacks(null, null);
+ }
+
+ private static final Object sDumpStackLock = new Object();
+
+ /**
+ * Prints the stack trace from all threads.
+ */
+ private static void dumpStacks(
+ @Nullable Thread exceptionThread, @Nullable Throwable throwable) {
+ cancelTimeout();
+ synchronized (sDumpStackLock) {
+ final PrintStream out = sStdErr;
+ out.println("-----BEGIN ALL THREAD STACKS-----");
+
+ var stacks = Thread.getAllStackTraces();
+ var threads = stacks.keySet().stream().sorted(
+ Comparator.comparingLong(Thread::getId)).collect(Collectors.toList());
+
+ // Put the test and the main thread at the top.
+ var testThread = sTestThread;
+ var mainThread = sMainThread;
+ if (mainThread != null) {
+ threads.remove(mainThread);
+ threads.add(0, mainThread);
+ }
+ if (testThread != null) {
+ threads.remove(testThread);
+ threads.add(0, testThread);
+ }
+ // Put the exception thread at the top.
+ // Also inject the stacktrace from the exception.
+ if (exceptionThread != null) {
+ threads.remove(exceptionThread);
+ threads.add(0, exceptionThread);
+ stacks.put(exceptionThread, throwable.getStackTrace());
+ }
+ for (var th : threads) {
+ out.println();
+
+ out.print("Thread");
+ if (th == exceptionThread) {
+ out.print(" [** EXCEPTION THREAD **]");
+ }
+ out.print(": " + th.getName() + " / " + th);
+ out.println();
+
+ for (StackTraceElement e : stacks.get(th)) {
+ out.println("\tat " + e);
+ }
}
+ out.println("-----END ALL THREAD STACKS-----");
}
}
@@ -524,13 +671,17 @@ public class RavenwoodRuntimeEnvironmentController {
() -> Class.forName("org.mockito.Matchers"));
}
- // TODO: use the real UiAutomation class instead of a mock
- private static UiAutomation createMockUiAutomation() {
- sAdoptedPermissions = Collections.emptySet();
- var mock = mock(UiAutomation.class, inv -> {
+ static <T> T makeDefaultThrowMock(Class<T> clazz) {
+ return mock(clazz, inv -> {
HostTestUtils.onThrowMethodCalled();
return null;
});
+ }
+
+ // TODO: use the real UiAutomation class instead of a mock
+ private static UiAutomation createMockUiAutomation() {
+ sAdoptedPermissions = Collections.emptySet();
+ var mock = makeDefaultThrowMock(UiAutomation.class);
doAnswer(inv -> {
sAdoptedPermissions = UiAutomation.ALL_PERMISSIONS;
return null;
@@ -564,4 +715,50 @@ public class RavenwoodRuntimeEnvironmentController {
Log.v(TAG, " " + arg);
}
}
+
+ private static void reportUncaughtExceptions(Thread th, Throwable e) {
+ sStdErr.printf("Uncaught exception detected: %s: %s\n",
+ th, RavenwoodCommonUtils.getStackTraceString(e));
+
+ doBugreport(th, e, DIE_ON_UNCAUGHT_EXCEPTION);
+ }
+
+ private static void doBugreport(
+ @Nullable Thread exceptionThread, @Nullable Throwable throwable,
+ boolean killSelf) {
+ // TODO: Print more information
+ dumpStacks(exceptionThread, throwable);
+ if (killSelf) {
+ System.exit(13);
+ }
+ }
+
+ private static void dumpJavaProperties() {
+ Log.v(TAG, "JVM properties:");
+ dumpMap(System.getProperties());
+ }
+
+ private static void dumpEnvironment() {
+ Log.v(TAG, "Environment:");
+ dumpMap(System.getenv());
+ }
+
+ private static void dumpMap(Map<?, ?> map) {
+ for (var key : map.keySet().stream().sorted().toList()) {
+ Log.v(TAG, " " + key + "=" + map.get(key));
+ }
+ }
+ private static void dumpOtherInfo() {
+ Log.v(TAG, "Other key information:");
+ var jloc = Locale.getDefault();
+ Log.v(TAG, " java.util.Locale=" + jloc + " / " + jloc.toLanguageTag());
+ var uloc = ULocale.getDefault();
+ Log.v(TAG, " android.icu.util.ULocale=" + uloc + " / " + uloc.toLanguageTag());
+
+ var jtz = java.util.TimeZone.getDefault();
+ Log.v(TAG, " java.util.TimeZone=" + jtz.getDisplayName() + " / " + jtz);
+
+ var itz = android.icu.util.TimeZone.getDefault();
+ Log.v(TAG, " android.icu.util.TimeZone=" + itz.getDisplayName() + " / " + itz);
+ }
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 70c161c1f19a..819d93a9c336 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
@@ -45,6 +46,9 @@ public class RavenwoodSystemProperties {
/** The default values. */
static final Map<String, String> sDefaultValues = new HashMap<>();
+ static final Set<String> sReadableKeys = new HashSet<>();
+ static final Set<String> sWritableKeys = new HashSet<>();
+
private static final String[] PARTITIONS = {
"bootimage",
"odm",
@@ -88,9 +92,24 @@ public class RavenwoodSystemProperties {
ravenwoodProps.forEach((key, origValue) -> {
final String value;
- // If a value starts with "$$$", then this is a reference to the device-side value.
if (origValue.startsWith("$$$")) {
+ // If a value starts with "$$$", then:
+ // - If it's "$$$r", the key is allowed to read.
+ // - If it's "$$$w", the key is allowed to write.
+ // - Otherwise, it's a reference to the device-side value.
+ // In case of $$$r and $$$w, if the key ends with a '.', then it'll be treaded
+ // as a prefix match.
var deviceKey = origValue.substring(3);
+ if ("r".equals(deviceKey)) {
+ sReadableKeys.add(key);
+ Log.v(TAG, key + " (readable)");
+ return;
+ } else if ("w".equals(deviceKey)) {
+ sWritableKeys.add(key);
+ Log.v(TAG, key + " (writable)");
+ return;
+ }
+
var deviceValue = deviceProps.get(deviceKey);
if (deviceValue == null) {
throw new RuntimeException("Failed to initialize system properties. Key '"
@@ -131,50 +150,38 @@ public class RavenwoodSystemProperties {
sDefaultValues.forEach(RavenwoodRuntimeNative::setSystemProperty);
}
- private static boolean isKeyReadable(String key) {
- // All writable keys are also readable
- if (isKeyWritable(key)) return true;
+ private static boolean checkAllowedInner(String key, Set<String> allowed) {
+ if (allowed.contains(key)) {
+ return true;
+ }
- final String root = getKeyRoot(key);
+ // Also search for a prefix match.
+ for (var k : allowed) {
+ if (k.endsWith(".") && key.startsWith(k)) {
+ return true;
+ }
+ }
+ return false;
+ }
- // This set is carefully curated to help identify situations where a test may
- // accidentally depend on a default value of an obscure property whose owner hasn't
- // decided how Ravenwood should behave.
- if (root.startsWith("boot.")) return true;
- if (root.startsWith("build.")) return true;
- if (root.startsWith("product.")) return true;
- if (root.startsWith("soc.")) return true;
- if (root.startsWith("system.")) return true;
+ private static boolean checkAllowed(String key, Set<String> allowed) {
+ return checkAllowedInner(key, allowed) || checkAllowedInner(getKeyRoot(key), allowed);
+ }
+ private static boolean isKeyReadable(String key) {
// All core values should be readable
- if (sDefaultValues.containsKey(key)) return true;
-
- // Hardcoded allowlist
- return switch (key) {
- case "gsm.version.baseband",
- "no.such.thing",
- "qemu.sf.lcd_density",
- "ro.bootloader",
- "ro.hardware",
- "ro.hw_timeout_multiplier",
- "ro.odm.build.media_performance_class",
- "ro.sf.lcd_density",
- "ro.treble.enabled",
- "ro.vndk.version",
- "ro.icu.data.path" -> true;
- default -> false;
- };
+ if (sDefaultValues.containsKey(key)) {
+ return true;
+ }
+ if (checkAllowed(key, sReadableKeys)) {
+ return true;
+ }
+ // All writable keys are also readable
+ return isKeyWritable(key);
}
private static boolean isKeyWritable(String key) {
- final String root = getKeyRoot(key);
-
- if (root.startsWith("debug.")) return true;
-
- // For PropertyInvalidatedCache
- if (root.startsWith("cache_key.")) return true;
-
- return false;
+ return checkAllowed(key, sWritableKeys);
}
static boolean isKeyAccessible(String key, boolean write) {
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java
index 19c1bffaebcd..3e2c4051b792 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodUtils.java
@@ -15,7 +15,20 @@
*/
package android.platform.test.ravenwood;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.ReflectedMethod.reflectMethod;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+
import com.android.ravenwood.common.RavenwoodCommonUtils;
+import com.android.ravenwood.common.SneakyThrow;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
/**
* Utilities for writing (bivalent) ravenwood tests.
@@ -47,4 +60,129 @@ public class RavenwoodUtils {
public static void loadJniLibrary(String libname) {
RavenwoodCommonUtils.loadJniLibrary(libname);
}
+
+ private class MainHandlerHolder {
+ static Handler sMainHandler = new Handler(Looper.getMainLooper());
+ }
+
+ /**
+ * Returns the main thread handler.
+ */
+ public static Handler getMainHandler() {
+ return MainHandlerHolder.sMainHandler;
+ }
+
+ /**
+ * Run a Callable on Handler and wait for it to complete.
+ */
+ @Nullable
+ public static <T> T runOnHandlerSync(@NonNull Handler h, @NonNull Callable<T> c) {
+ var result = new AtomicReference<T>();
+ var thrown = new AtomicReference<Throwable>();
+ var latch = new CountDownLatch(1);
+ h.post(() -> {
+ try {
+ result.set(c.call());
+ } catch (Throwable th) {
+ thrown.set(th);
+ }
+ latch.countDown();
+ });
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ throw new RuntimeException("Interrupted while waiting on the Runnable", e);
+ }
+ var th = thrown.get();
+ if (th != null) {
+ SneakyThrow.sneakyThrow(th);
+ }
+ return result.get();
+ }
+
+
+ /**
+ * Run a Runnable on Handler and wait for it to complete.
+ */
+ @Nullable
+ public static void runOnHandlerSync(@NonNull Handler h, @NonNull Runnable r) {
+ runOnHandlerSync(h, () -> {
+ r.run();
+ return null;
+ });
+ }
+
+ /**
+ * Run a Callable on main thread and wait for it to complete.
+ */
+ @Nullable
+ public static <T> T runOnMainThreadSync(@NonNull Callable<T> c) {
+ return runOnHandlerSync(getMainHandler(), c);
+ }
+
+ /**
+ * Run a Runnable on main thread and wait for it to complete.
+ */
+ @Nullable
+ public static void runOnMainThreadSync(@NonNull Runnable r) {
+ runOnHandlerSync(getMainHandler(), r);
+ }
+
+ public static class MockitoHelper {
+ private MockitoHelper() {
+ }
+
+ /**
+ * Allow verifyZeroInteractions to work on ravenwood. It was replaced with a different
+ * method on. (Maybe we should do it in Ravenizer.)
+ */
+ public static void verifyZeroInteractions(Object... mocks) {
+ if (RavenwoodRule.isOnRavenwood()) {
+ // Mockito 4 or later
+ reflectMethod("org.mockito.Mockito", "verifyNoInteractions", Object[].class)
+ .callStatic(new Object[]{mocks});
+ } else {
+ // Mockito 2
+ reflectMethod("org.mockito.Mockito", "verifyZeroInteractions", Object[].class)
+ .callStatic(new Object[]{mocks});
+ }
+ }
+ }
+
+
+ /**
+ * Wrap the given {@link Supplier} to become memoized.
+ *
+ * The underlying {@link Supplier} will only be invoked once, and that result will be cached
+ * and returned for any future requests.
+ */
+ static <T> Supplier<T> memoize(ThrowingSupplier<T> supplier) {
+ return new Supplier<>() {
+ private T mInstance;
+
+ @Override
+ public T get() {
+ synchronized (this) {
+ if (mInstance == null) {
+ mInstance = create();
+ }
+ return mInstance;
+ }
+ }
+
+ private T create() {
+ try {
+ return supplier.get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ /** Used by {@link #memoize(ThrowingSupplier)} */
+ public interface ThrowingSupplier<T> {
+ /** */
+ T get() throws Exception;
+ }
}
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 a967a3fff0d7..893b354d4645 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -26,10 +26,12 @@ import java.io.FileInputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import java.util.Objects;
import java.util.function.Supplier;
public class RavenwoodCommonUtils {
@@ -329,4 +331,70 @@ public class RavenwoodCommonUtils {
public static <T> T withDefault(@Nullable T value, @Nullable T def) {
return value != null ? value : def;
}
+
+ /**
+ * Utility for calling a method with reflections. Used to call a method by name.
+ * Note, this intentionally does _not_ support non-public methods, as we generally
+ * shouldn't violate java visibility in ravenwood.
+ *
+ * @param <TTHIS> class owning the method.
+ */
+ public static class ReflectedMethod<TTHIS> {
+ private final Class<TTHIS> mThisClass;
+ private final Method mMethod;
+
+ private ReflectedMethod(Class<TTHIS> thisClass, Method method) {
+ mThisClass = thisClass;
+ mMethod = method;
+ }
+
+ /** Factory method. */
+ @SuppressWarnings("unchecked")
+ public static <TTHIS> ReflectedMethod<TTHIS> reflectMethod(
+ @NonNull Class<TTHIS> clazz, @NonNull String methodName,
+ @NonNull Class<?>... argTypes) {
+ try {
+ return new ReflectedMethod(clazz, clazz.getMethod(methodName, argTypes));
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Factory method. */
+ @SuppressWarnings("unchecked")
+ public static <TTHIS> ReflectedMethod<TTHIS> reflectMethod(
+ @NonNull String className, @NonNull String methodName,
+ @NonNull Class<?>... argTypes) {
+ try {
+ return reflectMethod((Class<TTHIS>) Class.forName(className), methodName, argTypes);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Call the instance method */
+ @SuppressWarnings("unchecked")
+ public <RET> RET call(@NonNull TTHIS thisObject, @NonNull Object... args) {
+ try {
+ return (RET) mMethod.invoke(Objects.requireNonNull(thisObject), args);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Call the static method */
+ @SuppressWarnings("unchecked")
+ public <RET> RET callStatic(@NonNull Object... args) {
+ try {
+ return (RET) mMethod.invoke(null, args);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /** Handy method to create an array */
+ public static <T> T[] arr(@NonNull T... objects) {
+ return objects;
+ }
}
diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
index 7ab9cda378b7..855a4ff21671 100644
--- a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
+++ b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
@@ -21,7 +21,6 @@ import android.util.Log.Level;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.RuntimeInit;
import com.android.ravenwood.RavenwoodRuntimeNative;
-import com.android.ravenwood.common.RavenwoodCommonUtils;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
@@ -164,7 +163,7 @@ public class Log_ravenwood {
* Return the "real" {@code System.out} if it's been swapped by {@code RavenwoodRuleImpl}, so
* that we don't end up in a recursive loop.
*/
- private static PrintStream getRealOut() {
+ public static PrintStream getRealOut() {
if (RuntimeInit.sOut$ravenwood != null) {
return RuntimeInit.sOut$ravenwood;
} else {
diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java
index 96aed4b3401d..d5a96ddc3a98 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodJdkPatch.java
@@ -20,6 +20,7 @@ import com.android.ravenwood.common.JvmWorkaround;
import java.io.FileDescriptor;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.regex.Pattern;
/**
* Class to host APIs that exist in libcore, but not in standard JRE.
@@ -46,4 +47,22 @@ public class RavenwoodJdkPatch {
final var it = map.entrySet().iterator();
return it.hasNext() ? it.next() : null;
}
+
+ /**
+ * Implements Pattern.compile(String)
+ *
+ * ART always assumes UNICODE_CHARACTER_CLASS is set.
+ */
+ public static Pattern compilePattern(String regex) {
+ return Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS);
+ }
+
+ /**
+ * Implements Pattern.compile(String, int)
+ *
+ * ART always assumes UNICODE_CHARACTER_CLASS is set.
+ */
+ public static Pattern compilePattern(String regex, int flag) {
+ return Pattern.compile(regex, flag | Pattern.UNICODE_CHARACTER_CLASS);
+ }
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
index acbcdf1926db..0d82a8691881 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java
@@ -66,6 +66,8 @@ public class RavenwoodRuntimeNative {
public static native int gettid();
+ public static native String getIcuDataName();
+
public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException {
return nLseek(JvmWorkaround.getInstance().getFdInt(fd), offset, whence);
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java
new file mode 100644
index 000000000000..82bab64f22f3
--- /dev/null
+++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/CloseGuard.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dalvik.system;
+
+/**
+ * A no-op copy of libcore/dalvik/src/main/java/dalvik/system/CloseGuard.java
+ */
+public final class CloseGuard {
+
+ /**
+ * Returns a CloseGuard instance. {@code #open(String)} can be used to set
+ * up the instance to warn on failure to close.
+ *
+ * @return {@link CloseGuard} instance.
+ *
+ * @hide
+ */
+ public static CloseGuard get() {
+ return new CloseGuard();
+ }
+
+ /**
+ * Enables/disables stack capture and tracking. A call stack is captured
+ * during open(), and open/close events are reported to the Tracker, only
+ * if enabled is true. If a stack trace was captured, the {@link
+ * #getReporter() reporter} is informed of unclosed resources; otherwise a
+ * one-line warning is logged.
+ *
+ * @param enabled whether stack capture and tracking is enabled.
+ *
+ * @hide
+ */
+ public static void setEnabled(boolean enabled) {
+ }
+
+ /**
+ * True if CloseGuard stack capture and tracking are enabled.
+ *
+ * @hide
+ */
+ public static boolean isEnabled() {
+ return false;
+ }
+
+ /**
+ * Used to replace default Reporter used to warn of CloseGuard
+ * violations when stack tracking is enabled. Must be non-null.
+ *
+ * @param rep replacement for default Reporter.
+ *
+ * @hide
+ */
+ public static void setReporter(Reporter rep) {
+ if (rep == null) {
+ throw new NullPointerException("reporter == null");
+ }
+ }
+
+ /**
+ * Returns non-null CloseGuard.Reporter.
+ *
+ * @return CloseGuard's Reporter.
+ *
+ * @hide
+ */
+ public static Reporter getReporter() {
+ return null;
+ }
+
+ /**
+ * Sets the {@link Tracker} that is notified when resources are allocated and released.
+ * The Tracker is invoked only if CloseGuard {@link #isEnabled()} held when {@link #open()}
+ * was called. A null argument disables tracking.
+ *
+ * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+ * MUST NOT be used for any other purposes.
+ *
+ * @hide
+ */
+ public static void setTracker(Tracker tracker) {
+ }
+
+ /**
+ * Returns {@link #setTracker(Tracker) last Tracker that was set}, or null to indicate
+ * there is none.
+ *
+ * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+ * MUST NOT be used for any other purposes.
+ *
+ * @hide
+ */
+ public static Tracker getTracker() {
+ return null;
+ }
+
+ private CloseGuard() {}
+
+ /**
+ * {@code open} initializes the instance with a warning that the caller
+ * should have explicitly called the {@code closer} method instead of
+ * relying on finalization.
+ *
+ * @param closer non-null name of explicit termination method. Printed by warnIfOpen.
+ * @throws NullPointerException if closer is null.
+ *
+ * @hide
+ */
+ public void open(String closer) {
+ openWithCallSite(closer, null /* callsite */);
+ }
+
+ /**
+ * Like {@link #open(String)}, but with explicit callsite string being passed in for better
+ * performance.
+ * <p>
+ * This only has better performance than {@link #open(String)} if {@link #isEnabled()} returns {@code true}, which
+ * usually shouldn't happen on release builds.
+ *
+ * @param closer Non-null name of explicit termination method. Printed by warnIfOpen.
+ * @param callsite Non-null string uniquely identifying the callsite.
+ *
+ * @hide
+ */
+ public void openWithCallSite(String closer, String callsite) {
+ }
+
+ // We keep either an allocation stack containing the closer String or, when
+ // in disabled state, just the closer String.
+ // We keep them in a single field only to minimize overhead.
+ private Object /* String or Throwable */ closerNameOrAllocationInfo;
+
+ /**
+ * Marks this CloseGuard instance as closed to avoid warnings on
+ * finalization.
+ *
+ * @hide
+ */
+ public void close() {
+ }
+
+ /**
+ * Logs a warning if the caller did not properly cleanup by calling an
+ * explicit close method before finalization. If CloseGuard was enabled
+ * when the CloseGuard was created, passes the stacktrace associated with
+ * the allocation to the current reporter. If it was not enabled, it just
+ * directly logs a brief message.
+ *
+ * @hide
+ */
+ public void warnIfOpen() {
+ }
+
+
+ /**
+ * Interface to allow customization of tracking behaviour.
+ *
+ * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+ * MUST NOT be used for any other purposes.
+ *
+ * @hide
+ */
+ public interface Tracker {
+ void open(Throwable allocationSite);
+ void close(Throwable allocationSite);
+ }
+
+ /**
+ * Interface to allow customization of reporting behavior.
+ * @hide
+ */
+ public interface Reporter {
+ /**
+ *
+ * @hide
+ */
+ void report(String message, Throwable allocationSite);
+
+ /**
+ *
+ * @hide
+ */
+ default void report(String message) {}
+ }
+}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
index eaadac6a8b92..50cfd3bbe863 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
@@ -57,4 +57,12 @@ public class VMRuntime {
public int getTargetSdkVersion() {
return RavenwoodRuntimeState.sTargetSdkLevel;
}
+
+ /** Ignored on ravenwood. */
+ public void registerNativeAllocation(long bytes) {
+ }
+
+ /** Ignored on ravenwood. */
+ public void registerNativeFree(long bytes) {
+ }
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java
new file mode 100644
index 000000000000..2a1ee2542982
--- /dev/null
+++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/io/IoBridge.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class IoBridge {
+
+ public static void closeAndSignalBlockedThreads(FileDescriptor fd) throws IOException {
+ if (fd == null) {
+ return;
+ }
+ try {
+ Os.close(fd);
+ } catch (ErrnoException errnoException) {
+ throw errnoException.rethrowAsIOException();
+ }
+ }
+
+ public static FileDescriptor open(String path, int flags) throws FileNotFoundException {
+ FileDescriptor fd = null;
+ try {
+ fd = Os.open(path, flags, 0666);
+ // Posix open(2) fails with EISDIR only if you ask for write permission.
+ // Java disallows reading directories too.f
+ if (OsConstants.S_ISDIR(Os.fstat(fd).st_mode)) {
+ throw new ErrnoException("open", OsConstants.EISDIR);
+ }
+ return fd;
+ } catch (ErrnoException errnoException) {
+ try {
+ if (fd != null) {
+ closeAndSignalBlockedThreads(fd);
+ }
+ } catch (IOException ignored) {
+ }
+ FileNotFoundException ex = new FileNotFoundException(path + ": "
+ + errnoException.getMessage());
+ ex.initCause(errnoException);
+ throw ex;
+ }
+ }
+}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java
index ad86135de32e..985e00e8641d 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NativeAllocationRegistry.java
@@ -35,6 +35,11 @@ public class NativeAllocationRegistry {
return new NativeAllocationRegistry(classLoader, freeFunction, size);
}
+ public static NativeAllocationRegistry createNonmalloced(
+ Class clazz, long freeFunction, long size) {
+ return new NativeAllocationRegistry(clazz.getClassLoader(), freeFunction, size);
+ }
+
public static NativeAllocationRegistry createMalloced(
ClassLoader classLoader, long freeFunction, long size) {
return new NativeAllocationRegistry(classLoader, freeFunction, size);
@@ -45,6 +50,11 @@ public class NativeAllocationRegistry {
return new NativeAllocationRegistry(classLoader, freeFunction, 0);
}
+ public static NativeAllocationRegistry createMalloced(
+ Class clazz, long freeFunction, long size) {
+ return new NativeAllocationRegistry(clazz.getClassLoader(), freeFunction, size);
+ }
+
public NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size) {
if (size < 0) {
throw new IllegalArgumentException("Invalid native allocation size: " + size);
@@ -52,21 +62,67 @@ public class NativeAllocationRegistry {
mFreeFunction = freeFunction;
}
+ private class CleanerThunk implements Runnable {
+ private long nativePtr;
+
+ public CleanerThunk() {
+ nativePtr = 0;
+ }
+
+ public void setNativePtr(long ptr) {
+ nativePtr = ptr;
+ }
+
+ @Override
+ public void run() {
+ if (nativePtr != 0) {
+ applyFreeFunction(mFreeFunction, nativePtr);
+ }
+ }
+ }
+
+ private static class CleanableRunner implements Runnable {
+ private final Cleaner.Cleanable mCleanable;
+
+ public CleanableRunner(Cleaner.Cleanable cleanable) {
+ mCleanable = cleanable;
+ }
+
+ public void run() {
+ mCleanable.clean();
+ }
+ }
+
public Runnable registerNativeAllocation(Object referent, long nativePtr) {
if (referent == null) {
throw new IllegalArgumentException("referent is null");
}
+ if (mFreeFunction == 0) {
+ return () -> {}; // do nothing
+ }
if (nativePtr == 0) {
throw new IllegalArgumentException("nativePtr is null");
}
- final Runnable releaser = () -> {
- RavenwoodRuntimeNative.applyFreeFunction(mFreeFunction, nativePtr);
- };
- sCleaner.register(referent, releaser);
+ final CleanerThunk thunk;
+ final CleanableRunner result;
+ try {
+ thunk = new CleanerThunk();
+ final var cleanable = sCleaner.register(referent, thunk);
+ result = new CleanableRunner(cleanable);
+ } catch (VirtualMachineError vme /* probably OutOfMemoryError */) {
+ applyFreeFunction(mFreeFunction, nativePtr);
+ throw vme;
+ }
+ // Enable the cleaner only after we can no longer throw anything, including OOME.
+ thunk.setNativePtr(nativePtr);
// Ensure that cleaner doesn't get invoked before we enable it.
Reference.reachabilityFence(referent);
- return releaser;
+ return result;
+ }
+
+ public static void applyFreeFunction(long freeFunction, long nativePtr) {
+ RavenwoodRuntimeNative.applyFreeFunction(freeFunction, nativePtr);
}
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NonNull.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NonNull.java
index db3cd8ed712f..1153a77d5c9a 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NonNull.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/NonNull.java
@@ -35,14 +35,4 @@ import java.lang.annotation.Target;
@Retention(SOURCE)
@Target({FIELD, METHOD, PARAMETER, TYPE_USE})
@libcore.api.IntraCoreApi
-public @interface NonNull {
- /**
- * Min Android API level (inclusive) to which this annotation is applied.
- */
- int from() default Integer.MIN_VALUE;
-
- /**
- * Max Android API level to which this annotation is applied.
- */
- int to() default Integer.MAX_VALUE;
-}
+public @interface NonNull {}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Nullable.java b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Nullable.java
index 3371978b0568..295f083426ff 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Nullable.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/libcore/util/Nullable.java
@@ -35,14 +35,4 @@ import java.lang.annotation.Target;
@Retention(SOURCE)
@Target({FIELD, METHOD, PARAMETER, TYPE_USE})
@libcore.api.IntraCoreApi
-public @interface Nullable {
- /**
- * Min Android API level (inclusive) to which this annotation is applied.
- */
- int from() default Integer.MIN_VALUE;
-
- /**
- * Max Android API level to which this annotation is applied.
- */
- int to() default Integer.MAX_VALUE;
-}
+public @interface Nullable {}
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index 391c5d56b212..8a35ade649b2 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -26,6 +26,10 @@
#include <fcntl.h>
#include <set>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <cstdlib>
#include "jni_helper.h"
@@ -182,17 +186,82 @@ static jboolean removeSystemProperty(JNIEnv* env, jclass, jstring javaKey) {
}
}
+// Find the PPID of child_pid using /proc/N/stat. The 4th field is the PPID.
+// Also returns child_pid's process name (2nd field).
+static pid_t getppid_of(pid_t child_pid, std::string& out_process_name) {
+ if (child_pid < 0) {
+ return -1;
+ }
+ std::string stat_file = "/proc/" + std::to_string(child_pid) + "/stat";
+ std::ifstream stat_stream(stat_file);
+ if (!stat_stream.is_open()) {
+ ALOGW("Unable to open '%s': %s", stat_file.c_str(), strerror(errno));
+ return -1;
+ }
+
+ std::string field;
+ int field_count = 0;
+ while (std::getline(stat_stream, field, ' ')) {
+ if (++field_count == 4) {
+ return atoi(field.c_str());
+ }
+ if (field_count == 2) {
+ out_process_name = field;
+ }
+ }
+ ALOGW("Unexpected format in '%s'", stat_file.c_str());
+ return -1;
+}
+
+// Find atest's PID. Climb up the process tree, and find "atest-py3".
+static pid_t find_atest_pid() {
+ auto ret = getpid(); // self (isolation runner process)
+
+ while (ret != -1) {
+ std::string proc;
+ ret = getppid_of(ret, proc);
+ if (proc == "(atest-py3)") {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+// If $RAVENWOOD_LOG_OUT is set, redirect stdout/err to this file.
+// Originally it was added to allow to monitor log in realtime, with
+// RAVENWOOD_LOG_OUT=$(tty) atest...
+//
+// As a special case, if $RAVENWOOD_LOG_OUT is set to "-", we try to find
+// atest's process and send the output to its stdout. It's sort of hacky, but
+// this allows shell redirection to work on Ravenwood output too,
+// so e.g. `atest ... |tee atest.log` would work on Ravenwood's output.
+// (which wouldn't work with `RAVENWOOD_LOG_OUT=$(tty)`).
+//
+// Otherwise -- if $RAVENWOOD_LOG_OUT isn't set -- atest/tradefed just writes
+// the test's output to its own log file.
static void maybeRedirectLog() {
auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT");
- if (ravenwoodLogOut == NULL) {
+ if (ravenwoodLogOut == NULL || *ravenwoodLogOut == '\0') {
return;
}
- ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to %s", ravenwoodLogOut);
+ std::string path;
+ if (strcmp("-", ravenwoodLogOut) == 0) {
+ pid_t ppid = find_atest_pid();
+ if (ppid < 0) {
+ ALOGI("RAVENWOOD_LOG_OUT set to '-', but unable to find atest's PID");
+ return;
+ }
+ path = std::format("/proc/{}/fd/1", ppid);
+ } else {
+ path = ravenwoodLogOut;
+ }
+ ALOGI("RAVENWOOD_LOG_OUT set. Redirecting output to '%s'", path.c_str());
// Redirect stdin / stdout to /dev/tty.
- int ttyFd = open(ravenwoodLogOut, O_WRONLY | O_APPEND);
+ int ttyFd = open(path.c_str(), O_WRONLY | O_APPEND);
if (ttyFd == -1) {
- ALOGW("$RAVENWOOD_LOG_OUT is set to %s, but failed to open: %s ", ravenwoodLogOut,
+ ALOGW("$RAVENWOOD_LOG_OUT is set, but failed to open '%s': %s ", path.c_str(),
strerror(errno));
return;
}
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index 8d8ed7119e84..01ebdc953539 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -20,6 +20,7 @@
#include <sys/syscall.h>
#include <unistd.h>
#include <utils/misc.h>
+#include <unicode/utypes.h>
#include <string>
@@ -183,6 +184,10 @@ static jint Linux_gettid(JNIEnv* env, jobject) {
return syscall(__NR_gettid);
}
+static jstring getIcuDataName(JNIEnv* env, jclass clazz) {
+ return env->NewStringUTF(U_ICUDATA_NAME);
+}
+
// ---- Registration ----
extern void register_android_system_OsConstants(JNIEnv* env);
@@ -201,6 +206,7 @@ static const JNINativeMethod sMethods[] =
{ "setenv", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*)Linux_setenv },
{ "getpid", "()I", (void*)Linux_getpid },
{ "gettid", "()I", (void*)Linux_gettid },
+ { "getIcuDataName", "()Ljava/lang/String;", (void*)getIcuDataName },
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
diff --git a/ravenwood/scripts/add-annotations.sh b/ravenwood/scripts/add-annotations.sh
new file mode 100755
index 000000000000..8c394f51d8c4
--- /dev/null
+++ b/ravenwood/scripts/add-annotations.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# Copyright (C) 2025 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.
+
+#
+# Use "ravehleper mm" to create a shell script which:
+# - Reads read a list of methods from STDIN
+# Which basically looks like a list of 'com.android.ravenwoodtest.tests.Test1#testA'
+# - Add @DisabledOnRavenwood to them
+#
+# Example usage:
+#
+# ./add-annotations.sh $ANDROID_BUILD_TOP/frameworks/base/ravenwood/tests <METHOD-LIST.txt
+#
+# Use a different annotation instead. (Note, in order to use an at, you need to use a double-at.)
+# ./add-annotations.sh -t '@@Ignore' $ANDROID_BUILD_TOP/frameworks/base/ravenwood/tests <METHOD-LIST.txt
+#
+
+set -e
+
+# Uncomment it to always build ravenhelper (slow)
+# ${BUILD_CMD:-m} ravenhelper
+
+# We add this line to each methods found.
+# Note, if we used a single @, that'd be handled as an at file. Use
+# the double-at instead.
+annotation="@@android.platform.test.annotations.DisabledOnRavenwood(reason = \"bulk-disabled by script\")"
+while getopts "t:" opt; do
+case "$opt" in
+ t)
+ annotation="$OPTARG"
+ ;;
+ '?')
+ exit 1
+ ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+source_dirs="$@"
+
+OUT_SCRIPT="${OUT_SCRIPT:-/tmp/add-annotations.sh}"
+
+rm -f "$OUT_SCRIPT"
+
+
+with_flag() {
+ local flag="$1"
+ shift
+
+ for arg in "$@"; do
+ echo "$flag $arg"
+ done
+}
+
+run() {
+ echo "Running: $*"
+ "$@"
+}
+
+run ${RAVENHELPER_CMD:-ravenhelper mm} \
+ --output-script $OUT_SCRIPT \
+ --text "$annotation" \
+ $(with_flag --src $source_dirs)
+
+
+if ! [[ -f $OUT_SCRIPT ]] ; then
+ # no operations generated.
+ exit 0
+fi
+
+echo
+echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT"
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
index bdc1de0c44f4..0629b77029e0 100755
--- a/ravenwood/scripts/extract-last-soong-commands.py
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -32,7 +32,7 @@ re_command = re.compile(r''' ^\[.*?\] \s* (.*) ''', re.X)
HEADER = r'''#!/bin/bash
set -e # Stop on a failed command
-
+set -x # Print command line before executing
cd "${ANDROID_BUILD_TOP:?}"
'''
@@ -48,6 +48,7 @@ def main(args):
with open(outfile, "w") as out:
out.write(HEADER)
+ count = 0
with gzip.open(log) as f:
for line in f:
s = line.decode("utf-8")
@@ -63,16 +64,9 @@ def main(args):
if m:
command = m.groups()[0]
- out.write('#========\n')
-
- # Show the full command line before executing it.
- out.write('#echo ' + shlex.quote(command) + '\n')
- out.write('\n')
-
- # Execute the command.
- out.write('#' + command + '\n')
-
- out.write('\n')
+ count += 1
+ out.write(f'### Command {count} ========\n\n')
+ out.write('#' + command + '\n\n')
continue
diff --git a/ravenwood/scripts/pta-framework.sh b/ravenwood/scripts/pta-framework.sh
new file mode 100755
index 000000000000..d396839ec182
--- /dev/null
+++ b/ravenwood/scripts/pta-framework.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+# Copyright (C) 2025 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.
+
+#
+# Use "ravehleper pta" to create a shell script which:
+# - Reads the text "policy" files
+# - Convert to java annotations (using sed)
+#
+
+set -e
+
+
+# Uncomment it to always build ravenhelper (slow)
+# ${BUILD_CMD:-m} ravenhelper
+
+# Get the target directory. Default to $ANDROID_BUILD_TOP.
+TARGET_DIR="${TARGET_DIR:-${ANDROID_BUILD_TOP?\$ANDROID_BUILD_TOP must be set}}"
+
+echo "Target dir=$TARGET_DIR"
+
+cd "$TARGET_DIR"
+
+# Add -v or -d as needed.
+extra_args="$@"
+
+OUT_SCRIPT="${OUT_SCRIPT:-/tmp/pta.sh}"
+
+rm -f "$OUT_SCRIPT"
+
+# If you want to run on other files, run this script with the following
+# env vars predefined.
+
+POLICIES="${POLICIES:-
+frameworks/base/ravenwood/texts/ravenwood-common-policies.txt
+frameworks/base/ravenwood/texts/ravenwood-framework-policies.txt
+}"
+
+SOURCES="${SOURCES:-
+frameworks/base/core/java/
+frameworks/base/graphics/java/
+}"
+
+AAC="${AAC:-frameworks/base/ravenwood/texts/ravenwood-annotation-allowed-classes.txt}"
+
+with_flag() {
+ local flag="$1"
+ shift
+
+ for arg in "$@"; do
+ echo "$flag $arg"
+ done
+}
+
+run() {
+ echo "Running: $*"
+ "$@"
+}
+
+run_pta() {
+ local extra_args="$@"
+
+ run ${RAVENHELPER_CMD:-ravenhelper pta} \
+ --output-script $OUT_SCRIPT \
+ --annotation-allowed-classes-file $AAC \
+ $(with_flag --policy-override-file $POLICIES) \
+ $(with_flag --src $SOURCES) \
+ $extra_args
+
+ if ! [[ -f $OUT_SCRIPT ]] ; then
+ echo "No files need updating."
+ # no operations generated.
+ exit 0
+ fi
+
+ echo
+ echo "Created script at $OUT_SCRIPT. Run it with: sh $OUT_SCRIPT"
+ return 0
+}
+
+run_pta "$extra_args"
diff --git a/ravenwood/scripts/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh
index 27c5ea1bd0d7..67ebb1fc9473 100755
--- a/ravenwood/scripts/run-ravenwood-tests.sh
+++ b/ravenwood/scripts/run-ravenwood-tests.sh
@@ -66,7 +66,7 @@ esac
done
shift $(($OPTIND - 1))
-all_tests=(hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test ravenwood-stats-checker)
+all_tests=(hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test ravenwood-stats-checker ravenhelpertest)
all_tests+=( $(${0%/*}/list-ravenwood-tests.sh) )
filter() {
diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp
index ac545dfb06cc..c4086c5b3835 100644
--- a/ravenwood/tests/bivalenttest/Android.bp
+++ b/ravenwood/tests/bivalenttest/Android.bp
@@ -40,6 +40,7 @@ java_defaults {
"junit-params",
"platform-parametric-runner-lib",
+ "platform-compat-test-rules",
// To make sure it won't cause VerifyError (b/324063814)
"platformprotosnano",
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 882c91c43ee9..540b0822319c 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,31 +16,52 @@
package com.android.ravenwoodtest.bivalenttest.compat
import android.app.compat.CompatChanges
+import android.compat.testing.PlatformCompatChangeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest
-import org.junit.Assert
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class RavenwoodCompatFrameworkTest {
+
+ @get:Rule
+ val compatRule = PlatformCompatChangeRule()
+
@Test
fun testEnabled() {
- Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
+ assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
}
@Test
fun testDisabled() {
- Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_2))
+ assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_2))
}
@Test
fun testEnabledAfterSForUApps() {
- Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_3))
+ assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_3))
}
@Test
fun testEnabledAfterUForUApps() {
- Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
+ assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
+ }
+
+ @Test
+ @EnableCompatChanges(CompatIdsForTest.TEST_COMPAT_ID_5)
+ fun testEnableCompatChanges() {
+ assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_5))
+ }
+
+ @Test
+ @DisableCompatChanges(CompatIdsForTest.TEST_COMPAT_ID_5)
+ fun testDisableCompatChanges() {
+ assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_5))
}
}
diff --git a/ravenwood/tests/coretest/Android.bp b/ravenwood/tests/coretest/Android.bp
index 9dd7cc683719..182a7cf3d3de 100644
--- a/ravenwood/tests/coretest/Android.bp
+++ b/ravenwood/tests/coretest/Android.bp
@@ -33,3 +33,34 @@ android_ravenwood_test {
},
auto_gen_config: true,
}
+
+// Same as RavenwoodCoreTest, but it excludes tests using platform-parametric-runner-lib,
+// because that modules has too many dependencies and slow to build incrementally.
+android_ravenwood_test {
+ name: "RavenwoodCoreTest-light",
+
+ static_libs: [
+ "androidx.annotation_annotation",
+ "androidx.test.ext.junit",
+ "androidx.test.rules",
+
+ // This library should be removed by Ravenizer
+ "mockito-target-minus-junit4",
+ ],
+ libs: [
+ // We access internal private classes
+ "ravenwood-junit-impl",
+ ],
+ srcs: [
+ "test/**/*.java",
+ "test/**/*.kt",
+ ],
+
+ exclude_srcs: [
+ "test/com/android/ravenwoodtest/runnercallbacktests/*",
+ ],
+ ravenizer: {
+ strip_mockito: true,
+ },
+ auto_gen_config: true,
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java
new file mode 100644
index 000000000000..68387d76b675
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodMainThreadTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.coretest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.ravenwood.RavenwoodUtils;
+
+import org.junit.Test;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+public class RavenwoodMainThreadTest {
+ private static final boolean RUN_UNSAFE_TESTS =
+ "1".equals(System.getenv("RAVENWOOD_RUN_UNSAFE_TESTS"));
+
+ @Test
+ public void testRunOnMainThread() {
+ AtomicReference<Thread> thr = new AtomicReference<>();
+ RavenwoodUtils.runOnMainThreadSync(() -> {
+ thr.set(Thread.currentThread());
+ });
+ var th = thr.get();
+ assertThat(th).isNotNull();
+ assertThat(th).isNotEqualTo(Thread.currentThread());
+ }
+
+ /**
+ * Sleep a long time on the main thread. This test would then "pass", but Ravenwood
+ * should show the stack traces.
+ *
+ * This is "unsafe" because this test is slow.
+ */
+ @Test
+ public void testUnsafeMainThreadHang() {
+ assumeTrue(RUN_UNSAFE_TESTS);
+
+ // The test should time out.
+ RavenwoodUtils.runOnMainThreadSync(() -> {
+ try {
+ Thread.sleep(30_000);
+ } catch (InterruptedException e) {
+ fail("Interrupted");
+ }
+ });
+ }
+
+ /**
+ * AssertionError on the main thread would be swallowed and reported "normally".
+ * (Other kinds of exceptions would be caught by the unhandled exception handler, and kills
+ * the process)
+ *
+ * This is "unsafe" only because this feature can be disabled via the env var.
+ */
+ @Test
+ public void testUnsafeAssertFailureOnMainThread() {
+ assumeTrue(RUN_UNSAFE_TESTS);
+
+ assertThrows(AssertionError.class, () -> {
+ RavenwoodUtils.runOnMainThreadSync(() -> {
+ fail();
+ });
+ });
+ }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java
new file mode 100644
index 000000000000..421fb50e0c9a
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodReflectorTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.coretest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.ravenwood.common.RavenwoodCommonUtils.ReflectedMethod;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link ReflectedMethod}.
+ */
+public class RavenwoodReflectorTest {
+ /** test target */
+ public class Target {
+ private final int mVar;
+
+ /** test target */
+ public Target(int var) {
+ mVar = var;
+ }
+
+ /** test target */
+ public int foo(int x) {
+ return x + mVar;
+ }
+
+ /** test target */
+ public static int bar(int x) {
+ return x + 1;
+ }
+ }
+
+ /** Test for a non-static method call */
+ @Test
+ public void testNonStatic() {
+ var obj = new Target(5);
+
+ var m = ReflectedMethod.reflectMethod(Target.class, "foo", int.class);
+ assertThat((int) m.call(obj, 2)).isEqualTo(7);
+ }
+
+ /** Test for a static method call */
+ @Test
+ public void testStatic() {
+ var m = ReflectedMethod.reflectMethod(Target.class, "bar", int.class);
+ assertThat((int) m.callStatic(1)).isEqualTo(2);
+ }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java
new file mode 100644
index 000000000000..454f5a9576d9
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodSystemPropertiesTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.coretest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.fail;
+
+import android.os.SystemProperties;
+
+import org.junit.Test;
+
+public class RavenwoodSystemPropertiesTest {
+ @Test
+ public void testRead() {
+ assertThat(SystemProperties.get("ro.board.first_api_level")).isEqualTo("1");
+ }
+
+ @Test
+ public void testWrite() {
+ SystemProperties.set("debug.xxx", "5");
+ assertThat(SystemProperties.get("debug.xxx")).isEqualTo("5");
+ }
+
+ private static void assertException(String expectedMessage, Runnable r) {
+ try {
+ r.run();
+ fail("Excepted exception with message '" + expectedMessage + "' but wasn't thrown");
+ } catch (RuntimeException e) {
+ if (e.getMessage().contains(expectedMessage)) {
+ return;
+ }
+ fail("Excepted exception with message '" + expectedMessage + "' but was '"
+ + e.getMessage() + "'");
+ }
+ }
+
+
+ @Test
+ public void testReadDisallowed() {
+ assertException("Read access to system property 'nonexisitent' denied", () -> {
+ SystemProperties.get("nonexisitent");
+ });
+ }
+
+ @Test
+ public void testWriteDisallowed() {
+ assertException("failed to set system property \"ro.board.first_api_level\" ", () -> {
+ SystemProperties.set("ro.board.first_api_level", "2");
+ });
+ }
+}
diff --git a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
index 30abaa2e7d38..b1a40f082656 100644
--- a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
+++ b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
@@ -16,28 +16,27 @@
package com.android.ravenwoodtest;
import android.platform.test.annotations.IgnoreUnderRavenwood;
-import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Assert;
-import org.junit.Rule;
+import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class RavenwoodMinimumTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
- .setProcessApp()
- .build();
-
@Test
public void testSimple() {
Assert.assertTrue(android.os.Process.isApplicationUid(android.os.Process.myUid()));
}
@Test
+ public void testAssumeNot() {
+ Assume.assumeFalse(android.os.Process.isApplicationUid(android.os.Process.myUid()));
+ }
+
+ @Test
@IgnoreUnderRavenwood
public void testIgnored() {
throw new RuntimeException("Shouldn't be executed under ravenwood");
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index c196a09e18d1..7462cc2f384a 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -30,6 +30,10 @@ android.util.AndroidRuntimeException
android.util.ArrayMap
android.util.ArraySet
android.util.AtomicFile
+android.util.AtomicFileOutputStream
+android.util.AtomicFileBufferedOutputStream
+android.util.AtomicFilePrintWriter
+android.util.AtomicFileBufferedPrintWriter
android.util.BackupUtils
android.util.Base64
android.util.Base64DataException
@@ -111,6 +115,7 @@ android.util.UtilConfig
android.util.Xml
android.util.proto.EncodedBuffer
+android.util.proto.ProtoFieldFilter
android.util.proto.ProtoInputStream
android.util.proto.ProtoOutputStream
android.util.proto.ProtoParseException
@@ -146,6 +151,10 @@ android.os.Looper
android.os.Message
android.os.MessageQueue
android.os.MessageQueue_ravenwood
+android.os.PerfettoTrace
+android.os.PerfettoTrace$Category
+android.os.PerfettoTrackEventExtra
+android.os.PerfettoTrackEventExtra$NoOpBuilder
android.os.PackageTagsList
android.os.Parcel
android.os.ParcelFileDescriptor
@@ -250,6 +259,8 @@ android.database.sqlite.SQLiteClosable
android.database.sqlite.SQLiteException
android.text.TextUtils
+android.text.Html
+android.text.HtmlToSpannedConverter
android.accounts.Account
@@ -269,6 +280,10 @@ android.graphics.PointF
android.graphics.Rect
android.graphics.RectF
+android.graphics.fonts.SystemFonts
+
+android.graphics.text.LineBreakConfig
+
android.content.ContentProvider
android.app.ActivityManager
@@ -374,3 +389,228 @@ android.app.compat.*
com.android.server.compat.*
com.android.internal.compat.*
android.app.AppCompatCallbacks
+android.graphics.AvoidXfermode
+android.graphics.BLASTBufferQueue
+android.graphics.BaseCanvas
+android.graphics.BaseRecordingCanvas
+android.graphics.Bitmap
+android.graphics.BitmapFactory
+android.graphics.BitmapRegionDecoder
+android.graphics.BitmapShader
+android.graphics.BlendMode
+android.graphics.BlendModeColorFilter
+android.graphics.BlurMaskFilter
+android.graphics.Camera
+android.graphics.Canvas
+android.graphics.CanvasProperty
+android.graphics.ColorFilter
+android.graphics.ColorMatrix
+android.graphics.ColorMatrixColorFilter
+android.graphics.Compatibility
+android.graphics.ComposePathEffect
+android.graphics.ComposeShader
+android.graphics.CornerPathEffect
+android.graphics.DashPathEffect
+android.graphics.DiscretePathEffect
+android.graphics.DrawFilter
+android.graphics.EmbossMaskFilter
+android.graphics.FontFamily
+android.graphics.FontListParser
+android.graphics.ForceDarkType
+android.graphics.FrameInfo
+android.graphics.Gainmap
+android.graphics.GraphicBuffer
+android.graphics.GraphicsProtos
+android.graphics.GraphicsStatsService
+android.graphics.HardwareBufferRenderer
+android.graphics.HardwareRenderer
+android.graphics.HardwareRendererObserver
+android.graphics.ImageDecoder
+android.graphics.ImageFormat
+android.graphics.LayerRasterizer
+android.graphics.LeakyTypefaceStorage
+android.graphics.LightingColorFilter
+android.graphics.LinearGradient
+android.graphics.MaskFilter
+android.graphics.Mesh
+android.graphics.MeshSpecification
+android.graphics.Movie
+android.graphics.NinePatch
+android.graphics.Paint
+android.graphics.PaintFlagsDrawFilter
+android.graphics.PathDashPathEffect
+android.graphics.PathEffect
+android.graphics.PathIterator
+android.graphics.PathMeasure
+android.graphics.Picture
+android.graphics.PixelXorXfermode
+android.graphics.PorterDuff
+android.graphics.PorterDuffColorFilter
+android.graphics.PorterDuffXfermode
+android.graphics.PostProcessor
+android.graphics.RadialGradient
+android.graphics.Rasterizer
+android.graphics.RecordingCanvas
+android.graphics.Region
+android.graphics.RegionIterator
+android.graphics.RenderEffect
+android.graphics.RenderNode
+android.graphics.RuntimeColorFilter
+android.graphics.RuntimeShader
+android.graphics.RuntimeXfermode
+android.graphics.Shader
+android.graphics.SumPathEffect
+android.graphics.SurfaceTexture
+android.graphics.SweepGradient
+android.graphics.TableMaskFilter
+android.graphics.TemporaryBuffer
+android.graphics.TextureLayer
+android.graphics.Typeface
+android.graphics.Xfermode
+android.graphics.YuvImage
+android.graphics.fonts.Font
+android.graphics.fonts.FontCustomizationParser
+android.graphics.fonts.FontFamily
+android.graphics.fonts.FontFamilyUpdateRequest
+android.graphics.fonts.FontFileUpdateRequest
+android.graphics.fonts.FontFileUtil
+android.graphics.fonts.FontStyle
+android.graphics.fonts.FontVariationAxis
+android.graphics.text.GraphemeBreak
+android.graphics.text.LineBreaker
+android.graphics.text.MeasuredText
+android.graphics.text.PositionedGlyphs
+android.graphics.text.TextRunShaper
+android.text.AlteredCharSequence
+android.text.AndroidBidi
+android.text.AndroidCharacter
+android.text.Annotation
+android.text.AutoGrowArray
+android.text.AutoText
+android.text.BidiFormatter
+android.text.BoringLayout
+android.text.CharSequenceCharacterIterator
+android.text.ClipboardManager
+android.text.DynamicLayout
+android.text.Editable
+android.text.Emoji
+android.text.EmojiConsistency
+android.text.FontConfig
+android.text.GetChars
+android.text.GraphemeClusterSegmentFinder
+android.text.GraphicsOperations
+android.text.Highlights
+android.text.Hyphenator
+android.text.InputFilter
+android.text.InputType
+android.text.Layout
+android.text.LoginFilter
+android.text.MeasuredParagraph
+android.text.NoCopySpan
+android.text.PackedIntVector
+android.text.PackedObjectVector
+android.text.ParcelableSpan
+android.text.PrecomputedText
+android.text.SegmentFinder
+android.text.Selection
+android.text.SpanColors
+android.text.SpanSet
+android.text.SpanWatcher
+android.text.Spannable
+android.text.SpannableString
+android.text.SpannableStringBuilder
+android.text.SpannableStringInternal
+android.text.Spanned
+android.text.SpannedString
+android.text.StaticLayout
+android.text.TextDirectionHeuristic
+android.text.TextDirectionHeuristics
+android.text.TextLine
+android.text.TextPaint
+android.text.TextShaper
+android.text.TextWatcher
+android.text.WordSegmentFinder
+android.text.format.DateFormat
+android.text.format.DateIntervalFormat
+android.text.format.DateTimeFormat
+android.text.format.DateUtils
+android.text.format.DateUtilsBridge
+android.text.format.Formatter
+android.text.format.RelativeDateTimeFormatter
+android.text.format.Time
+android.text.format.TimeFormatter
+android.text.format.TimeMigrationUtils
+android.text.method.AllCapsTransformationMethod
+android.text.method.ArrowKeyMovementMethod
+android.text.method.BaseKeyListener
+android.text.method.BaseMovementMethod
+android.text.method.CharacterPickerDialog
+android.text.method.DateKeyListener
+android.text.method.DateTimeKeyListener
+android.text.method.DialerKeyListener
+android.text.method.DigitsKeyListener
+android.text.method.HideReturnsTransformationMethod
+android.text.method.InsertModeTransformationMethod
+android.text.method.KeyListener
+android.text.method.LinkMovementMethod
+android.text.method.MetaKeyKeyListener
+android.text.method.MovementMethod
+android.text.method.MultiTapKeyListener
+android.text.method.NumberKeyListener
+android.text.method.OffsetMapping
+android.text.method.PasswordTransformationMethod
+android.text.method.QwertyKeyListener
+android.text.method.ReplacementTransformationMethod
+android.text.method.ScrollingMovementMethod
+android.text.method.SingleLineTransformationMethod
+android.text.method.TextKeyListener
+android.text.method.TimeKeyListener
+android.text.method.Touch
+android.text.method.TransformationMethod
+android.text.method.TransformationMethod2
+android.text.method.TranslationTransformationMethod
+android.text.method.WordIterator
+android.text.style.AbsoluteSizeSpan
+android.text.style.AccessibilityClickableSpan
+android.text.style.AccessibilityReplacementSpan
+android.text.style.AccessibilityURLSpan
+android.text.style.AlignmentSpan
+android.text.style.BackgroundColorSpan
+android.text.style.BulletSpan
+android.text.style.CharacterStyle
+android.text.style.ClickableSpan
+android.text.style.ForegroundColorSpan
+android.text.style.IconMarginSpan
+android.text.style.LeadingMarginSpan
+android.text.style.LineBackgroundSpan
+android.text.style.LineBreakConfigSpan
+android.text.style.LineHeightSpan
+android.text.style.LocaleSpan
+android.text.style.MaskFilterSpan
+android.text.style.MetricAffectingSpan
+android.text.style.NoWritingToolsSpan
+android.text.style.ParagraphStyle
+android.text.style.QuoteSpan
+android.text.style.RasterizerSpan
+android.text.style.RelativeSizeSpan
+android.text.style.ReplacementSpan
+android.text.style.ScaleXSpan
+android.text.style.SpanUtils
+android.text.style.SpellCheckSpan
+android.text.style.StrikethroughSpan
+android.text.style.StyleSpan
+android.text.style.SubscriptSpan
+android.text.style.SuggestionRangeSpan
+android.text.style.SuggestionSpan
+android.text.style.SuperscriptSpan
+android.text.style.TabStopSpan
+android.text.style.TextAppearanceSpan
+android.text.style.TtsSpan
+android.text.style.TypefaceSpan
+android.text.style.URLSpan
+android.text.style.UnderlineSpan
+android.text.style.UpdateAppearance
+android.text.style.UpdateLayout
+android.text.style.WrapTogetherSpan
+android.text.util.Rfc822Token
+android.text.util.Rfc822Tokenizer
diff --git a/ravenwood/texts/ravenwood-build.prop b/ravenwood/texts/ravenwood-build.prop
index 93a18cffec50..974ea296f0ed 100644
--- a/ravenwood/texts/ravenwood-build.prop
+++ b/ravenwood/texts/ravenwood-build.prop
@@ -8,7 +8,43 @@ ro.soc.manufacturer=Android
ro.soc.model=Ravenwood
ro.debuggable=1
-# The ones starting with "ro.product" or "ro.bild" will be copied to all "partitions" too.
+persist.sys.locale=en-US
+ro.product.locale=en-US
+
+ro.hwui.max_texture_allocation_size=104857600
+
+# Allowlist control:
+# This set is carefully curated to help identify situations where a test may
+# accidentally depend on a default value of an obscure property whose owner hasn't
+# decided how Ravenwood should behave.
+
+boot.=$$$r
+build.=$$$r
+product.=$$$r
+soc.=$$$r
+system.=$$$r
+wm.debug.=$$$r
+wm.extensions.=$$$r
+
+gsm.version.baseband=$$$r
+no.such.thing=$$$r
+qemu.sf.lcd_density=$$$r
+ro.bootloader=$$$r
+ro.hardware=$$$r
+ro.hw_timeout_multiplier=$$$r
+ro.odm.build.media_performance_class=$$$r
+ro.sf.lcd_density=$$$r
+ro.treble.enabled=$$$r
+ro.vndk.version=$$$r
+ro.icu.data.path=$$$r
+
+# Writable keys
+debug.=$$$w
+
+# For PropertyInvalidatedCache
+cache_key.=$$$w
+
+# The ones starting with "ro.product" or "ro.build" will be copied to all "partitions" too.
# See RavenwoodSystemProperties.
ro.product.brand=Android
ro.product.device=Ravenwood
diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt
index 83c31512eb70..f0f4b8580f7d 100644
--- a/ravenwood/texts/ravenwood-common-policies.txt
+++ b/ravenwood/texts/ravenwood-common-policies.txt
@@ -1,5 +1,8 @@
# Ravenwood "policy" that should apply to all code.
+# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
+# which tries to convert policies to annotations.
+
# Keep all AIDL interfaces
class :aidl keepclass
@@ -13,8 +16,12 @@ class :sysprops keepclass
class :r keepclass
# Support APIs not available in standard JRE
-class java.io.FileDescriptor keep
+class java.io.FileDescriptor # no-pta
method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$
method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$
-class java.util.LinkedHashMap keep
+class java.util.LinkedHashMap # no-pta
method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest
+
+# Always set flag UNICODE_CHARACTER_CLASS when compiling regex
+class java.util.regex.Pattern keep
+ method compile @com.android.ravenwood.RavenwoodJdkPatch.compilePattern
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index 80126df1b8df..5c1766241698 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -1,62 +1,86 @@
# Ravenwood "policy" file for framework-minus-apex.
+# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
+# which tries to convert policies to annotations.
+
# To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes.
# Note: The "rename" directive must use slashes (/) as a package name separator.
rename com/.*/nano/ devicenano/
rename android/.*/nano/ devicenano/
# StatsD auto-generated
-class com.android.internal.util.FrameworkStatsLog keepclass
+class com.android.internal.util.FrameworkStatsLog keepclass # no-pta
# Exported to Mainline modules; cannot use annotations
-class com.android.internal.util.FastXmlSerializer keepclass
-class com.android.internal.util.FileRotator keepclass
-class com.android.internal.util.HexDump keepclass
-class com.android.internal.util.IndentingPrintWriter keepclass
-class com.android.internal.util.LocalLog keepclass
-class com.android.internal.util.MessageUtils keepclass
-class com.android.internal.util.TokenBucket keepclass
-class android.os.HandlerExecutor keepclass
-class android.util.BackupUtils keepclass
-class android.util.IndentingPrintWriter keepclass
-class android.util.LocalLog keepclass
-class android.util.Pair keepclass
-class android.util.Rational keepclass
+class com.android.internal.util.FastXmlSerializer keepclass # no-pta
+class com.android.internal.util.FileRotator keepclass # no-pta
+class com.android.internal.util.HexDump keepclass # no-pta
+class com.android.internal.util.IndentingPrintWriter keepclass # no-pta
+class com.android.internal.util.LocalLog keepclass # no-pta
+class com.android.internal.util.MessageUtils keepclass # no-pta
+class com.android.internal.util.TokenBucket keepclass # no-pta
+class android.os.HandlerExecutor keepclass # no-pta
+class android.util.BackupUtils keepclass # no-pta
+class android.util.IndentingPrintWriter keepclass # no-pta
+class android.util.LocalLog keepclass # no-pta
+class android.util.Pair keepclass # no-pta
+class android.util.Rational keepclass # no-pta
# From modules-utils; cannot use annotations
-class com.android.internal.util.Preconditions keepclass
-class com.android.internal.logging.InstanceId keepclass
-class com.android.internal.logging.InstanceIdSequence keepclass
-class com.android.internal.logging.UiEvent keepclass
-class com.android.internal.logging.UiEventLogger keepclass
+class com.android.internal.util.Preconditions keepclass # no-pta
+class com.android.internal.logging.InstanceId keepclass # no-pta
+class com.android.internal.logging.InstanceIdSequence keepclass # no-pta
+class com.android.internal.logging.UiEvent keepclass # no-pta
+class com.android.internal.logging.UiEventLogger keepclass # no-pta
# From modules-utils; cannot use annotations
-class com.android.modules.utils.BinaryXmlPullParser keepclass
-class com.android.modules.utils.BinaryXmlSerializer keepclass
-class com.android.modules.utils.FastDataInput keepclass
-class com.android.modules.utils.FastDataOutput keepclass
-class com.android.modules.utils.ModifiedUtf8 keepclass
-class com.android.modules.utils.TypedXmlPullParser keepclass
-class com.android.modules.utils.TypedXmlSerializer keepclass
+class com.android.modules.utils.BinaryXmlPullParser keepclass # no-pta
+class com.android.modules.utils.BinaryXmlSerializer keepclass # no-pta
+class com.android.modules.utils.FastDataInput keepclass # no-pta
+class com.android.modules.utils.FastDataOutput keepclass # no-pta
+class com.android.modules.utils.ModifiedUtf8 keepclass # no-pta
+class com.android.modules.utils.TypedXmlPullParser keepclass # no-pta
+class com.android.modules.utils.TypedXmlSerializer keepclass # no-pta
# Uri
-class android.net.Uri keepclass
-class android.net.UriCodec keepclass
+class android.net.Uri keepclass # no-pta
+class android.net.UriCodec keepclass # no-pta
# Telephony
-class android.telephony.PinResult keepclass
+class android.telephony.PinResult keepclass # no-pta
# Just enough to support mocking, no further functionality
-class android.content.BroadcastReceiver keep
- method <init> ()V keep
-class android.content.Context keep
+class android.content.BroadcastReceiver allow-annotation
+ method <init> ()V allow-annotation
+
+# TODO: Convert the following policies to "allow-annotation".
+class android.content.Context keep # no-pta
method <init> ()V keep
- method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep
-class android.content.pm.PackageManager keep
+ method getSystemService (Ljava/lang/Class;)Ljava/lang/Object; keep # no-pta
+class android.content.pm.PackageManager # no-pta
method <init> ()V keep
-class android.text.ClipboardManager keep
+class android.text.ClipboardManager keep # no-pta
method <init> ()V keep
# Just enough to allow ResourcesManager to run
-class android.hardware.display.DisplayManagerGlobal keep
- method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
+class android.hardware.display.DisplayManagerGlobal keep # no-pta
+ method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore # no-pta
+
+# Bare minimum to support running ImageDecoderTest
+class android.graphics.drawable.Drawable$ConstantState keepclass # no-pta
+class android.graphics.drawable.BitmapDrawable$BitmapState keepclass # no-pta
+class android.graphics.drawable.BitmapDrawable keep # no-pta
+ method <init> (Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V keep
+ method init * keep
+ method updateLocalState * keep
+ method computeBitmapSize * keep
+ method getIntrinsicWidth * keep
+ method getIntrinsicHeight * keep
+ method getBitmap * keep
+class android.graphics.drawable.Drawable keep # no-pta
+ method <init> ()V keep
+ method resolveDensity * keep
+ method updateBlendModeFilter * ignore
+
+class android.os.StrictMode keep # no-pta
+ method noteSlowCall (Ljava/lang/String;)V ignore
diff --git a/ravenwood/texts/ravenwood-services-jarjar-rules.txt b/ravenwood/texts/ravenwood-services-jarjar-rules.txt
index 8fdd3408f74d..64a0e2548e2e 100644
--- a/ravenwood/texts/ravenwood-services-jarjar-rules.txt
+++ b/ravenwood/texts/ravenwood-services-jarjar-rules.txt
@@ -5,7 +5,7 @@ rule com.android.server.pm.pkg.AndroidPackageSplit @0
# Rename all other service internals so that tests can continue to statically
# link services code when owners aren't ready to support on Ravenwood
-rule com.android.server.** repackaged.@0
+rule com.android.server.** repackaged.services.@0
# TODO: support AIDL generated Parcelables via hoststubgen
-rule android.hardware.power.stats.** repackaged.@0
+rule android.hardware.power.stats.** repackaged.services.@0
diff --git a/ravenwood/texts/ravenwood-services-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt
index 530e5c8f5986..e3be9afdba5c 100644
--- a/ravenwood/texts/ravenwood-services-policies.txt
+++ b/ravenwood/texts/ravenwood-services-policies.txt
@@ -1,12 +1,15 @@
# Ravenwood "policy" file for services.core.
+# The "no-pta" marker is used to exclude the lines from "ravenhelper pta",
+# which tries to convert policies to annotations.
+
# Auto-generated from XSD
-class com.android.server.compat.config.Change keepclass
-class com.android.server.compat.config.Config keepclass
-class com.android.server.compat.config.XmlParser keepclass
-class com.android.server.compat.overrides.ChangeOverrides keepclass
-class com.android.server.compat.overrides.OverrideValue keepclass
-class com.android.server.compat.overrides.Overrides keepclass
-class com.android.server.compat.overrides.RawOverrideValue keepclass
-class com.android.server.compat.overrides.XmlParser keepclass
-class com.android.server.compat.overrides.XmlWriter keepclass \ No newline at end of file
+class com.android.server.compat.config.Change keepclass # no-pta
+class com.android.server.compat.config.Config keepclass # no-pta
+class com.android.server.compat.config.XmlParser keepclass # no-pta
+class com.android.server.compat.overrides.ChangeOverrides keepclass # no-pta
+class com.android.server.compat.overrides.OverrideValue keepclass # no-pta
+class com.android.server.compat.overrides.Overrides keepclass # no-pta
+class com.android.server.compat.overrides.RawOverrideValue keepclass # no-pta
+class com.android.server.compat.overrides.XmlParser keepclass # no-pta
+class com.android.server.compat.overrides.XmlWriter keepclass # no-pta \ No newline at end of file
diff --git a/ravenwood/texts/ravenwood-standard-options.txt b/ravenwood/texts/ravenwood-standard-options.txt
index 3ec3e3ce2946..233657557747 100644
--- a/ravenwood/texts/ravenwood-standard-options.txt
+++ b/ravenwood/texts/ravenwood-standard-options.txt
@@ -5,10 +5,14 @@
# Keep all classes / methods / fields, but make the methods throw.
--default-throw
+--delete-finals
+
# Uncomment below lines to enable each feature.
+# Enable method call hook.
#--default-method-call-hook
-# com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+# android.platform.test.ravenwood.RavenwoodMethodCallLogger.logMethodCall
+
#--default-class-load-hook
# com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
@@ -29,6 +33,12 @@
--remove-annotation
android.ravenwood.annotation.RavenwoodRemove
+--ignore-annotation
+ android.ravenwood.annotation.RavenwoodIgnore
+
+--partially-allowed-annotation
+ android.ravenwood.annotation.RavenwoodPartiallyAllowlisted
+
--substitute-annotation
android.ravenwood.annotation.RavenwoodReplace
diff --git a/nfc/java/android/nfc/Placeholder.java b/ravenwood/tools/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestPartiallyAllowlisted.java
index 3509644ac106..49b5938941fb 100644
--- a/nfc/java/android/nfc/Placeholder.java
+++ b/ravenwood/tools/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestPartiallyAllowlisted.java
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package android.hosttest.annotation;
-package android.nfc;
+import static java.lang.annotation.ElementType.TYPE;
-/**
- * Placeholder class so new framework-nfc module isn't empty, will be removed once module is
- * populated.
- *
- * @hide
- *
- */
-public class Placeholder {
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestPartiallyAllowlisted {
}
diff --git a/ravenwood/tools/hoststubgen/framework-policy-override.txt b/ravenwood/tools/hoststubgen/framework-policy-override.txt
deleted file mode 100644
index af3789e270a4..000000000000
--- a/ravenwood/tools/hoststubgen/framework-policy-override.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-# --------------------------------------------------------------------------------------------------
-# This file contains rules to process `framework-all.jar` to generate the host side test "stub" and
-# "impl" jars, without using Java annotations.
-#
-# Useful when:
-# - The class is auto-generated and annotations can't be added.
-# (We need to figure out what to do on auto-generated classes.)
-# - Want to quickly change filter rules without having to rebuild framework.jar.
-#
-# Using this file, one can control the visibility of APIs on a per-class, per-field and per-method
-# basis, but in most cases, per-class directives would be sufficient. That is:
-#
-# - To put the entire class, including its members and nested classes, in the "stub" jar,
-# so that the test / target code can use the API, use `stubclass`.
-#
-# class package.class stubclass
-#
-# - To put the entire class, including its members and nested classes, in the "impl" jar,
-# but not in the "stub" jar, use `keepclass`. Use this when you don't want to expose an API to
-# tests/target directly, but it's still needed at runtime, because it's used by other "stub" APIs
-# directly or indirectly.
-#
-# class package.class keepclass
-#
-# All other classes will be removed from both the stub jar and impl jar.
-#
-# --------------------------------------------------------------------------------------------------
-
-# --------------------------------------------------------------------------------------------------
-# Directions on auto-generated classes, where we can't use Java annotations (yet).
-# --------------------------------------------------------------------------------------------------
-class android.Manifest stubclass
-class android.R stubclass
-class android.os.PersistableBundleProto keepclass
-
-# This is in module-utils, where using a HostStubGen annotation would be complicated, so we
-# add a direction here rather than using a java annotation.
-# The build file says it's deprecated, anyway...? Figure out what to do with it.
-class com.android.internal.util.Preconditions keepclass
-
-# --------------------------------------------------------------------------------------------------
-# Actual framework classes
-# --------------------------------------------------------------------------------------------------
-
-# Put basic exception classes in the "impl" jar.
-# We don't put them in stub yet (until something actually needs them).
-class android.os.DeadObjectException keepclass
-class android.os.DeadSystemRuntimeException keepclass
-class android.os.NetworkOnMainThreadException keepclass
-class android.os.RemoteException keepclass
-class android.os.ServiceSpecificException keepclass
-class android.util.AndroidException keepclass
-class android.util.AndroidRuntimeException keepclass
-class android.os.DeadSystemException keepclass
-
-
-# For now, we only want to expose ArrayMap and Log, but they and their tests depend on
-# more classes.
-
-class android.util.ArrayMap stubclass
-
-# Used by ArrayMap. No need to put them in the stub, but we need them in impl.
-class android.util.MapCollections keepclass
-class android.util.ContainerHelpers keepclass
-class android.util.EmptyArray stubclass
-class com.android.internal.util.XmlUtils keepclass
-class com.android.internal.util.FastMath keepclass
-class android.util.MathUtils keepclass
-
-
-class android.util.Log stubclass
-class android.util.Slog stubclass
-# We don't use Log's native code, yet. Instead, the following line enables the Java substitution.
-# Comment it out to disable Java substitution of Log's native methods.
-class android.util.Log !com.android.hoststubgen.nativesubstitution.Log_host
-
-# Used by log
-class com.android.internal.util.FastPrintWriter keepclass
-class com.android.internal.util.LineBreakBufferedWriter keepclass
-
-class android.util.EventLog stubclass
-class android.util.EventLog !com.android.hoststubgen.nativesubstitution.EventLog_host
-class android.util.EventLog$Event stubclass
-
-# Expose Context because it's referred to by AndroidTestCase, but don't need to expose any of
-# its members.
-class android.content.Context keep
-
-# Expose Parcel, Parcel and there relevant classes, which are used by ArrayMapTets.
-class android.os.Parcelable StubClass
-class android.os.Parcel StubClass
-class android.os.Parcel !com.android.hoststubgen.nativesubstitution.Parcel_host
-
-class android.os.IBinder stubClass
-class android.os.IInterface stubclass
-
-class android.os.BadParcelableException stubclass
-class android.os.BadTypeParcelableException stubclass
-
-class android.os.BaseBundle stubclass
-class android.os.Bundle stubclass
-class android.os.PersistableBundle stubclass
-
-class android.os.MessageQueue stubclass
-class android.os.MessageQueue !com.android.hoststubgen.nativesubstitution.MessageQueue_host
diff --git a/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java b/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
index 78fd8f7f960a..145325ccc809 100644
--- a/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
+++ b/ravenwood/tools/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
@@ -18,6 +18,7 @@ package com.android.hoststubgen.hosthelper;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
/**
* Utilities used in the host side test environment.
@@ -36,9 +37,14 @@ public class HostTestUtils {
public static final String CLASS_INTERNAL_NAME = getInternalName(HostTestUtils.class);
+ /** If true, we skip all method call hooks */
+ private static final boolean SKIP_METHOD_CALL_HOOK = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_METHOD_CALL_HOOK"));
+
/** If true, we won't print method call log. */
- private static final boolean SKIP_METHOD_LOG = "1".equals(System.getenv(
- "HOSTTEST_SKIP_METHOD_LOG"));
+ private static final boolean SKIP_METHOD_LOG =
+ "1".equals(System.getenv("HOSTTEST_SKIP_METHOD_LOG"))
+ || "1".equals(System.getenv("RAVENWOOD_NO_METHOD_LOG"));
/** If true, we won't print class load log. */
private static final boolean SKIP_CLASS_LOG = "1".equals(System.getenv(
@@ -65,6 +71,9 @@ public class HostTestUtils {
+ "consider using Mockito; more details at go/ravenwood-docs");
}
+ private static final Class<?>[] sMethodHookArgTypes =
+ { Class.class, String.class, String.class};
+
/**
* Trampoline method for method-call-hook.
*/
@@ -74,16 +83,22 @@ public class HostTestUtils {
String methodDescriptor,
String callbackMethod
) {
- callStaticMethodByName(callbackMethod, "method call hook", methodClass,
- methodName, methodDescriptor);
+ if (SKIP_METHOD_CALL_HOOK) {
+ return;
+ }
+ callStaticMethodByName(callbackMethod, "method call hook", sMethodHookArgTypes,
+ methodClass, methodName, methodDescriptor);
}
/**
+ * Simple implementation of method call hook, which just prints the information of the
+ * method. This is just for basic testing. We don't use it in Ravenwood, because this would
+ * be way too noisy as it prints every single method, even trivial ones. (iterator methods,
+ * etc..)
+ *
* I can be used as
* {@code --default-method-call-hook
* com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall}.
- *
- * It logs every single methods called.
*/
public static void logMethodCall(
Class<?> methodClass,
@@ -97,6 +112,8 @@ public class HostTestUtils {
+ methodName + methodDescriptor);
}
+ private static final Class<?>[] sClassLoadHookArgTypes = { Class.class };
+
/**
* Called when any top level class (not nested classes) in the impl jar is loaded.
*
@@ -111,11 +128,12 @@ public class HostTestUtils {
logPrintStream.println("! Class loaded: " + loadedClass.getCanonicalName()
+ " calling hook " + callbackMethod);
- callStaticMethodByName(callbackMethod, "class load hook", loadedClass);
+ callStaticMethodByName(
+ callbackMethod, "class load hook", sClassLoadHookArgTypes, loadedClass);
}
private static void callStaticMethodByName(String classAndMethodName,
- String description, Object... args) {
+ String description, Class<?>[] argTypes, Object... args) {
// Forward the call to callbackMethod.
final int lastPeriod = classAndMethodName.lastIndexOf(".");
@@ -145,19 +163,14 @@ public class HostTestUtils {
className));
}
- Class<?>[] argTypes = new Class[args.length];
- for (int i = 0; i < args.length; i++) {
- argTypes[i] = args[i].getClass();
- }
-
Method method = null;
try {
method = clazz.getMethod(methodName, argTypes);
} catch (Exception e) {
throw new HostTestException(String.format(
"Unable to find %s: class %s doesn't have method %s"
- + " (method must take exactly one parameter of type Class,"
- + " and public static)",
+ + " Method must be public static, and arg types must be: "
+ + Arrays.toString(argTypes),
description, className, methodName), e);
}
if (!(Modifier.isPublic(method.getModifiers())
diff --git a/ravenwood/tools/hoststubgen/hoststubgen-standard-options.txt b/ravenwood/tools/hoststubgen/hoststubgen-standard-options.txt
index 001943c18d6b..062541241d2c 100644
--- a/ravenwood/tools/hoststubgen/hoststubgen-standard-options.txt
+++ b/ravenwood/tools/hoststubgen/hoststubgen-standard-options.txt
@@ -2,6 +2,8 @@
--debug
+--delete-finals
+
# Uncomment below lines to enable each feature.
#--default-method-call-hook
@@ -18,6 +20,9 @@
--keep-class-annotation
android.hosttest.annotation.HostSideTestWholeClassKeep
+--partially-allowed-annotation
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+
--throw-annotation
android.hosttest.annotation.HostSideTestThrow
diff --git a/ravenwood/tools/hoststubgen/invoketest/hoststubgen-invoke-test.sh b/ravenwood/tools/hoststubgen/invoketest/hoststubgen-invoke-test.sh
index 084448d0a797..da1e40a27944 100755
--- a/ravenwood/tools/hoststubgen/invoketest/hoststubgen-invoke-test.sh
+++ b/ravenwood/tools/hoststubgen/invoketest/hoststubgen-invoke-test.sh
@@ -47,6 +47,7 @@ INJAR=hoststubgen-test-tiny-framework.jar
OUTJAR=$TEMP/host.jar
ANNOTATION_FILTER=$TEMP/annotation-filter.txt
+POLICY_FILE=$TEMP/policy-file.txt
HOSTSTUBGEN_OUT=$TEMP/output.txt
@@ -66,12 +67,14 @@ hoststubgen() {
run_hoststubgen() {
local test_name="$1"
local annotation_filter="$2"
+ local policy="$3"
echo "# Test: $test_name"
cleanup_temp
local filter_arg=""
+ local policy_arg=""
if [[ "$annotation_filter" != "" ]] ; then
echo "$annotation_filter" > $ANNOTATION_FILTER
@@ -80,6 +83,13 @@ run_hoststubgen() {
cat $ANNOTATION_FILTER
fi
+ if [[ "$policy" != "" ]] ; then
+ echo "$policy" > $POLICY_FILE
+ policy_arg="--policy-override-file $POLICY_FILE"
+ echo "=== policy ==="
+ cat $POLICY_FILE
+ fi
+
local out_arg=""
if [[ "$OUTJAR" != "" ]] ; then
@@ -108,7 +118,10 @@ run_hoststubgen() {
android.hosttest.annotation.HostSideTestClassLoadHook \
--keep-static-initializer-annotation \
android.hosttest.annotation.HostSideTestStaticInitializerKeep \
+ --partially-allowed-annotation \
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted \
$filter_arg \
+ $policy_arg \
$EXTRA_ARGS \
|& tee $HOSTSTUBGEN_OUT
HOSTSTUBGEN_RC=${PIPESTATUS[0]}
@@ -132,10 +145,11 @@ assert_file_generated() {
}
run_hoststubgen_for_success() {
+ local test_name="$1"
run_hoststubgen "$@"
if (( $HOSTSTUBGEN_RC != 0 )) ; then
- echo "HostStubGen expected to finish successfully, but failed with $rc"
+ echo "HostStubGen expected to finish successfully, but failed with $HOSTSTUBGEN_RC: Test=$test_name"
return 1
fi
@@ -151,7 +165,7 @@ run_hoststubgen_for_failure() {
run_hoststubgen "$test_name" "$@"
if (( $HOSTSTUBGEN_RC == 0 )) ; then
- echo "HostStubGen expected to fail, but it didn't fail"
+ echo "HostStubGen expected to fail, but it didn't fail. Test=$test_name"
return 1
fi
@@ -161,24 +175,31 @@ run_hoststubgen_for_failure() {
# Start the tests...
+# These classes require special care, so let's delete them in most tests...
+DELETE_PARTIAL_ANNOTATION_CLASSESS='
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+'
+
# Pass "" as a filter to _not_ add `--annotation-allowed-classes-file`.
-run_hoststubgen_for_success "No annotation filter" ""
+run_hoststubgen_for_success "No annotation filter" "" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
# Now, we use " ", so we do add `--annotation-allowed-classes-file`.
run_hoststubgen_for_failure "No classes are allowed to have annotations" \
"not allowed to have Ravenwood annotations" \
- " "
+ " " "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_success "All classes allowed (wildcard)" \
"
* # Allow all classes
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_failure "All classes disallowed (wildcard)" \
"not allowed to have Ravenwood annotations" \
"
!* # Disallow all classes
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_failure "Some classes not allowed (1)" \
"not allowed to have Ravenwood annotations" \
@@ -186,7 +207,7 @@ run_hoststubgen_for_failure "Some classes not allowed (1)" \
android.hosttest.*
com.android.hoststubgen.*
com.supported.*
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_failure "Some classes not allowed (2)" \
"not allowed to have Ravenwood annotations" \
@@ -194,7 +215,7 @@ run_hoststubgen_for_failure "Some classes not allowed (2)" \
android.hosttest.*
com.android.hoststubgen.*
com.unsupported.*
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_success "All classes allowed (package wildcard)" \
"
@@ -202,27 +223,109 @@ android.hosttest.*
com.android.hoststubgen.*
com.supported.*
com.unsupported.*
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_failure "One specific class disallowed" \
"TinyFrameworkAnnotations is not allowed to have Ravenwood annotations" \
"
!com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
* # All other classes allowed
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
run_hoststubgen_for_success "One specific class disallowed, but it doesn't use annotations" \
"
!com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
* # All other classes allowed
-"
+" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
-OUTJAR="" run_hoststubgen_for_success "No output generation" ""
+OUTJAR="" run_hoststubgen_for_success "No output generation" "" "$DELETE_PARTIAL_ANNOTATION_CLASSESS"
EXTRA_ARGS="--in-jar abc" run_hoststubgen_for_failure "Duplicate arg" \
"Duplicate or conflicting argument found: --in-jar" \
""
+# ---------------------------------------------------------------------------------------------
+# Tests for "partially-allowlisted".
+# ---------------------------------------------------------------------------------------------
+
+# Allowlist used by hoststubgen-test-tiny-test.
+ALLOWLIST='
+com.android.hoststubgen.test.tinyframework.*
+com.supported.*
+com.unsupported.*
+!*
+'
+
+run_hoststubgen_for_success 'The settings used by hoststubgen-test-tiny-test' \
+ "$ALLOWLIST" \
+ '
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+ method foo2 allow-annotation
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+'
+
+run_hoststubgen_for_failure 'PartiallyAllowlisted does not have allow-annotation' \
+ "PartiallyAllowlisted has annotation android.hosttest.annotation.HostSideTestPartiallyAllowlisted, but" \
+ "$ALLOWLIST" \
+ '
+#class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+# method foo2 allow-annotation
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+'
+
+
+run_hoststubgen_for_failure 'PartiallyAllowlisted.foo2 does not have allow-annotation' \
+ "foo2(I)I is not allowed to have Ravenwood annotations. (Class is partially allowlisted.)" \
+ "$ALLOWLIST" \
+ '
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+# method foo2 allow-annotation
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+'
+
+run_hoststubgen_for_failure 'Partially-allowlisted classes cannot have class-wide policies' \
+ "PartialWithWholeClass_bad has class wide annotation android.hosttest.annotation.HostSideTestWholeClassKeep" \
+ "$ALLOWLIST" \
+ '
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+ method foo2 allow-annotation
+
+# Now with allow-annotation
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad allow-annotation
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+'
+
+run_hoststubgen_for_failure 'Partially-allowlisted classes cannot have class-wide policies' \
+ "PartiallyAllowlistedWithoutAnnot_bad must have android.hosttest.annotation.HostSideTestPartiallyAllowlisted" \
+ "$ALLOWLIST" \
+ '
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+ method foo2 allow-annotation
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+
+# Now with allow-annotation
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad allow-annotation
+'
+
+run_hoststubgen_for_success 'The settings used by hoststubgen-test-tiny-test' \
+ "$ALLOWLIST" \
+ '
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+ method foo2 allow-annotation
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove
+
+# NoAnnotations has no annotations at all. Setting "allow-annotation" to it is okay even though
+# it does not have an @HostSideTestPartiallyAllowlisted, because it does nott have any other annotations anyway.
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations allow-annotation
+'
echo "All tests passed"
exit 0
diff --git a/ravenwood/tools/hoststubgen/scripts/dump-jar b/ravenwood/tools/hoststubgen/scripts/dump-jar
index 87652451359d..02a6d25378bd 100755
--- a/ravenwood/tools/hoststubgen/scripts/dump-jar
+++ b/ravenwood/tools/hoststubgen/scripts/dump-jar
@@ -89,14 +89,33 @@ filter_output() {
# - Some other transient lines
# - Sometimes the javap shows mysterious warnings, so remove them too.
#
- # `/PATTERN-1/,/PATTERN-1/{//!d}` is a trick to delete lines between two patterns, without
- # the start and the end lines.
+ # Most conversion are simple per-line deletion or simple inline replacement with a regex.
+ #
+ # But removing the constant pool is a bit tricky. It looks like this in the output:
+ #---------------------------
+ #Constant pool:
+ # #1 = Methodref #31.#88 // java/lang/Object."<init>":()V
+ # #2 = Class #89 // java/lang/UnsupportedOperationException
+ # :
+ #{ // Or something, I'm not sure if it always ends with a "{".
+ #---------------------------
+ # i.e. we want to delete all lines from "Constant pool:" as long as the first character
+ # is a space.
+ #
+ # If we simply use '/^Constant pool:/,/^[^ ]/d', then it'll delete the "Constant pool:"
+ # line and "{" line too, but again the last line might be important, so we don't want to
+ # delete it.
+ #
+ # So we instead, use '/^Constant pool:/,/^[^ ]/{/^ /d}', which mean:
+ # between lines matching '/^Constant pool:/' and '/^[^ ]/', delete lines that start with
+ # a space. (=='/^ /d').
+ #
sed -e 's/#[0-9][0-9]*/#x/g' \
-e 's/^\( *\)[0-9][0-9]*:/\1x:/' \
- -e '/^Constant pool:/,/^[^ ]/{//!d}' \
+ -e '/^Constant pool:/,/^[^ ]/{/^ /d}' \
-e '/^ *line *[0-9][0-9]*: *[0-9][0-9]*$/d' \
- -e '/SHA-256 checksum/d' \
- -e '/Last modified/d' \
+ -e '/^ *SHA-256 checksum/d' \
+ -e '/^ *Last modified/d' \
-e '/^Classfile jar/d' \
-e '/\[warning\]/d'
else
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 6d8d7b768b91..7e294ed652d3 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -27,9 +27,9 @@ import com.android.hoststubgen.filters.ImplicitOutputFilter
import com.android.hoststubgen.filters.KeepNativeFilter
import com.android.hoststubgen.filters.OutputFilter
import com.android.hoststubgen.filters.SanitizationFilter
-import com.android.hoststubgen.filters.TextFileFilterPolicyParser
+import com.android.hoststubgen.filters.TextFileFilterPolicyBuilder
import com.android.hoststubgen.filters.printAsTextPolicy
-import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.utils.ClassPredicate
import com.android.hoststubgen.visitors.BaseAdapter
import com.android.hoststubgen.visitors.PackageRedirectRemapper
import java.io.BufferedInputStream
@@ -145,21 +145,22 @@ class HostStubGen(val options: HostStubGenOptions) {
// Inject default hooks from options.
filter = DefaultHookInjectingFilter(
+ allClasses,
options.defaultClassLoadHook.get,
options.defaultMethodCallHook.get,
filter
)
- val annotationAllowedClassesFilter = options.annotationAllowedClassesFile.get.let { file ->
+ val annotationAllowedPredicate = options.annotationAllowedClassesFile.get.let { file ->
if (file == null) {
- ClassFilter.newNullFilter(true) // Allow all classes
+ ClassPredicate.newConstantPredicate(true) // Allow all classes
} else {
- ClassFilter.loadFromFile(file, false)
+ ClassPredicate.loadFromFile(file, false)
}
}
// Next, Java annotation based filter.
- filter = AnnotationBasedFilter(
+ val annotFilter = AnnotationBasedFilter(
errors,
allClasses,
options.keepAnnotations,
@@ -171,17 +172,20 @@ class HostStubGen(val options: HostStubGenOptions) {
options.redirectAnnotations,
options.redirectionClassAnnotations,
options.classLoadHookAnnotations,
+ options.partiallyAllowedAnnotations,
options.keepStaticInitializerAnnotations,
- annotationAllowedClassesFilter,
+ annotationAllowedPredicate,
filter
)
+ filter = annotFilter
// Next, "text based" filter, which allows to override polices without touching
// the target code.
if (options.policyOverrideFiles.isNotEmpty()) {
- val parser = TextFileFilterPolicyParser(allClasses, filter)
- options.policyOverrideFiles.forEach(parser::parse)
- filter = parser.createOutputFilter()
+ val builder = TextFileFilterPolicyBuilder(allClasses, filter)
+ options.policyOverrideFiles.forEach(builder::parse)
+ filter = builder.createOutputFilter()
+ annotFilter.annotationAllowedMembers = builder.annotationAllowedMembersFilter
}
// Apply the implicit filter.
@@ -411,6 +415,8 @@ class HostStubGen(val options: HostStubGenOptions) {
stats = stats,
enablePreTrace = options.enablePreTrace.get,
enablePostTrace = options.enablePostTrace.get,
+ deleteClassFinals = options.deleteFinals.get,
+ deleteMethodFinals = options.deleteFinals.get,
)
outVisitor = BaseAdapter.getVisitor(
classInternalName, classes, outVisitor, filter,
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
index 55e853e3e2fb..1ab88d24ab28 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -86,6 +86,7 @@ class HostStubGenOptions(
var removeAnnotations: MutableSet<String> = mutableSetOf(),
var ignoreAnnotations: MutableSet<String> = mutableSetOf(),
var keepClassAnnotations: MutableSet<String> = mutableSetOf(),
+ var partiallyAllowedAnnotations: MutableSet<String> = mutableSetOf(),
var redirectAnnotations: MutableSet<String> = mutableSetOf(),
var substituteAnnotations: MutableSet<String> = mutableSetOf(),
@@ -106,6 +107,8 @@ class HostStubGenOptions(
var cleanUpOnError: SetOnce<Boolean> = SetOnce(false),
+ var deleteFinals: SetOnce<Boolean> = SetOnce(false),
+
var enableClassChecker: SetOnce<Boolean> = SetOnce(false),
var enablePreTrace: SetOnce<Boolean> = SetOnce(false),
var enablePostTrace: SetOnce<Boolean> = SetOnce(false),
@@ -179,6 +182,9 @@ class HostStubGenOptions(
"--keep-class-annotation" ->
ret.keepClassAnnotations.addUniqueAnnotationArg()
+ "--partially-allowed-annotation" ->
+ ret.partiallyAllowedAnnotations.addUniqueAnnotationArg()
+
"--throw-annotation" ->
ret.throwAnnotations.addUniqueAnnotationArg()
@@ -218,6 +224,8 @@ class HostStubGenOptions(
"--gen-keep-all-file" ->
ret.inputJarAsKeepAllFile.set(nextArg())
+ "--delete-finals" -> ret.deleteFinals.set(true)
+
// Following options are for debugging.
"--enable-class-checker" -> ret.enableClassChecker.set(true)
"--no-class-checker" -> ret.enableClassChecker.set(false)
@@ -283,6 +291,7 @@ class HostStubGenOptions(
removeAnnotations=$removeAnnotations,
ignoreAnnotations=$ignoreAnnotations,
keepClassAnnotations=$keepClassAnnotations,
+ partiallyAllowedAnnotations=$partiallyAllowedAnnotations,
substituteAnnotations=$substituteAnnotations,
nativeSubstituteAnnotations=$redirectionClassAnnotations,
classLoadHookAnnotations=$classLoadHookAnnotations,
@@ -293,6 +302,7 @@ class HostStubGenOptions(
defaultMethodCallHook=$defaultMethodCallHook,
policyOverrideFiles=${policyOverrideFiles.toTypedArray().contentToString()},
defaultPolicy=$defaultPolicy,
+ deleteFinals=$deleteFinals,
cleanUpOnError=$cleanUpOnError,
enableClassChecker=$enableClassChecker,
enablePreTrace=$enablePreTrace,
@@ -349,6 +359,8 @@ class ArgIterator(
* Scan the arguments, and if any of them starts with an `@`, then load from the file
* and use its content as arguments.
*
+ * In order to pass an argument that starts with an '@', use '@@' instead.
+ *
* In this file, each line is treated as a single argument.
*
* The file can contain '#' as comments.
@@ -357,7 +369,10 @@ private fun expandAtFiles(args: Array<String>): List<String> {
val ret = mutableListOf<String>()
args.forEach { arg ->
- if (!arg.startsWith('@')) {
+ if (arg.startsWith("@@")) {
+ ret += arg.substring(1)
+ return@forEach
+ } else if (!arg.startsWith('@')) {
ret += arg
return@forEach
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
index f47aaba8ef22..b41ce0f65017 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
@@ -191,7 +191,14 @@ fun String.toJvmClassName(): String {
}
fun String.toHumanReadableClassName(): String {
- return this.replace('/', '.')
+ var ret = this
+ if (ret.startsWith("L")) {
+ ret = ret.substring(1)
+ }
+ if (ret.endsWith(";")) {
+ ret = ret.substring(0, ret.length - 1)
+ }
+ return ret.replace('/', '.')
}
fun String.toHumanReadableMethodName(): String {
@@ -261,18 +268,45 @@ fun writeByteCodeToReturn(methodDescriptor: String, writer: MethodVisitor) {
}
/**
+ * Write bytecode to pop the 2 uninitialized instances out of the stack
+ * after performing constructor redirection.
+ */
+fun adjustStackForConstructorRedirection(writer: MethodVisitor) {
+ // Stack: { uninitialized, uninitialized, obj }
+ writer.visitInsn(Opcodes.SWAP)
+ // Stack: { uninitialized, obj, uninitialized }
+ writer.visitInsn(Opcodes.POP)
+ // Stack: { uninitialized, obj }
+ writer.visitInsn(Opcodes.SWAP)
+ // Stack: { obj, uninitialized }
+ writer.visitInsn(Opcodes.POP)
+ // Stack: { obj }
+
+ // We end up with only the desired object on the stack
+}
+
+/**
* Given a method descriptor, insert an [argType] as the first argument to it.
*/
fun prependArgTypeToMethodDescriptor(methodDescriptor: String, classInternalName: String): String {
val returnType = Type.getReturnType(methodDescriptor)
val argTypes = Type.getArgumentTypes(methodDescriptor).toMutableList()
- argTypes.add(0, Type.getType("L" + classInternalName + ";"))
+ argTypes.add(0, Type.getType("L$classInternalName;"))
return Type.getMethodDescriptor(returnType, *argTypes.toTypedArray())
}
/**
+ * Given a method descriptor, change the return type to [classInternalName].
+ */
+fun changeMethodDescriptorReturnType(methodDescriptor: String, classInternalName: String): String {
+ val argTypes = Type.getArgumentTypes(methodDescriptor)
+ val returnType = Type.getType("L$classInternalName;")
+ return Type.getMethodDescriptor(returnType, *argTypes)
+}
+
+/**
* Return the "visibility" modifier from an `access` integer.
*
* (see https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1)
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
index 36adf0626415..73c72a21ef7b 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
@@ -31,7 +31,7 @@ import com.android.hoststubgen.asm.toHumanReadableClassName
import com.android.hoststubgen.asm.toHumanReadableMethodName
import com.android.hoststubgen.asm.toJvmClassName
import com.android.hoststubgen.log
-import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.utils.ClassPredicate
import org.objectweb.asm.tree.AnnotationNode
import org.objectweb.asm.tree.ClassNode
@@ -53,10 +53,19 @@ class AnnotationBasedFilter(
redirectAnnotations_: Set<String>,
redirectionClassAnnotations_: Set<String>,
classLoadHookAnnotations_: Set<String>,
+ partiallyAllowlistedClassAnnotations_: Set<String>,
keepStaticInitializerAnnotations_: Set<String>,
- private val annotationAllowedClassesFilter: ClassFilter,
+ private val annotationAllowedClassesFilter: ClassPredicate,
fallback: OutputFilter,
) : DelegatingFilter(fallback) {
+
+ /**
+ * This is a filter chain to check if an entity (class/member) has a "allow-annotation"
+ * policy.
+ */
+ var annotationAllowedMembers: OutputFilter =
+ ConstantFilter(FilterPolicy.Remove, "default disallowed")
+
private val keepAnnotations = convertToInternalNames(keepAnnotations_)
private val keepClassAnnotations = convertToInternalNames(keepClassAnnotations_)
private val throwAnnotations = convertToInternalNames(throwAnnotations_)
@@ -67,6 +76,9 @@ class AnnotationBasedFilter(
private val redirectionClassAnnotations =
convertToInternalNames(redirectionClassAnnotations_)
private val classLoadHookAnnotations = convertToInternalNames(classLoadHookAnnotations_)
+ private val partiallyAllowlistedClassAnnotations =
+ convertToInternalNames(partiallyAllowlistedClassAnnotations_)
+
private val keepStaticInitializerAnnotations =
convertToInternalNames(keepStaticInitializerAnnotations_)
@@ -79,17 +91,22 @@ class AnnotationBasedFilter(
redirectAnnotations +
substituteAnnotations
- /** All the annotations we use. */
- private val allAnnotations = visibilityAnnotations +
+ /**
+ * Annotations that require "fully" allowlisting.
+ */
+ private val allowlistRequiringAnnotations = visibilityAnnotations +
redirectionClassAnnotations +
classLoadHookAnnotations +
keepStaticInitializerAnnotations
+ // partiallyAllowlistedClassAnnotations // This is excluded.
/**
- * All the annotations we use. Note, this one is in a [convertToJvmNames] format unlike
- * other ones, because of how it's used.
+ * We always keep these types.
+ *
+ * Note, this one is in a [convertToJvmNames] format unlike other ones, because of how it's
+ * used.
*/
- private val allAnnotationClasses: Set<String> = convertToJvmNames(
+ private val alwaysKeepClasses: Set<String> = convertToJvmNames(
keepAnnotations_ +
keepClassAnnotations_ +
throwAnnotations_ +
@@ -98,6 +115,7 @@ class AnnotationBasedFilter(
substituteAnnotations_ +
redirectionClassAnnotations_ +
classLoadHookAnnotations_ +
+ partiallyAllowlistedClassAnnotations_ +
keepStaticInitializerAnnotations_
)
@@ -122,7 +140,7 @@ class AnnotationBasedFilter(
override fun getPolicyForClass(className: String): FilterPolicyWithReason {
// If it's any of the annotations, then always keep it.
- if (allAnnotationClasses.contains(className)) {
+ if (alwaysKeepClasses.contains(className)) {
return FilterPolicy.KeepClass.withReason("HostStubGen Annotation")
}
@@ -197,13 +215,34 @@ class AnnotationBasedFilter(
val classLoadHooks: List<String>
init {
- val allowAnnotation = annotationAllowedClassesFilter.matches(cn.name)
- detectInvalidAnnotations(
- cn.name, allowAnnotation,
+ // First, check if the class has "partially-allowed" policy.
+ // This filter chain contains
+ val annotationPartiallyAllowedClass =
+ annotationAllowedMembers.getPolicyForClass(cn.name).policy ==
+ FilterPolicy.AnnotationAllowed
+
+ // If a class is partially-allowlisted, then it's not fully-allowlisted.
+ // Otherwise, just use annotationAllowedClassesFilter.
+ val fullyAllowAnnotation = !annotationPartiallyAllowedClass &&
+ annotationAllowedClassesFilter.matches(cn.name)
+ detectInvalidAnnotations(isClass = true,
+ cn.name, fullyAllowAnnotation, annotationPartiallyAllowedClass,
+ annotationPartiallyAllowedClass,
cn.visibleAnnotations, cn.invisibleAnnotations,
"class", cn.name
)
- classPolicy = cn.findAnyAnnotation(visibilityAnnotations)?.policy
+
+ val classAnnot = cn.findAnyAnnotation(visibilityAnnotations)
+ classPolicy = classAnnot?.policy
+
+ classPolicy?.let { policy ->
+ if (policy.policy.isClassWide && annotationPartiallyAllowedClass) {
+ errors.onErrorFound("Class ${cn.name.toHumanReadableClassName()}" +
+ " has class wide annotation" +
+ " ${classAnnot?.desc?.toHumanReadableClassName()}" +
+ ", which can't be used in a partially-allowlisted class")
+ }
+ }
redirectionClass = cn.findAnyAnnotation(redirectionClassAnnotations)?.let { an ->
getAnnotationField(an, "value")?.let { resolveRelativeClass(cn, it) }
}
@@ -216,8 +255,10 @@ class AnnotationBasedFilter(
}
for (fn in cn.fields ?: emptyList()) {
- detectInvalidAnnotations(
- cn.name, allowAnnotation,
+ val partiallyAllowAnnotation = false // No partial allowlisting on fields (yet)
+ detectInvalidAnnotations(isClass = false,
+ cn.name, fullyAllowAnnotation, partiallyAllowAnnotation,
+ annotationPartiallyAllowedClass,
fn.visibleAnnotations, fn.invisibleAnnotations,
"field", cn.name, fn.name
)
@@ -227,8 +268,12 @@ class AnnotationBasedFilter(
}
for (mn in cn.methods ?: emptyList()) {
- detectInvalidAnnotations(
- cn.name, allowAnnotation,
+ val partiallyAllowAnnotation =
+ annotationAllowedMembers.getPolicyForMethod(cn.name, mn.name, mn.desc).policy ==
+ FilterPolicy.AnnotationAllowed
+ detectInvalidAnnotations(isClass = false,
+ cn.name, fullyAllowAnnotation, partiallyAllowAnnotation,
+ annotationPartiallyAllowedClass,
mn.visibleAnnotations, mn.invisibleAnnotations,
"method", cn.name, mn.name, mn.desc
)
@@ -263,8 +308,11 @@ class AnnotationBasedFilter(
* to avoid unnecessary string concatenations.
*/
private fun detectInvalidAnnotations(
+ isClass: Boolean,
className: String,
- allowAnnotation: Boolean,
+ fullyAllowAnnotation: Boolean,
+ partiallyAllowAnnotation: Boolean,
+ classPartiallyAllowAnnotation: Boolean,
visibles: List<AnnotationNode>?,
invisibles: List<AnnotationNode>?,
type: String,
@@ -272,13 +320,26 @@ class AnnotationBasedFilter(
name2: String = "",
name3: String = "",
) {
+ // Lazily create the description.
+ val desc = { getItemDescription(type, name1, name2, name3) }
+
+ val partiallyAllowlistAnnotation =
+ findAnyAnnotation(partiallyAllowlistedClassAnnotations, visibles, invisibles)
+ partiallyAllowlistAnnotation?.let { anot ->
+ if (!partiallyAllowAnnotation) {
+ errors.onErrorFound(desc() +
+ " has annotation ${anot.desc?.toHumanReadableClassName()}, but" +
+ " doesn't have" +
+ " '${FilterPolicy.AnnotationAllowed.policyStringOrPrefix}' policy.'")
+ }
+ }
var count = 0
var visibleCount = 0
for (an in visibles ?: emptyList()) {
if (visibilityAnnotations.contains(an.desc)) {
visibleCount++
}
- if (allAnnotations.contains(an.desc)) {
+ if (allowlistRequiringAnnotations.contains(an.desc)) {
count++
}
}
@@ -286,28 +347,54 @@ class AnnotationBasedFilter(
if (visibilityAnnotations.contains(an.desc)) {
visibleCount++
}
- if (allAnnotations.contains(an.desc)) {
+ if (allowlistRequiringAnnotations.contains(an.desc)) {
count++
}
}
- if (count > 0 && !allowAnnotation) {
+ // Special case -- if it's a class, and has an "allow-annotation" policy
+ // *and* if it actually has an annotation, then it must have the
+ // "PartiallyAllowlisted" annotation.
+ // Conversely, even if it has an "allow-annotation" policy, it's okay
+ // if it doesn't have the annotation, as long as it doesn't have any
+ // annotations.
+ if (isClass && count > 0 && partiallyAllowAnnotation) {
+ if (partiallyAllowlistAnnotation == null) {
+ val requiredAnnot = partiallyAllowlistedClassAnnotations.firstOrNull()
+ throw InvalidAnnotationException(
+ "${desc()} must have ${requiredAnnot?.toHumanReadableClassName()} to use" +
+ " annotations")
+ }
+ }
+
+ if (count > 0 && !(fullyAllowAnnotation || partiallyAllowAnnotation)) {
+ val extInfo = if (classPartiallyAllowAnnotation) {
+ " (Class is partially allowlisted.)"
+ } else {""}
throw InvalidAnnotationException(
- "Class ${className.toHumanReadableClassName()} is not allowed to have " +
- "Ravenwood annotations. Contact g/ravenwood for more details."
+ "${desc()} is not allowed to have " +
+ "Ravenwood annotations.$extInfo Contact g/ravenwood for more details."
)
}
if (visibleCount > 1) {
- val description = if (name2 == "" && name3 == "") {
- "$type $name1"
- } else {
- "$type $name1.$name2$name3"
- }
throw InvalidAnnotationException(
- "Found more than one visibility annotations on $description"
+ "Found more than one visibility annotations on ${desc()}"
)
}
}
+ private fun getItemDescription(
+ type: String,
+ name1: String,
+ name2: String,
+ name3: String,
+ ): String {
+ return if (name2 == "" && name3 == "") {
+ "$type $name1"
+ } else {
+ "$type $name1.$name2$name3"
+ }
+ }
+
/**
* Return the (String) value of 'value' parameter from an annotation.
*/
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
index d771003a955d..aaf49c154a17 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
@@ -16,8 +16,11 @@
package com.android.hoststubgen.filters
import com.android.hoststubgen.addLists
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.isAnnotation
class DefaultHookInjectingFilter(
+ val classes: ClassNodes,
defaultClassLoadHook: String?,
defaultMethodCallHook: String?,
fallback: OutputFilter
@@ -36,8 +39,30 @@ class DefaultHookInjectingFilter(
private val defaultClassLoadHookAsList: List<String> = toSingleList(defaultClassLoadHook)
private val defaultMethodCallHookAsList: List<String> = toSingleList(defaultMethodCallHook)
+ private fun shouldInject(className: String): Boolean {
+ // Let's not inject default hooks to annotation classes or inner classes of an annotation
+ // class, because these methods could be called at the class load time, which
+ // is very confusing, and usually not useful.
+
+ val cn = classes.findClass(className) ?: return false
+ if (cn.isAnnotation()) {
+ return false
+ }
+ cn.nestHostClass?.let { nestHostClass ->
+ val nestHost = classes.findClass(nestHostClass) ?: return false
+ if (nestHost.isAnnotation()) {
+ return false
+ }
+ }
+ return true
+ }
+
override fun getClassLoadHooks(className: String): List<String> {
- return addLists(super.getClassLoadHooks(className), defaultClassLoadHookAsList)
+ val s = super.getClassLoadHooks(className)
+ if (!shouldInject(className)) {
+ return s
+ }
+ return addLists(s, defaultClassLoadHookAsList)
}
override fun getMethodCallHooks(
@@ -45,9 +70,23 @@ class DefaultHookInjectingFilter(
methodName: String,
descriptor: String
): List<String> {
- return addLists(
- super.getMethodCallHooks(className, methodName, descriptor),
- defaultMethodCallHookAsList,
- )
+ val s = super.getMethodCallHooks(className, methodName, descriptor)
+ if (!shouldInject(className)) {
+ return s
+ }
+ // Don't hook Object methods.
+ if (methodName == "finalize" && descriptor == "()V") {
+ return s
+ }
+ if (methodName == "toString" && descriptor == "()Ljava/lang/String;") {
+ return s
+ }
+ if (methodName == "equals" && descriptor == "(Ljava/lang/Object;)Z") {
+ return s
+ }
+ if (methodName == "hashCode" && descriptor == "()I") {
+ return s
+ }
+ return addLists(s, defaultMethodCallHookAsList)
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
index 2f2f81b05ad1..81c26ffdf1f4 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
@@ -15,44 +15,51 @@
*/
package com.android.hoststubgen.filters
-enum class FilterPolicy {
+enum class FilterPolicy(val policyStringOrPrefix: String) {
/**
* Keep the item in the jar file.
*/
- Keep,
+ Keep("keep"),
/**
* Only usable with classes. Keep the class in the jar, and also all its members.
* Each member can have another policy to override it.
*/
- KeepClass,
+ KeepClass("keepclass"),
/**
* Only usable with methods. Replace a method with a "substitution" method.
*/
- Substitute,
+ Substitute("@"), // @ is a prefix
/**
* Only usable with methods. Redirect a method to a method in the substitution class.
*/
- Redirect,
+ Redirect("redirect"),
/**
* Only usable with methods. The item will be kept in the impl jar file, but when called,
* it'll throw.
*/
- Throw,
+ Throw("throw"),
/**
* Only usable with methods. The item will be kept in the impl jar file, but when called,
* it'll no-op.
*/
- Ignore,
+ Ignore("ignore"),
/**
* Remove the item completely.
*/
- Remove;
+ Remove("remove"),
+
+ /**
+ * Special policy used for "partial annotation allowlisting". This policy must not be
+ * used in the "main" filter chain. (which would be detected by [SanitizationFilter].)
+ * It's used in a separate filter chain used by [AnnotationBasedFilter].
+ */
+ AnnotationAllowed("allow-annotation");
val needsInOutput: Boolean
get() {
@@ -66,7 +73,7 @@ enum class FilterPolicy {
val isUsableWithClasses: Boolean
get() {
return when (this) {
- Keep, KeepClass, Remove -> true
+ Keep, KeepClass, Remove, AnnotationAllowed -> true
else -> false
}
}
@@ -75,6 +82,7 @@ enum class FilterPolicy {
val isUsableWithFields: Boolean
get() {
return when (this) {
+ // AnnotationAllowed isn't supported on fields (yet). We could support it if needed.
Keep, Remove -> true
else -> false
}
@@ -102,7 +110,7 @@ enum class FilterPolicy {
val isSupported: Boolean
get() {
return when (this) {
- Keep, KeepClass, Substitute, Redirect -> true
+ Keep, KeepClass, Substitute, Redirect, AnnotationAllowed -> true
else -> false
}
}
@@ -115,6 +123,25 @@ enum class FilterPolicy {
}
}
+ val isClassWide: Boolean
+ get() {
+ return when (this) {
+ Remove, KeepClass -> true
+ else -> false
+ }
+ }
+
+ /**
+ * Internal policies must not be used in the main filter chain.
+ */
+ val isInternalPolicy: Boolean
+ get() {
+ return when (this) {
+ AnnotationAllowed -> true
+ else -> false
+ }
+ }
+
/**
* Convert KeepClass to Keep, or return itself.
*/
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
index c5a2f9ff5e96..bba4681d3838 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/FilterRemapper.kt
@@ -15,6 +15,7 @@
*/
package com.android.hoststubgen.filters
+import com.android.hoststubgen.log
import org.objectweb.asm.commons.Remapper
/**
@@ -23,19 +24,25 @@ import org.objectweb.asm.commons.Remapper
class FilterRemapper(val filter: OutputFilter) : Remapper() {
private val cache = mutableMapOf<String, String>()
- override fun mapType(typeInternalName: String?): String? {
+
+ override fun map(typeInternalName: String?): String? {
if (typeInternalName == null) {
return null
}
cache[typeInternalName]?.let {
+ // log.d("Cached rename from $typeInternalName to $it")
return it
}
- var mapped = filter.remapType(typeInternalName) ?: typeInternalName
+ var mapped = filter.remapType(typeInternalName)
+ if (mapped != null) {
+ log.d("Renaming type $typeInternalName to $mapped")
+ } else {
+ // log.d("Not renaming type $typeInternalName")
+ }
+ mapped = mapped ?: typeInternalName
cache[typeInternalName] = mapped
return mapped
}
-
- // TODO Do we need to implement mapPackage(), etc too?
} \ No newline at end of file
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt
index 18a1e16bcf3a..4375c6500b62 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/SanitizationFilter.kt
@@ -16,6 +16,7 @@
package com.android.hoststubgen.filters
import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.HostStubGenInternalException
import com.android.hoststubgen.asm.ClassNodes
import com.android.hoststubgen.asm.toHumanReadableClassName
import com.android.hoststubgen.log
@@ -28,12 +29,30 @@ class SanitizationFilter(
private val classes: ClassNodes,
fallback: OutputFilter
) : DelegatingFilter(fallback) {
+ private fun validate(policy: FilterPolicyWithReason): FilterPolicyWithReason {
+ // "Internal" policies shouldn't be used in the "main" filter chain.
+ // They're for filter chains for other purposes.
+ if (policy.policy.isInternalPolicy) {
+ throw HostStubGenInternalException(
+ "Policy $policy must not be used in the \"real\" filter chain.")
+ }
+ return policy
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ return validate(super.getPolicyForClass(className))
+ }
+
+ override fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason {
+ return validate(super.getPolicyForField(className, fieldName))
+ }
+
override fun getPolicyForMethod(
className: String,
methodName: String,
descriptor: String
): FilterPolicyWithReason {
- val policy = super.getPolicyForMethod(className, methodName, descriptor)
+ val policy = validate(super.getPolicyForMethod(className, methodName, descriptor))
if (policy.policy == FilterPolicy.Redirect) {
// Check whether the hosting class has a redirection class
if (getRedirectionClass(className) == null) {
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
index 7462a8ce12c5..dd353e9caeff 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
@@ -23,10 +23,12 @@ import com.android.hoststubgen.asm.toJvmClassName
import com.android.hoststubgen.log
import com.android.hoststubgen.normalizeTextLine
import com.android.hoststubgen.whitespaceRegex
-import java.io.File
+import org.objectweb.asm.tree.ClassNode
+import java.io.BufferedReader
+import java.io.FileReader
import java.io.PrintWriter
+import java.io.Reader
import java.util.regex.Pattern
-import org.objectweb.asm.tree.ClassNode
/**
* Print a class node as a "keep" policy.
@@ -48,7 +50,7 @@ fun printAsTextPolicy(pw: PrintWriter, cn: ClassNode) {
private const val FILTER_REASON = "file-override"
-private enum class SpecialClass {
+enum class SpecialClass {
NotSpecial,
Aidl,
FeatureFlags,
@@ -56,10 +58,57 @@ private enum class SpecialClass {
RFile,
}
-class TextFileFilterPolicyParser(
+/**
+ * This receives [TextFileFilterPolicyBuilder] parsing result.
+ */
+interface PolicyFileProcessor {
+ /** "package" directive. */
+ fun onPackage(name: String, policy: FilterPolicyWithReason)
+
+ /** "rename" directive. */
+ fun onRename(pattern: Pattern, prefix: String)
+
+ /** "class" directive. */
+ fun onClassStart(className: String)
+ fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason)
+ fun onClassEnd(className: String)
+
+ fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason)
+ fun onRedirectionClass(fromClassName: String, toClassName: String)
+ fun onClassLoadHook(className: String, callback: String)
+ fun onSpecialClassPolicy(type: SpecialClass, policy: FilterPolicyWithReason)
+
+ /** "field" directive. */
+ fun onField(className: String, fieldName: String, policy: FilterPolicyWithReason)
+
+ /** "method" directive. */
+ fun onSimpleMethodPolicy(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ policy: FilterPolicyWithReason,
+ )
+ fun onMethodInClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ targetName: String,
+ policy: FilterPolicyWithReason,
+ )
+ fun onMethodOutClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ replaceSpec: TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec,
+ )
+}
+
+class TextFileFilterPolicyBuilder(
private val classes: ClassNodes,
fallback: OutputFilter
) {
+ private val parser = TextFileFilterPolicyParser()
+
private val subclassFilter = SubclassFilter(classes, fallback)
private val packageFilter = PackageFilter(subclassFilter)
private val imf = InMemoryOutputFilter(classes, packageFilter)
@@ -71,30 +120,38 @@ class TextFileFilterPolicyParser(
private val methodReplaceSpec =
mutableListOf<TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec>()
- private lateinit var currentClassName: String
+ /**
+ * Fields for a filter chain used for "partial allowlisting", which are used by
+ * [AnnotationBasedFilter].
+ */
+ private val annotationAllowedInMemoryFilter: InMemoryOutputFilter
+ val annotationAllowedMembersFilter: OutputFilter
+
+ private val annotationAllowedPolicy = FilterPolicy.AnnotationAllowed.withReason(FILTER_REASON)
+
+ init {
+ // Create a filter that checks "partial allowlisting".
+ var aaf: OutputFilter = ConstantFilter(FilterPolicy.Remove, "default disallowed")
+
+ aaf = InMemoryOutputFilter(classes, aaf)
+ annotationAllowedInMemoryFilter = aaf
+
+ annotationAllowedMembersFilter = annotationAllowedInMemoryFilter
+ }
/**
- * Read a given "policy" file and return as an [OutputFilter]
+ * Parse a given policy file. This method can be called multiple times to read from
+ * multiple files. To get the resulting filter, use [createOutputFilter]
*/
fun parse(file: String) {
- log.i("Loading offloaded annotations from $file ...")
- log.withIndent {
- var lineNo = 0
- try {
- File(file).forEachLine {
- lineNo++
- val line = normalizeTextLine(it)
- if (line.isEmpty()) {
- return@forEachLine // skip empty lines.
- }
- parseLine(line)
- }
- } catch (e: ParseException) {
- throw e.withSourceInfo(file, lineNo)
- }
- }
+ // We may parse multiple files, but we reuse the same parser, because the parser
+ // will make sure there'll be no dupplicating "special class" policies.
+ parser.parse(FileReader(file), file, Processor())
}
+ /**
+ * Generate the resulting [OutputFilter].
+ */
fun createOutputFilter(): OutputFilter {
var ret: OutputFilter = imf
if (typeRenameSpec.isNotEmpty()) {
@@ -112,14 +169,220 @@ class TextFileFilterPolicyParser(
return ret
}
+ private inner class Processor : PolicyFileProcessor {
+ override fun onPackage(name: String, policy: FilterPolicyWithReason) {
+ if (policy.policy == FilterPolicy.AnnotationAllowed) {
+ throw ParseException("${FilterPolicy.AnnotationAllowed.policyStringOrPrefix}" +
+ " on `package` isn't supported yet.")
+ return
+ }
+ packageFilter.addPolicy(name, policy)
+ }
+
+ override fun onRename(pattern: Pattern, prefix: String) {
+ typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
+ pattern, prefix
+ )
+ }
+
+ override fun onClassStart(className: String) {
+ }
+
+ override fun onClassEnd(className: String) {
+ }
+
+ override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) {
+ if (policy.policy == FilterPolicy.AnnotationAllowed) {
+ annotationAllowedInMemoryFilter.setPolicyForClass(
+ className, annotationAllowedPolicy)
+ return
+ }
+ imf.setPolicyForClass(className, policy)
+ }
+
+ override fun onSubClassPolicy(
+ superClassName: String,
+ policy: FilterPolicyWithReason,
+ ) {
+ log.i("class extends $superClassName")
+ subclassFilter.addPolicy( superClassName, policy)
+ }
+
+ override fun onRedirectionClass(fromClassName: String, toClassName: String) {
+ imf.setRedirectionClass(fromClassName, toClassName)
+ }
+
+ override fun onClassLoadHook(className: String, callback: String) {
+ imf.setClassLoadHook(className, callback)
+ }
+
+ override fun onSpecialClassPolicy(
+ type: SpecialClass,
+ policy: FilterPolicyWithReason,
+ ) {
+ log.i("class special $type $policy")
+ when (type) {
+ SpecialClass.NotSpecial -> {} // Shouldn't happen
+
+ SpecialClass.Aidl -> {
+ aidlPolicy = policy
+ }
+
+ SpecialClass.FeatureFlags -> {
+ featureFlagsPolicy = policy
+ }
+
+ SpecialClass.Sysprops -> {
+ syspropsPolicy = policy
+ }
+
+ SpecialClass.RFile -> {
+ rFilePolicy = policy
+ }
+ }
+ }
+
+ override fun onField(className: String, fieldName: String, policy: FilterPolicyWithReason) {
+ imf.setPolicyForField(className, fieldName, policy)
+ }
+
+ override fun onSimpleMethodPolicy(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ policy: FilterPolicyWithReason,
+ ) {
+ if (policy.policy == FilterPolicy.AnnotationAllowed) {
+ annotationAllowedInMemoryFilter.setPolicyForMethod(
+ className, methodName, methodDesc, annotationAllowedPolicy)
+ return
+ }
+ imf.setPolicyForMethod(className, methodName, methodDesc, policy)
+ }
+
+ override fun onMethodInClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ targetName: String,
+ policy: FilterPolicyWithReason,
+ ) {
+ imf.setPolicyForMethod(className, methodName, methodDesc, policy)
+
+ // Make sure to keep the target method.
+ imf.setPolicyForMethod(
+ className,
+ targetName,
+ methodDesc,
+ FilterPolicy.Keep.withReason(FILTER_REASON)
+ )
+ // Set up the rename.
+ imf.setRenameTo(className, targetName, methodDesc, methodName)
+ }
+
+ override fun onMethodOutClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ replaceSpec: TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec,
+ ) {
+ // Keep the source method, because the target method may call it.
+ imf.setPolicyForMethod(className, methodName, methodDesc,
+ FilterPolicy.Keep.withReason(FILTER_REASON))
+ methodReplaceSpec.add(replaceSpec)
+ }
+ }
+}
+
+/**
+ * Parses a filer policy text file.
+ */
+class TextFileFilterPolicyParser {
+ private lateinit var processor: PolicyFileProcessor
+ private var currentClassName: String? = null
+
+ private var aidlPolicy: FilterPolicyWithReason? = null
+ private var featureFlagsPolicy: FilterPolicyWithReason? = null
+ private var syspropsPolicy: FilterPolicyWithReason? = null
+ private var rFilePolicy: FilterPolicyWithReason? = null
+
+ /** Name of the file that's currently being processed. */
+ var filename: String = ""
+ private set
+
+ /** 1-based line number in the current file */
+ var lineNumber = -1
+ private set
+
+ /** Current line */
+ var currentLineText = ""
+ private set
+
+ /**
+ * Parse a given "policy" file.
+ */
+ fun parse(reader: Reader, inputName: String, processor: PolicyFileProcessor) {
+ filename = inputName
+
+ this.processor = processor
+ BufferedReader(reader).use { rd ->
+ lineNumber = 0
+ try {
+ while (true) {
+ var line = rd.readLine()
+ if (line == null) {
+ break
+ }
+ lineNumber++
+ currentLineText = line
+ line = normalizeTextLine(line) // Remove comment and trim.
+ if (line.isEmpty()) {
+ continue
+ }
+ parseLine(line)
+ }
+ finishLastClass()
+ } catch (e: ParseException) {
+ throw e.withSourceInfo(inputName, lineNumber)
+ }
+ }
+ }
+
+ private fun finishLastClass() {
+ currentClassName?.let { className ->
+ processor.onClassEnd(className)
+ currentClassName = null
+ }
+ }
+
+ private fun ensureInClass(directive: String): String {
+ return currentClassName ?:
+ throw ParseException("Directive '$directive' must follow a 'class' directive")
+ }
+
private fun parseLine(line: String) {
val fields = line.split(whitespaceRegex).toTypedArray()
when (fields[0].lowercase()) {
- "p", "package" -> parsePackage(fields)
- "c", "class" -> parseClass(fields)
- "f", "field" -> parseField(fields)
- "m", "method" -> parseMethod(fields)
- "r", "rename" -> parseRename(fields)
+ "p", "package" -> {
+ finishLastClass()
+ parsePackage(fields)
+ }
+ "c", "class" -> {
+ finishLastClass()
+ parseClass(fields)
+ }
+ "f", "field" -> {
+ ensureInClass("field")
+ parseField(fields)
+ }
+ "m", "method" -> {
+ ensureInClass("method")
+ parseMethod(fields)
+ }
+ "r", "rename" -> {
+ finishLastClass()
+ parseRename(fields)
+ }
else -> throw ParseException("Unknown directive \"${fields[0]}\"")
}
}
@@ -146,14 +409,15 @@ class TextFileFilterPolicyParser(
private fun parsePolicy(s: String): FilterPolicy {
return when (s.lowercase()) {
- "k", "keep" -> FilterPolicy.Keep
- "t", "throw" -> FilterPolicy.Throw
- "r", "remove" -> FilterPolicy.Remove
- "kc", "keepclass" -> FilterPolicy.KeepClass
- "i", "ignore" -> FilterPolicy.Ignore
- "rdr", "redirect" -> FilterPolicy.Redirect
+ "k", FilterPolicy.Keep.policyStringOrPrefix -> FilterPolicy.Keep
+ "t", FilterPolicy.Throw.policyStringOrPrefix -> FilterPolicy.Throw
+ "r", FilterPolicy.Remove.policyStringOrPrefix -> FilterPolicy.Remove
+ "kc", FilterPolicy.KeepClass.policyStringOrPrefix -> FilterPolicy.KeepClass
+ "i", FilterPolicy.Ignore.policyStringOrPrefix -> FilterPolicy.Ignore
+ "rdr", FilterPolicy.Redirect.policyStringOrPrefix -> FilterPolicy.Redirect
+ FilterPolicy.AnnotationAllowed.policyStringOrPrefix -> FilterPolicy.AnnotationAllowed
else -> {
- if (s.startsWith("@")) {
+ if (s.startsWith(FilterPolicy.Substitute.policyStringOrPrefix)) {
FilterPolicy.Substitute
} else {
throw ParseException("Invalid policy \"$s\"")
@@ -184,22 +448,24 @@ class TextFileFilterPolicyParser(
if (!policy.isUsableWithClasses) {
throw ParseException("Package can't have policy '$policy'")
}
- packageFilter.addPolicy(name, policy.withReason(FILTER_REASON))
+ processor.onPackage(name, policy.withReason(FILTER_REASON))
}
private fun parseClass(fields: Array<String>) {
- if (fields.size < 3) {
- throw ParseException("Class ('c') expects 2 fields.")
+ if (fields.size <= 1) {
+ throw ParseException("Class ('c') expects 1 or 2 fields.")
}
- currentClassName = fields[1]
+ val className = fields[1].toHumanReadableClassName()
// superClass is set when the class name starts with a "*".
- val superClass = resolveExtendingClass(currentClassName)
+ val superClass = resolveExtendingClass(className)
// :aidl, etc?
- val classType = resolveSpecialClass(currentClassName)
+ val classType = resolveSpecialClass(className)
+
+ val policyStr = if (fields.size > 2) { fields[2] } else { "" }
- if (fields[2].startsWith("!")) {
+ if (policyStr.startsWith("!")) {
if (classType != SpecialClass.NotSpecial) {
// We could support it, but not needed at least for now.
throw ParseException(
@@ -207,9 +473,12 @@ class TextFileFilterPolicyParser(
)
}
// It's a redirection class.
- val toClass = fields[2].substring(1)
- imf.setRedirectionClass(currentClassName, toClass)
- } else if (fields[2].startsWith("~")) {
+ val toClass = policyStr.substring(1)
+
+ currentClassName = className
+ processor.onClassStart(className)
+ processor.onRedirectionClass(className, toClass)
+ } else if (policyStr.startsWith("~")) {
if (classType != SpecialClass.NotSpecial) {
// We could support it, but not needed at least for now.
throw ParseException(
@@ -217,10 +486,24 @@ class TextFileFilterPolicyParser(
)
}
// It's a class-load hook
- val callback = fields[2].substring(1)
- imf.setClassLoadHook(currentClassName, callback)
+ val callback = policyStr.substring(1)
+
+ currentClassName = className
+ processor.onClassStart(className)
+ processor.onClassLoadHook(className, callback)
} else {
- val policy = parsePolicy(fields[2])
+ // Special case: if it's a class directive with no policy, then it encloses
+ // members, but we don't apply any policy to the class itself.
+ // This is only allowed in a not-special case.
+ if (policyStr == "") {
+ if (classType == SpecialClass.NotSpecial && superClass == null) {
+ currentClassName = className
+ return
+ }
+ throw ParseException("Special class or subclass directive must have a policy")
+ }
+
+ val policy = parsePolicy(policyStr)
if (!policy.isUsableWithClasses) {
throw ParseException("Class can't have policy '$policy'")
}
@@ -229,26 +512,27 @@ class TextFileFilterPolicyParser(
SpecialClass.NotSpecial -> {
// TODO: Duplicate check, etc
if (superClass == null) {
- imf.setPolicyForClass(
- currentClassName, policy.withReason(FILTER_REASON)
- )
+ currentClassName = className
+ processor.onClassStart(className)
+ processor.onSimpleClassPolicy(className, policy.withReason(FILTER_REASON))
} else {
- subclassFilter.addPolicy(
+ processor.onSubClassPolicy(
superClass,
- policy.withReason("extends $superClass")
+ policy.withReason("extends $superClass"),
)
}
}
-
SpecialClass.Aidl -> {
if (aidlPolicy != null) {
throw ParseException(
"Policy for AIDL classes already defined"
)
}
- aidlPolicy = policy.withReason(
+ val p = policy.withReason(
"$FILTER_REASON (special-class AIDL)"
)
+ processor.onSpecialClassPolicy(classType, p)
+ aidlPolicy = p
}
SpecialClass.FeatureFlags -> {
@@ -257,9 +541,11 @@ class TextFileFilterPolicyParser(
"Policy for feature flags already defined"
)
}
- featureFlagsPolicy = policy.withReason(
+ val p = policy.withReason(
"$FILTER_REASON (special-class feature flags)"
)
+ processor.onSpecialClassPolicy(classType, p)
+ featureFlagsPolicy = p
}
SpecialClass.Sysprops -> {
@@ -268,9 +554,11 @@ class TextFileFilterPolicyParser(
"Policy for sysprops already defined"
)
}
- syspropsPolicy = policy.withReason(
+ val p = policy.withReason(
"$FILTER_REASON (special-class sysprops)"
)
+ processor.onSpecialClassPolicy(classType, p)
+ syspropsPolicy = p
}
SpecialClass.RFile -> {
@@ -279,9 +567,11 @@ class TextFileFilterPolicyParser(
"Policy for R file already defined"
)
}
- rFilePolicy = policy.withReason(
+ val p = policy.withReason(
"$FILTER_REASON (special-class R file)"
)
+ processor.onSpecialClassPolicy(classType, p)
+ rFilePolicy = p
}
}
}
@@ -296,17 +586,16 @@ class TextFileFilterPolicyParser(
if (!policy.isUsableWithFields) {
throw ParseException("Field can't have policy '$policy'")
}
- require(this::currentClassName.isInitialized)
// TODO: Duplicate check, etc
- imf.setPolicyForField(currentClassName, name, policy.withReason(FILTER_REASON))
+ processor.onField(currentClassName!!, name, policy.withReason(FILTER_REASON))
}
private fun parseMethod(fields: Array<String>) {
if (fields.size < 3 || fields.size > 4) {
throw ParseException("Method ('m') expects 3 or 4 fields.")
}
- val name = fields[1]
+ val methodName = fields[1]
val signature: String
val policyStr: String
if (fields.size <= 3) {
@@ -323,44 +612,47 @@ class TextFileFilterPolicyParser(
throw ParseException("Method can't have policy '$policy'")
}
- require(this::currentClassName.isInitialized)
+ val className = currentClassName!!
- imf.setPolicyForMethod(
- currentClassName, name, signature,
- policy.withReason(FILTER_REASON)
- )
- if (policy == FilterPolicy.Substitute) {
- val fromName = policyStr.substring(1)
+ val policyWithReason = policy.withReason(FILTER_REASON)
+ if (policy != FilterPolicy.Substitute) {
+ processor.onSimpleMethodPolicy(className, methodName, signature, policyWithReason)
+ } else {
+ val targetName = policyStr.substring(1)
- if (fromName == name) {
+ if (targetName == methodName) {
throw ParseException(
"Substitution must have a different name"
)
}
- // Set the policy for the "from" method.
- imf.setPolicyForMethod(
- currentClassName, fromName, signature,
- FilterPolicy.Keep.withReason(FILTER_REASON)
- )
-
- val classAndMethod = splitWithLastPeriod(fromName)
+ val classAndMethod = splitWithLastPeriod(targetName)
if (classAndMethod != null) {
// If the substitution target contains a ".", then
// it's a method call redirect.
- methodReplaceSpec.add(
- TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec(
- currentClassName.toJvmClassName(),
- name,
+ val spec = TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec(
+ currentClassName!!.toJvmClassName(),
+ methodName,
signature,
classAndMethod.first.toJvmClassName(),
classAndMethod.second,
)
+ processor.onMethodOutClassReplace(
+ className,
+ methodName,
+ signature,
+ spec,
)
} else {
// It's an in-class replace.
// ("@RavenwoodReplace" equivalent)
- imf.setRenameTo(currentClassName, fromName, signature, name)
+ processor.onMethodInClassReplace(
+ className,
+ methodName,
+ signature,
+ targetName,
+ policyWithReason,
+ )
}
}
}
@@ -378,7 +670,7 @@ class TextFileFilterPolicyParser(
// applied. (Which is needed for services.jar)
val prefix = fields[2].trimStart('/')
- typeRenameSpec += TextFilePolicyRemapperFilter.TypeRenameSpec(
+ processor.onRename(
pattern, prefix
)
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
index a78c6552b8d0..bc90d1248322 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyRemapperFilter.kt
@@ -15,7 +15,6 @@
*/
package com.android.hoststubgen.filters
-import com.android.hoststubgen.log
import java.util.regex.Pattern
/**
@@ -34,17 +33,12 @@ class TextFilePolicyRemapperFilter(
val typeInternalNamePrefix: String,
)
- private val cache = mutableMapOf<String, String>()
-
override fun remapType(className: String): String? {
- var mapped: String = className
typeRenameSpecs.forEach {
if (it.typeInternalNamePattern.matcher(className).matches()) {
- mapped = it.typeInternalNamePrefix + className
- log.d("Renaming type $className to $mapped")
+ return it.typeInternalNamePrefix + className
}
}
- cache[className] = mapped
- return mapped
+ return null
}
}
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
index d6aa7617fd59..4c53bc8fba97 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/utils/ClassPredicate.kt
@@ -22,9 +22,11 @@ import com.android.hoststubgen.normalizeTextLine
import java.io.File
/**
- * General purpose filter for class names.
+ * General purpose class "selector", which returns a boolean for a given class name.
+ *
+ * (It's used to check if a class is in the "annotations allowed classes" allowlist.)
*/
-class ClassFilter private constructor(
+class ClassPredicate private constructor(
private val defaultResult: Boolean,
) {
private enum class MatchType {
@@ -81,14 +83,14 @@ class ClassFilter private constructor(
companion object {
/**
- * Return a filter that alawys returns true or false.
+ * Return a filter that always returns true or false.
*/
- fun newNullFilter(defaultResult: Boolean): ClassFilter {
- return ClassFilter(defaultResult)
+ fun newConstantPredicate(defaultResult: Boolean): ClassPredicate {
+ return ClassPredicate(defaultResult)
}
/** Build a filter from a file. */
- fun loadFromFile(filename: String, defaultResult: Boolean): ClassFilter {
+ fun loadFromFile(filename: String, defaultResult: Boolean): ClassPredicate {
return buildFromString(File(filename).readText(), defaultResult, filename)
}
@@ -97,8 +99,8 @@ class ClassFilter private constructor(
filterString: String,
defaultResult: Boolean,
filenameForErrorMessage: String
- ): ClassFilter {
- val ret = ClassFilter(defaultResult)
+ ): ClassPredicate {
+ val ret = ClassPredicate(defaultResult)
var lineNo = 0
filterString.split('\n').forEach { s ->
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
index 261ef59c45c7..a08d1d605949 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
@@ -50,7 +50,13 @@ abstract class BaseAdapter(
val errors: HostStubGenErrors,
val stats: HostStubGenStats?,
val enablePreTrace: Boolean,
- val enablePostTrace: Boolean
+ val enablePostTrace: Boolean,
+ val deleteClassFinals: Boolean,
+ val deleteMethodFinals: Boolean,
+ // We don't remove finals from fields, because final fields have a stronger memory
+ // guarantee than non-final fields, see:
+ // https://docs.oracle.com/javase/specs/jls/se22/html/jls-17.html#jls-17.5
+ // i.e. changing a final field to non-final _could_ result in different behavior.
)
protected lateinit var currentPackageName: String
@@ -58,14 +64,33 @@ abstract class BaseAdapter(
protected var redirectionClass: String? = null
protected lateinit var classPolicy: FilterPolicyWithReason
+ private fun isEnum(access: Int): Boolean {
+ return (access and Opcodes.ACC_ENUM) != 0
+ }
+
+ protected fun modifyClassAccess(access: Int): Int {
+ if (options.deleteClassFinals && !isEnum(access)) {
+ return access and Opcodes.ACC_FINAL.inv()
+ }
+ return access
+ }
+
+ protected fun modifyMethodAccess(access: Int): Int {
+ if (options.deleteMethodFinals) {
+ return access and Opcodes.ACC_FINAL.inv()
+ }
+ return access
+ }
+
override fun visit(
version: Int,
- access: Int,
+ origAccess: Int,
name: String,
signature: String?,
superName: String?,
interfaces: Array<String>,
) {
+ val access = modifyClassAccess(origAccess)
super.visit(version, access, name, signature, superName, interfaces)
currentClassName = name
currentPackageName = getPackageNameFromFullClassName(name)
@@ -130,13 +155,14 @@ abstract class BaseAdapter(
}
}
- override fun visitMethod(
- access: Int,
+ final override fun visitMethod(
+ origAccess: Int,
name: String,
descriptor: String,
signature: String?,
exceptions: Array<String>?,
): MethodVisitor? {
+ val access = modifyMethodAccess(origAccess)
if (skipMemberModificationNestCount > 0) {
return super.visitMethod(access, name, descriptor, signature, exceptions)
}
@@ -176,6 +202,7 @@ abstract class BaseAdapter(
if (newAccess == NOT_COMPATIBLE) {
return null
}
+ newAccess = modifyMethodAccess(newAccess)
log.v(
"Emitting %s.%s%s as %s %s", currentClassName, name, descriptor,
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
index 567a69e43b58..b8a357668c2b 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
@@ -17,7 +17,10 @@ package com.android.hoststubgen.visitors
import com.android.hoststubgen.asm.CLASS_INITIALIZER_DESC
import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME
+import com.android.hoststubgen.asm.CTOR_NAME
import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.adjustStackForConstructorRedirection
+import com.android.hoststubgen.asm.changeMethodDescriptorReturnType
import com.android.hoststubgen.asm.prependArgTypeToMethodDescriptor
import com.android.hoststubgen.asm.writeByteCodeToPushArguments
import com.android.hoststubgen.asm.writeByteCodeToReturn
@@ -33,6 +36,7 @@ import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Opcodes.INVOKEINTERFACE
+import org.objectweb.asm.Opcodes.INVOKESPECIAL
import org.objectweb.asm.Opcodes.INVOKESTATIC
import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
import org.objectweb.asm.Type
@@ -51,12 +55,13 @@ class ImplGeneratingAdapter(
override fun visit(
version: Int,
- access: Int,
+ origAccess: Int,
name: String,
signature: String?,
superName: String?,
interfaces: Array<String>
) {
+ val access = modifyClassAccess(origAccess)
super.visit(version, access, name, signature, superName, interfaces)
classLoadHooks = filter.getClassLoadHooks(currentClassName)
@@ -375,53 +380,90 @@ class ImplGeneratingAdapter(
val callerMethodName: String,
next: MethodVisitor?,
) : MethodVisitor(OPCODE_VERSION, next) {
- override fun visitMethodInsn(
+
+ private fun doReplace(
opcode: Int,
- owner: String?,
- name: String?,
- descriptor: String?,
- isInterface: Boolean,
- ) {
+ owner: String,
+ name: String,
+ descriptor: String,
+ ): Boolean {
when (opcode) {
INVOKESTATIC, INVOKEVIRTUAL, INVOKEINTERFACE -> {}
- else -> {
- // Don't touch other opcodes.
- super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
- return
- }
+ // We only support INVOKESPECIAL when replacing constructors.
+ INVOKESPECIAL -> if (name != CTOR_NAME) return false
+ // Don't touch other opcodes.
+ else -> return false
}
+
val to = filter.getMethodCallReplaceTo(
- currentClassName, callerMethodName, owner!!, name!!, descriptor!!
+ currentClassName, callerMethodName, owner, name, descriptor
)
if (to == null
// Don't replace if the target is the callsite.
|| (to.className == currentClassName && to.methodName == callerMethodName)
) {
- super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
- return
+ return false
}
- // Replace the method call with a (static) call to the target method.
- // If it's a non-static call, the target method's first argument will receive "this".
- // (Because of that, we don't need to manipulate the stack. Just replace the
- // method call.)
+ if (opcode != INVOKESPECIAL) {
+ // It's either a static method call or virtual method call.
+ // Either way, we don't manipulate the stack and send the original arguments
+ // as is to the target method.
+ //
+ // If the call is a virtual call (INVOKEVIRTUAL or INVOKEINTERFACE), then
+ // the first argument in the stack is the "this" object, so the target
+ // method must have an extra argument as the first argument to receive it.
+ // We update the method descriptor with prependArgTypeToMethodDescriptor()
+ // to absorb this difference.
+
+ val toDesc = if (opcode == INVOKESTATIC) {
+ descriptor
+ } else {
+ prependArgTypeToMethodDescriptor(descriptor, owner)
+ }
- val toDesc = if (opcode == INVOKESTATIC) {
- // Static call to static call, no need to change the desc.
- descriptor
+ mv.visitMethodInsn(
+ INVOKESTATIC,
+ to.className,
+ to.methodName,
+ toDesc,
+ false
+ )
} else {
- // Need to prepend the "this" type to the descriptor.
- prependArgTypeToMethodDescriptor(descriptor, owner)
+ // Because an object initializer does not return a value, the newly created
+ // but uninitialized object will be dup-ed at the bottom of the stack.
+ // We first call the target method to consume the constructor arguments at the top.
+
+ val toDesc = changeMethodDescriptorReturnType(descriptor, owner)
+
+ // Before stack: { uninitialized, uninitialized, args... }
+ mv.visitMethodInsn(
+ INVOKESTATIC,
+ to.className,
+ to.methodName,
+ toDesc,
+ false
+ )
+ // After stack: { uninitialized, uninitialized, obj }
+
+ // Next we pop the 2 uninitialized instances out of the stack.
+ adjustStackForConstructorRedirection(mv)
}
- mv.visitMethodInsn(
- INVOKESTATIC,
- to.className,
- to.methodName,
- toDesc,
- false
- )
+ return true
+ }
+
+ override fun visitMethodInsn(
+ opcode: Int,
+ owner: String,
+ name: String,
+ descriptor: String,
+ isInterface: Boolean,
+ ) {
+ if (!doReplace(opcode, owner, name, descriptor)) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
+ }
}
}
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt
index de4cb0c536c1..8e41a87d349d 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt
@@ -1,29 +1,8 @@
-# Only classes listed here can use the hoststubgen annotations.
-
-# For each class, we check each item in this file, and when a match is found, we
-# either allow it if the line doesn't have a !, or disallow if the line has a !.
-# All the lines after the matching line will be ignored.
-
-
-# To allow a specific class to use annotations:
-# com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
-
-# To disallow a specific class to use annotations:
-# !com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
-
-# To allow a specific package to use annotations:
-# com.android.hoststubgen.test.*
-
-# To disallow a specific package to use annotations:
-# !com.android.hoststubgen.test.*
-
+# Policy file for "tiny-framework" used by hoststubgen's own tests.
com.android.hoststubgen.test.tinyframework.*
com.supported.*
com.unsupported.*
-# Use this to allow all packages
-# *
-
-# Use this to allow all packages
-# !* \ No newline at end of file
+# Disallow all other classes
+!* \ No newline at end of file
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
index b389a67a8e4c..23699fd1dba4 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
@@ -34,10 +34,10 @@ source "${0%/*}"/../common.sh
SCRIPT_NAME="${0##*/}"
-GOLDEN_DIR=golden-output
+GOLDEN_DIR=${GOLDEN_DIR:-golden-output}
mkdir -p $GOLDEN_DIR
-DIFF_CMD=${DIFF:-diff -u --ignore-blank-lines --ignore-space-change}
+DIFF_CMD=${DIFF_CMD:-./tiny-framework-dump-test.py run-diff}
update=0
three_way=0
@@ -62,12 +62,10 @@ done
shift $(($OPTIND - 1))
# Build the dump files, which are the input of this test.
-run m dump-jar tiny-framework-dump-test
-
+run ${BUILD_CMD:-m} dump-jar tiny-framework-dump-test
# Get the path to the generate text files. (not the golden files.)
# We get them from $OUT/module-info.json
-
files=(
$(python3 -c '
import sys
@@ -77,7 +75,7 @@ import json
with open(sys.argv[1], "r") as f:
data = json.load(f)
- # Equivalent to: jq -r '.["tiny-framework-dump-test"]["installed"][]'
+ # Equivalent to: jq -r '.["tiny-framework-dump-test"]["installed"][]'
for path in data["tiny-framework-dump-test"]["installed"]:
if "golden-output" in path:
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
index 5e5ca62b49f0..2b942a91a8f8 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -7,6 +7,8 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -30,6 +32,8 @@ public interface android.hosttest.annotation.HostSideTestIgnore extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestIgnore
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestIgnore.java"
RuntimeVisibleAnnotations:
@@ -50,6 +54,8 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -61,6 +67,28 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -70,6 +98,8 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -90,6 +120,8 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -113,6 +145,8 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -133,6 +167,8 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -153,6 +189,8 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -176,6 +214,8 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -196,6 +236,8 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -216,6 +258,8 @@ public interface android.hosttest.annotation.tests.HostSideTestSuppress extends
this_class: #x // android/hosttest/annotation/tests/HostSideTestSuppress
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestSuppress.java"
RuntimeVisibleAnnotations:
@@ -232,6 +276,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -273,6 +319,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -314,6 +362,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 3
+Constant pool:
+{
}
SourceFile: "IPretendingAidl.java"
NestMembers:
@@ -331,6 +381,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -376,6 +428,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.R();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -396,13 +450,15 @@ InnerClasses:
public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
Compiled from "TinyFrameworkAnnotations.java"
-public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
minor version: 0
major version: 65
- flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ flags: (0x0031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 9, attributes: 2
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -433,9 +489,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
x: #x()
android.hosttest.annotation.HostSideTestKeep
- public int addOne(int);
+ public final int addOne(int);
descriptor: (I)I
- flags: (0x0001) ACC_PUBLIC
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
Code:
stack=2, locals=2, args_size=2
x: iload_1
@@ -505,18 +561,18 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
0 4 1 value I
- public static native int nativeAddThree(int);
+ public static final native int nativeAddThree(int);
descriptor: (I)I
- flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ flags: (0x0119) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_NATIVE
RuntimeInvisibleAnnotations:
x: #x(#x=s#x)
android.hosttest.annotation.HostSideTestSubstitute(
suffix="_host"
)
- private static int nativeAddThree_host(int);
+ private static final int nativeAddThree_host(int);
descriptor: (I)I
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
Code:
stack=2, locals=1, args_size=1
x: iload_0
@@ -578,6 +634,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 2
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -640,6 +698,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 6, attributes: 2
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -764,6 +824,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 2
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -818,6 +880,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 2
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -878,6 +942,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 3
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1081,6 +1147,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 3
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1202,6 +1270,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1256,6 +1326,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 17, attributes: 1
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1507,6 +1579,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1661,6 +1735,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1807,6 +1883,42 @@ BootstrapMethods:
InnerClasses:
public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 0 10 1 i I
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -1815,7 +1927,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 3
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1859,10 +1973,28 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
Start Length Slot Name Signature
0 4 0 a I
0 4 1 b I
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 i I
}
SourceFile: "TinyFrameworkMethodCallReplace.java"
NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
Compiled from "TinyFrameworkMethodCallReplace.java"
@@ -1872,7 +2004,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 5, attributes: 5
+ interfaces: 0, fields: 0, methods: 6, attributes: 5
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1928,6 +2062,21 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: ireturn
LineNumberTable:
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 i I
+
private static int originalAdd(int, int);
descriptor: (II)I
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -1966,6 +2115,7 @@ RuntimeInvisibleAnnotations:
android.hosttest.annotation.HostSideTestWholeClassKeep
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
BootstrapMethods:
x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
@@ -1973,8 +2123,9 @@ BootstrapMethods:
#x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
#x ()V
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
- public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -1984,6 +2135,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 14, attributes: 2
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2157,6 +2310,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 7, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2263,6 +2418,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
flags: (0x0000)
@@ -2321,6 +2478,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
descriptor: ()V
flags: (0x0000)
@@ -2375,6 +2534,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
flags: (0x0000)
@@ -2433,6 +2594,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
descriptor: ()V
flags: (0x0000)
@@ -2487,6 +2650,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2521,6 +2686,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2558,6 +2725,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
descriptor: ()V
flags: (0x0000)
@@ -2613,6 +2782,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2647,6 +2818,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2694,6 +2867,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -2723,6 +2898,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 4
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2827,6 +3004,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2860,6 +3039,228 @@ SourceFile: "TinyFrameworkPackageRedirect.java"
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // NoAnnotations=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartialWithWholeClass_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted;
+
+ public static int foo1(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad;
+
+ public static int foo1(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlistedWithoutAnnot_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // NoAnnotations=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartiallyAllowlistedWithoutAnnot_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartialWithWholeClass_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -2868,7 +3269,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 2, attributes: 2
+ interfaces: 0, fields: 0, methods: 3, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2897,6 +3300,22 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 value I
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 value I
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeInvisibleAnnotations:
@@ -2910,7 +3329,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 2, attributes: 2
+ interfaces: 0, fields: 1, methods: 3, attributes: 2
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -2944,6 +3365,26 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: iconst_1
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 16 0 value I
}
SourceFile: "TinyFrameworkToBeRenamed.java"
RuntimeInvisibleAnnotations:
@@ -2958,6 +3399,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.A();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2981,6 +3424,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.B
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/B
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.B();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3004,6 +3449,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.sub.A();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3027,6 +3474,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.B
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/B
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.sub.B();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3050,6 +3499,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3073,6 +3524,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3096,6 +3549,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3119,6 +3574,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.CA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3142,6 +3599,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.CB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3165,6 +3624,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3188,6 +3649,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3211,6 +3674,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3234,6 +3699,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3257,6 +3724,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3280,6 +3749,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3303,6 +3774,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3326,6 +3799,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3349,6 +3824,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3372,6 +3849,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3395,6 +3874,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3418,6 +3899,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3441,6 +3924,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3464,6 +3949,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3487,6 +3974,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3510,6 +3999,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3533,6 +4024,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_None
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_None
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_None();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3556,6 +4049,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I1.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
@@ -3567,6 +4062,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I2.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
@@ -3578,6 +4075,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I3.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
@@ -3589,6 +4088,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "IA.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
@@ -3600,6 +4101,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "IB.java"
## Class: com/supported/UnsupportedClass.class
@@ -3611,6 +4114,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 2
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3658,6 +4163,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.unsupported.UnsupportedClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
index 84a8373008d7..d493ad152225 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/03-hoststubgen-test-tiny-framework-host-dump.txt
@@ -7,6 +7,8 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -35,6 +37,8 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -48,6 +52,30 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -57,6 +85,8 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -79,6 +109,8 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -107,6 +139,8 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -129,6 +163,8 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -151,6 +187,8 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -179,6 +217,8 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -201,6 +241,8 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -223,6 +265,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -273,6 +317,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -323,6 +369,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 4
+Constant pool:
+{
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
@@ -343,6 +391,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -400,6 +450,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.R();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -433,6 +485,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 7, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -591,6 +645,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -668,6 +724,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 4, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -768,6 +826,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 0, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -805,6 +865,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -867,6 +929,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1112,6 +1176,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1260,6 +1326,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1323,6 +1391,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 2
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1562,6 +1632,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1749,6 +1821,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1928,6 +2002,51 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 0 10 1 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -1936,7 +2055,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 4
+ interfaces: 0, fields: 0, methods: 4, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1989,9 +2110,30 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
- public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
SourceFile: "TinyFrameworkMethodCallReplace.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -2005,7 +2147,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 4, attributes: 6
+ interfaces: 0, fields: 0, methods: 6, attributes: 6
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2070,6 +2214,48 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.newConstructorTester:(I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: swap
+ x: pop
+ x: swap
+ x: pop
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 13 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static int originalAdd(int, int);
+ descriptor: (II)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: iconst_1
+ x: isub
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 a I
+ 0 6 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
@@ -2089,6 +2275,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
SourceFile: "TinyFrameworkMethodCallReplace.java"
@@ -2106,6 +2293,7 @@ BootstrapMethods:
#x ()V
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -2115,6 +2303,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 14, attributes: 3
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2373,6 +2563,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 7, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2503,6 +2695,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
flags: (0x0000)
@@ -2573,6 +2767,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
descriptor: ()V
flags: (0x0000)
@@ -2639,6 +2835,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
flags: (0x0000)
@@ -2709,6 +2907,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
descriptor: ()V
flags: (0x0000)
@@ -2775,6 +2975,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2818,6 +3020,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2864,6 +3068,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
descriptor: ()V
flags: (0x0000)
@@ -2931,6 +3137,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2974,6 +3182,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3033,6 +3243,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -3068,6 +3280,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -3193,6 +3407,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3235,6 +3451,49 @@ RuntimeVisibleAnnotations:
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 5
+Constant pool:
+{
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -3243,7 +3502,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 2, attributes: 3
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3278,6 +3539,25 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeVisibleAnnotations:
@@ -3295,6 +3575,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "A.java"
RuntimeVisibleAnnotations:
@@ -3309,6 +3591,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "A.java"
RuntimeVisibleAnnotations:
@@ -3323,6 +3607,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C1.java"
RuntimeVisibleAnnotations:
@@ -3337,6 +3623,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C2.java"
RuntimeVisibleAnnotations:
@@ -3351,6 +3639,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C3.java"
RuntimeVisibleAnnotations:
@@ -3365,6 +3655,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "CA.java"
RuntimeVisibleAnnotations:
@@ -3379,6 +3671,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "CB.java"
RuntimeVisibleAnnotations:
@@ -3393,6 +3687,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C1.java"
RuntimeVisibleAnnotations:
@@ -3407,6 +3703,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C2.java"
RuntimeVisibleAnnotations:
@@ -3421,6 +3719,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C3.java"
RuntimeVisibleAnnotations:
@@ -3435,6 +3735,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I1.java"
RuntimeVisibleAnnotations:
@@ -3449,6 +3751,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I1_IA.java"
RuntimeVisibleAnnotations:
@@ -3463,6 +3767,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I2.java"
RuntimeVisibleAnnotations:
@@ -3477,6 +3783,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I3.java"
RuntimeVisibleAnnotations:
@@ -3491,6 +3799,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I1.java"
RuntimeVisibleAnnotations:
@@ -3505,6 +3815,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I2.java"
RuntimeVisibleAnnotations:
@@ -3519,6 +3831,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I3.java"
RuntimeVisibleAnnotations:
@@ -3533,6 +3847,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "IA.java"
RuntimeVisibleAnnotations:
@@ -3547,6 +3863,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "IB.java"
RuntimeVisibleAnnotations:
@@ -3561,6 +3879,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3620,6 +3940,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.unsupported.UnsupportedClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -3674,7 +3996,9 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 2, attributes: 3
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3696,7 +4020,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
0 10 1 value I
RuntimeVisibleAnnotations:
x: #x()
@@ -3713,7 +4037,30 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: iconst_1
+ x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 16 0 value I
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
index 49769e648bbf..8978a7acefd8 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output.RELEASE_TARGET_JAVA_21/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -6,17 +6,9 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -44,16 +36,9 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -67,6 +52,30 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 65
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -75,16 +84,9 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirect
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -106,17 +108,9 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirectionClass
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -144,16 +138,9 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -175,16 +162,9 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -206,17 +186,9 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -244,16 +216,9 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -275,16 +240,9 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -307,6 +265,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -377,6 +337,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -447,6 +409,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -476,6 +440,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -546,6 +512,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -594,6 +562,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 7, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -785,6 +755,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -880,6 +852,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 5, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1010,6 +984,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 0, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1047,6 +1023,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1117,6 +1095,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1400,6 +1380,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1576,6 +1558,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -1659,6 +1643,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 2
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1971,6 +1957,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2201,6 +2189,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2423,6 +2413,66 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 11 10 1 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -2431,7 +2481,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 4, attributes: 4
+ interfaces: 0, fields: 0, methods: 5, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2509,8 +2561,34 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String newConstructorTester
+ x: ldc #x // String (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
SourceFile: "TinyFrameworkMethodCallReplace.java"
RuntimeVisibleAnnotations:
@@ -2525,7 +2603,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 5, attributes: 6
+ interfaces: 0, fields: 0, methods: 7, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2615,18 +2695,70 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String constructorReplaceTester
+ x: ldc #x // String (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.newConstructorTester:(I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: swap
+ x: pop
+ x: swap
+ x: pop
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 13 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static int originalAdd(int, int);
+ descriptor: (II)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String originalAdd
+ x: ldc #x // String (II)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: iconst_1
+ x: isub
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 a I
+ 11 6 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=4, locals=1, args_size=1
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
- x: ldc #x // String lambda$nonStaticMethodCallReplaceTester$0
- x: ldc #x // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ x: ldc #x // String lambda$nonStaticMethodCallReplaceTester$0
+ x: ldc #x // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
x: aload_0
- x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+ x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
x: invokevirtual #x // Method java/lang/Thread.isDaemon:()Z
x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
x: return
@@ -2639,6 +2771,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
SourceFile: "TinyFrameworkMethodCallReplace.java"
@@ -2656,6 +2789,7 @@ BootstrapMethods:
#x ()V
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -2665,6 +2799,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 3
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2998,6 +3134,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 8, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3173,6 +3311,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3268,6 +3408,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3359,6 +3501,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3454,6 +3598,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3545,6 +3691,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3603,6 +3751,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3664,6 +3814,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3756,6 +3908,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3814,6 +3968,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3893,6 +4049,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3943,6 +4101,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -4091,6 +4251,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4153,6 +4315,64 @@ RuntimeVisibleAnnotations:
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 65
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 5
+Constant pool:
+{
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ x: ldc #x // String foo2
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -4161,7 +4381,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 3
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4216,6 +4438,30 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ x: ldc #x // String bar
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeVisibleAnnotations:
@@ -4233,6 +4479,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4256,6 +4504,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4279,6 +4529,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4302,6 +4554,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4325,6 +4579,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4348,6 +4604,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4371,6 +4629,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4394,6 +4654,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4417,6 +4679,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4440,6 +4704,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4463,6 +4729,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4486,6 +4754,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4509,6 +4779,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4532,6 +4804,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4555,6 +4829,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4578,6 +4854,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4601,6 +4879,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4624,6 +4904,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4647,6 +4929,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4670,6 +4954,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -4749,6 +5035,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4823,7 +5111,9 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 3, attributes: 3
+ interfaces: 0, fields: 1, methods: 4, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -4836,8 +5126,8 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=0, args_size=0
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
x: return
@@ -4846,7 +5136,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=2, args_size=2
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
x: ldc #x // String <init>
x: ldc #x // String (I)V
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -4860,7 +5150,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 11 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
11 10 1 value I
RuntimeVisibleAnnotations:
x: #x()
@@ -4871,7 +5161,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
x: ldc #x // String getValue
x: ldc #x // String ()I
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -4882,7 +5172,35 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 11 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String getArray
+ x: ldc #x // String (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 16 0 value I
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
index 103e152c7e39..406c61138705 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -7,6 +7,8 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -30,6 +32,8 @@ public interface android.hosttest.annotation.HostSideTestIgnore extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestIgnore
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestIgnore.java"
RuntimeVisibleAnnotations:
@@ -50,6 +54,8 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -61,6 +67,28 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -70,6 +98,8 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -90,6 +120,8 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -113,6 +145,8 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -133,6 +167,8 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -153,6 +189,8 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -176,6 +214,8 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -196,6 +236,8 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -216,6 +258,8 @@ public interface android.hosttest.annotation.tests.HostSideTestSuppress extends
this_class: #x // android/hosttest/annotation/tests/HostSideTestSuppress
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestSuppress.java"
RuntimeVisibleAnnotations:
@@ -232,6 +276,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -273,6 +319,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -314,6 +362,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 3
+Constant pool:
+{
}
SourceFile: "IPretendingAidl.java"
NestMembers:
@@ -331,6 +381,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -376,6 +428,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.R();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -396,13 +450,15 @@ InnerClasses:
public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/R$Nested of class com/android/hoststubgen/test/tinyframework/R
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.class
Compiled from "TinyFrameworkAnnotations.java"
-public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
minor version: 0
major version: 61
- flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ flags: (0x0031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 9, attributes: 2
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -433,9 +489,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
x: #x()
android.hosttest.annotation.HostSideTestKeep
- public int addOne(int);
+ public final int addOne(int);
descriptor: (I)I
- flags: (0x0001) ACC_PUBLIC
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
Code:
stack=2, locals=2, args_size=2
x: iload_1
@@ -505,18 +561,18 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations;
0 4 1 value I
- public static native int nativeAddThree(int);
+ public static final native int nativeAddThree(int);
descriptor: (I)I
- flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ flags: (0x0119) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_NATIVE
RuntimeInvisibleAnnotations:
x: #x(#x=s#x)
android.hosttest.annotation.HostSideTestSubstitute(
suffix="_host"
)
- private static int nativeAddThree_host(int);
+ private static final int nativeAddThree_host(int);
descriptor: (I)I
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
Code:
stack=2, locals=1, args_size=1
x: iload_0
@@ -578,6 +634,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 2
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -640,6 +698,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 6, attributes: 2
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -764,6 +824,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 2
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -818,6 +880,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 2
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -878,6 +942,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 3
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1081,6 +1147,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 3
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1202,6 +1270,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1256,6 +1326,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 17, attributes: 1
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1507,6 +1579,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1661,6 +1735,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1807,6 +1883,42 @@ BootstrapMethods:
InnerClasses:
public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 0 10 1 i I
+}
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -1815,7 +1927,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 3
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1859,10 +1973,28 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
Start Length Slot Name Signature
0 4 0 a I
0 4 1 b I
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 i I
}
SourceFile: "TinyFrameworkMethodCallReplace.java"
NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.class
Compiled from "TinyFrameworkMethodCallReplace.java"
@@ -1872,7 +2004,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 5, attributes: 5
+ interfaces: 0, fields: 0, methods: 6, attributes: 5
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1928,6 +2062,21 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: ireturn
LineNumberTable:
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 i I
+
private static int originalAdd(int, int);
descriptor: (II)I
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -1966,6 +2115,7 @@ RuntimeInvisibleAnnotations:
android.hosttest.annotation.HostSideTestWholeClassKeep
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
BootstrapMethods:
x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
@@ -1973,8 +2123,9 @@ BootstrapMethods:
#x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.lambda$nonStaticMethodCallReplaceTester$0:(Ljava/util/concurrent/atomic/AtomicBoolean;)V
#x ()V
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
- public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -1984,6 +2135,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 14, attributes: 2
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2157,6 +2310,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 7, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2263,6 +2418,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 3, attributes: 5
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -2328,6 +2485,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
descriptor: ()V
flags: (0x0000)
@@ -2382,6 +2541,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 3, attributes: 5
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -2447,6 +2608,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
descriptor: ()V
flags: (0x0000)
@@ -2501,6 +2664,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2535,6 +2700,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2579,6 +2746,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 5
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
descriptor: ()V
flags: (0x0000)
@@ -2634,6 +2803,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2668,6 +2839,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2715,6 +2888,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -2744,6 +2919,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 4
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2848,6 +3025,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2881,6 +3060,228 @@ SourceFile: "TinyFrameworkPackageRedirect.java"
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$NoAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // NoAnnotations=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartialWithWholeClass_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted;
+
+ public static int foo1(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad;
+
+ public static int foo1(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlistedWithoutAnnot_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+Constant pool:
+{
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted;
+}
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+InnerClasses:
+ public static #x= #x of #x; // NoAnnotations=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$NoAnnotations of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartiallyAllowlistedWithoutAnnot_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartialWithWholeClass_bad=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -2889,7 +3290,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 2, attributes: 2
+ interfaces: 0, fields: 0, methods: 3, attributes: 2
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2918,6 +3321,22 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 value I
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 value I
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeInvisibleAnnotations:
@@ -2931,7 +3350,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 2, attributes: 2
+ interfaces: 0, fields: 1, methods: 3, attributes: 2
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -2965,6 +3386,26 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: iconst_1
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 16 0 value I
}
SourceFile: "TinyFrameworkToBeRenamed.java"
RuntimeInvisibleAnnotations:
@@ -2979,6 +3420,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.A();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3002,6 +3445,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.B
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/B
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.B();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3025,6 +3470,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.sub.A();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3048,6 +3495,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.B
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/B
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.packagetest.sub.B();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3071,6 +3520,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3094,6 +3545,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3117,6 +3570,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.C3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3140,6 +3595,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.CA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3163,6 +3620,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.CB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3186,6 +3645,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3209,6 +3670,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3232,6 +3695,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3255,6 +3720,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CA
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3278,6 +3745,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3301,6 +3770,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_CB_IA
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_CB_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3324,6 +3795,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3347,6 +3820,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3370,6 +3845,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3393,6 +3870,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3416,6 +3895,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3439,6 +3920,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3462,6 +3945,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I1
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I1();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3485,6 +3970,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IA_I3
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IA_I3();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3508,6 +3995,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3531,6 +4020,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_IB_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_IB_IA();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3554,6 +4045,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_None
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_None
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 1
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.subclasstest.Class_None();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3577,6 +4070,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I1.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I2.class
@@ -3588,6 +4083,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I2.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/I3.class
@@ -3599,6 +4096,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "I3.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IA.class
@@ -3610,6 +4109,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "IA.java"
## Class: com/android/hoststubgen/test/tinyframework/subclasstest/IB.class
@@ -3621,6 +4122,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 1
+Constant pool:
+{
}
SourceFile: "IB.java"
## Class: com/supported/UnsupportedClass.class
@@ -3632,6 +4135,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 2
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3679,6 +4184,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 2
+Constant pool:
+{
public com.unsupported.UnsupportedClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt
index eeec554e954c..6a8e4885d1d0 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-dump.txt
@@ -7,6 +7,8 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -35,6 +37,8 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -48,6 +52,30 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -57,6 +85,8 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -79,6 +109,8 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -107,6 +139,8 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -129,6 +163,8 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -151,6 +187,8 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -179,6 +217,8 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -201,6 +241,8 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -223,6 +265,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Proxy();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -273,6 +317,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -323,6 +369,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 4
+Constant pool:
+{
}
InnerClasses:
public static #x= #x of #x; // Stub=class com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub of class com/android/hoststubgen/test/tinyframework/IPretendingAidl
@@ -343,6 +391,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -400,6 +450,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.R();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -433,6 +485,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 7, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -591,6 +645,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -668,6 +724,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 4, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -768,6 +826,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 0, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -805,6 +865,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -867,6 +929,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1112,6 +1176,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1260,6 +1326,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1323,6 +1391,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 2
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1562,6 +1632,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1749,6 +1821,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -1928,6 +2002,51 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 0 10 1 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -1936,7 +2055,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 4
+ interfaces: 0, fields: 0, methods: 4, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -1989,9 +2110,30 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
- public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
SourceFile: "TinyFrameworkMethodCallReplace.java"
RuntimeVisibleAnnotations:
x: #x()
@@ -2005,7 +2147,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 4, attributes: 6
+ interfaces: 0, fields: 0, methods: 6, attributes: 6
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2070,6 +2214,48 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.newConstructorTester:(I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: swap
+ x: pop
+ x: swap
+ x: pop
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 13 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static int originalAdd(int, int);
+ descriptor: (II)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: iconst_1
+ x: isub
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 a I
+ 0 6 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
@@ -2089,6 +2275,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
SourceFile: "TinyFrameworkMethodCallReplace.java"
@@ -2106,6 +2293,7 @@ BootstrapMethods:
#x ()V
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -2115,6 +2303,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 14, attributes: 3
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2373,6 +2563,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 7, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -2503,6 +2695,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 3, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -2583,6 +2777,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
descriptor: ()V
flags: (0x0000)
@@ -2649,6 +2845,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 3, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -2729,6 +2927,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
descriptor: ()V
flags: (0x0000)
@@ -2795,6 +2995,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2838,6 +3040,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -2894,6 +3098,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 3, attributes: 6
+Constant pool:
+{
com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
descriptor: ()V
flags: (0x0000)
@@ -2961,6 +3167,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 1, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3004,6 +3212,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3063,6 +3273,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -3098,6 +3310,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -3223,6 +3437,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3265,6 +3481,49 @@ RuntimeVisibleAnnotations:
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 1, attributes: 5
+Constant pool:
+{
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -3273,7 +3532,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 2, attributes: 3
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
public com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
@@ -3308,6 +3569,25 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeVisibleAnnotations:
@@ -3325,6 +3605,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "A.java"
RuntimeVisibleAnnotations:
@@ -3339,6 +3621,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "A.java"
RuntimeVisibleAnnotations:
@@ -3353,6 +3637,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C1.java"
RuntimeVisibleAnnotations:
@@ -3367,6 +3653,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C2.java"
RuntimeVisibleAnnotations:
@@ -3381,6 +3669,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "C3.java"
RuntimeVisibleAnnotations:
@@ -3395,6 +3685,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "CA.java"
RuntimeVisibleAnnotations:
@@ -3409,6 +3701,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "CB.java"
RuntimeVisibleAnnotations:
@@ -3423,6 +3717,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C1.java"
RuntimeVisibleAnnotations:
@@ -3437,6 +3733,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C2.java"
RuntimeVisibleAnnotations:
@@ -3451,6 +3749,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_C3.java"
RuntimeVisibleAnnotations:
@@ -3465,6 +3765,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I1.java"
RuntimeVisibleAnnotations:
@@ -3479,6 +3781,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I1_IA.java"
RuntimeVisibleAnnotations:
@@ -3493,6 +3797,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I2.java"
RuntimeVisibleAnnotations:
@@ -3507,6 +3813,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "Class_I3.java"
RuntimeVisibleAnnotations:
@@ -3521,6 +3829,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I1.java"
RuntimeVisibleAnnotations:
@@ -3535,6 +3845,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I2.java"
RuntimeVisibleAnnotations:
@@ -3549,6 +3861,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "I3.java"
RuntimeVisibleAnnotations:
@@ -3563,6 +3877,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "IA.java"
RuntimeVisibleAnnotations:
@@ -3577,6 +3893,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "IB.java"
RuntimeVisibleAnnotations:
@@ -3591,6 +3909,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3650,6 +3970,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 3
+Constant pool:
+{
public com.unsupported.UnsupportedClass(int);
descriptor: (I)V
flags: (0x0001) ACC_PUBLIC
@@ -3704,7 +4026,9 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 2, attributes: 3
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -3726,7 +4050,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
0 10 1 value I
RuntimeVisibleAnnotations:
x: #x()
@@ -3743,7 +4067,30 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 0 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: iconst_1
+ x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 16 0 value I
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
index 0f8af92dc486..d8e76321b038 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-dump.txt
@@ -6,17 +6,9 @@ public interface android.hosttest.annotation.HostSideTestClassLoadHook extends j
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -44,16 +36,9 @@ public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestKeep.java"
RuntimeVisibleAnnotations:
@@ -67,6 +52,30 @@ RuntimeVisibleAnnotations:
java.lang.annotation.Retention(
value=Ljava/lang/annotation/RetentionPolicy;.CLASS
)
+## Class: android/hosttest/annotation/HostSideTestPartiallyAllowlisted.class
+ Compiled from "HostSideTestPartiallyAllowlisted.java"
+public interface android.hosttest.annotation.HostSideTestPartiallyAllowlisted extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestPartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
+}
+SourceFile: "HostSideTestPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
## Class: android/hosttest/annotation/HostSideTestRedirect.class
Compiled from "HostSideTestRedirect.java"
public interface android.hosttest.annotation.HostSideTestRedirect extends java.lang.annotation.Annotation
@@ -75,16 +84,9 @@ public interface android.hosttest.annotation.HostSideTestRedirect extends java.l
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirect
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirect
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRedirect.java"
RuntimeVisibleAnnotations:
@@ -106,17 +108,9 @@ public interface android.hosttest.annotation.HostSideTestRedirectionClass extend
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRedirectionClass
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRedirectionClass
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String value();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -144,16 +138,9 @@ public interface android.hosttest.annotation.HostSideTestRemove extends java.lan
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestRemove
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestRemove.java"
RuntimeVisibleAnnotations:
@@ -175,16 +162,9 @@ public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep e
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestStaticInitializerKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestStaticInitializerKeep.java"
RuntimeVisibleAnnotations:
@@ -206,17 +186,9 @@ public interface android.hosttest.annotation.HostSideTestSubstitute extends java
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 2, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
-
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
public abstract java.lang.String suffix();
descriptor: ()Ljava/lang/String;
flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
@@ -244,16 +216,9 @@ public interface android.hosttest.annotation.HostSideTestThrow extends java.lang
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestThrow
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestThrow.java"
RuntimeVisibleAnnotations:
@@ -275,16 +240,9 @@ public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends
flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
super_class: #x // java/lang/Object
- interfaces: 1, fields: 0, methods: 1, attributes: 2
- private static {};
- descriptor: ()V
- flags: (0x000a) ACC_PRIVATE, ACC_STATIC
- Code:
- stack=2, locals=0, args_size=0
- x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
- x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
- x: return
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+Constant pool:
+{
}
SourceFile: "HostSideTestWholeClassKeep.java"
RuntimeVisibleAnnotations:
@@ -307,6 +265,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub$Pro
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub$Proxy
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -377,6 +337,8 @@ public class com.android.hoststubgen.test.tinyframework.IPretendingAidl$Stub
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl$Stub
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -447,6 +409,8 @@ public interface com.android.hoststubgen.test.tinyframework.IPretendingAidl
this_class: #x // com/android/hoststubgen/test/tinyframework/IPretendingAidl
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -476,6 +440,8 @@ public class com.android.hoststubgen.test.tinyframework.R$Nested
this_class: #x // com/android/hoststubgen/test/tinyframework/R$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public static int[] ARRAY;
descriptor: [I
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -546,6 +512,8 @@ public class com.android.hoststubgen.test.tinyframework.R
this_class: #x // com/android/hoststubgen/test/tinyframework/R
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -594,6 +562,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkAnnotations
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 7, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -785,6 +755,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHo
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
descriptor: Ljava/util/Set;
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
@@ -880,6 +852,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWideAn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWideAnnotations
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 5, attributes: 3
+Constant pool:
+{
public int keep;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1010,6 +984,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 0, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1047,6 +1023,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithIn
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 1, attributes: 3
+Constant pool:
+{
public static boolean sInitialized;
descriptor: Z
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
@@ -1117,6 +1095,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumC
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
super_class: #x // java/lang/Enum
interfaces: 0, fields: 6, methods: 7, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1400,6 +1380,8 @@ public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumS
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
super_class: #x // java/lang/Enum
interfaces: 0, fields: 3, methods: 5, attributes: 4
+Constant pool:
+{
public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
@@ -1576,6 +1558,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTe
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -1659,6 +1643,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPoli
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 2
+Constant pool:
+{
public int stub;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -1971,6 +1957,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nes
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2201,6 +2189,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 8, attributes: 6
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -2423,6 +2413,66 @@ BootstrapMethods:
#x ()Ljava/lang/Integer;
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester.class
+ Compiled from "TinyFrameworkMethodCallReplace.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
+ public int i;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field i:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ 11 10 1 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+SourceFile: "TinyFrameworkMethodCallReplace.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.class
Compiled from "TinyFrameworkMethodCallReplace.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo
@@ -2431,7 +2481,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 4, attributes: 4
+ interfaces: 0, fields: 0, methods: 5, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2509,8 +2561,34 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester newConstructorTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ x: ldc #x // String newConstructorTester
+ x: ldc #x // String (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: iconst_1
+ x: iadd
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester."<init>":(I)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
SourceFile: "TinyFrameworkMethodCallReplace.java"
RuntimeVisibleAnnotations:
@@ -2525,7 +2603,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 5, attributes: 6
+ interfaces: 0, fields: 0, methods: 7, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -2615,18 +2695,70 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester constructorReplaceTester(int);
+ descriptor: (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String constructorReplaceTester
+ x: ldc #x // String (I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
+ x: dup
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo.newConstructorTester:(I)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester;
+ x: swap
+ x: pop
+ x: swap
+ x: pop
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 13 0 i I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ private static int originalAdd(int, int);
+ descriptor: (II)I
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
+ x: ldc #x // String originalAdd
+ x: ldc #x // String (II)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iload_1
+ x: iadd
+ x: iconst_1
+ x: isub
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 a I
+ 11 6 1 b I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
private static void lambda$nonStaticMethodCallReplaceTester$0(java.util.concurrent.atomic.AtomicBoolean);
descriptor: (Ljava/util/concurrent/atomic/AtomicBoolean;)V
flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=4, locals=1, args_size=1
x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
- x: ldc #x // String lambda$nonStaticMethodCallReplaceTester$0
- x: ldc #x // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
+ x: ldc #x // String lambda$nonStaticMethodCallReplaceTester$0
+ x: ldc #x // String (Ljava/util/concurrent/atomic/AtomicBoolean;)V
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
x: aload_0
- x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
+ x: invokestatic #x // Method java/lang/Thread.currentThread:()Ljava/lang/Thread;
x: invokevirtual #x // Method java/lang/Thread.isDaemon:()Z
x: invokevirtual #x // Method java/util/concurrent/atomic/AtomicBoolean.set:(Z)V
x: return
@@ -2639,6 +2771,7 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallR
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
InnerClasses:
+ public static #x= #x of #x; // ConstructorTester=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static #x= #x of #x; // ReplaceTo=class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo of class com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace
public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
SourceFile: "TinyFrameworkMethodCallReplace.java"
@@ -2656,6 +2789,7 @@ BootstrapMethods:
#x ()V
NestMembers:
com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ReplaceTo
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace$ConstructorTester
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
Compiled from "TinyFrameworkNative.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
@@ -2665,6 +2799,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 15, attributes: 3
+Constant pool:
+{
int value;
descriptor: I
flags: (0x0000)
@@ -2998,6 +3134,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 8, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3173,6 +3311,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 4, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -3278,6 +3418,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3369,6 +3511,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
super_class: #x // java/lang/Object
interfaces: 1, fields: 1, methods: 4, attributes: 6
+Constant pool:
+{
final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
@@ -3474,6 +3618,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3565,6 +3711,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3623,6 +3771,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3694,6 +3844,8 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$Stat
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 4, attributes: 6
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3786,6 +3938,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$Double$NestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 2, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3844,6 +3998,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 4
+Constant pool:
+{
public int value;
descriptor: I
flags: (0x0001) ACC_PUBLIC
@@ -3923,6 +4079,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
interfaces: 0, fields: 0, methods: 2, attributes: 4
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -3973,6 +4131,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClass
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
super_class: #x // java/lang/Object
interfaces: 0, fields: 2, methods: 4, attributes: 5
+Constant pool:
+{
public final java.util.function.Supplier<java.lang.Integer> mSupplier;
descriptor: Ljava/util/function/Supplier;
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
@@ -4121,6 +4281,8 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedi
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4183,6 +4345,64 @@ RuntimeVisibleAnnotations:
RuntimeInvisibleAnnotations:
x: #x()
android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted.class
+ Compiled from "TinyFrameworkPartiallyAllowlisted.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 5
+Constant pool:
+{
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public static int foo2(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted
+ x: ldc #x // String foo2
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+}
+InnerClasses:
+ public static #x= #x of #x; // PartiallyAllowlisted=class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted of class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
+SourceFile: "TinyFrameworkPartiallyAllowlisted.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestPartiallyAllowlisted
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted
## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.class
Compiled from "TinyFrameworkRenamedClassCaller.java"
public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClassCaller
@@ -4191,7 +4411,9 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
super_class: #x // java/lang/Object
- interfaces: 0, fields: 0, methods: 3, attributes: 3
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4246,6 +4468,30 @@ public class com.android.hoststubgen.test.tinyframework.TinyFrameworkRenamedClas
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static int bar(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller
+ x: ldc #x // String bar
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: invokestatic #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getArray:(I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: iconst_0
+ x: aaload
+ x: invokevirtual #x // Method rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 value I
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
}
SourceFile: "TinyFrameworkRenamedClassCaller.java"
RuntimeVisibleAnnotations:
@@ -4263,6 +4509,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4286,6 +4534,8 @@ public class com.android.hoststubgen.test.tinyframework.packagetest.sub.A
this_class: #x // com/android/hoststubgen/test/tinyframework/packagetest/sub/A
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4309,6 +4559,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4332,6 +4584,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C2 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4355,6 +4609,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.C3 extends
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4378,6 +4634,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4401,6 +4659,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.CB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/CB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4424,6 +4684,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C1 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C1
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C1
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4447,6 +4709,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C2 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C2
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C2
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4470,6 +4734,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_C3 ex
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_C3
super_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/C3
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4493,6 +4759,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4516,6 +4784,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I1_IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I1_IA
super_class: #x // java/lang/Object
interfaces: 2, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4539,6 +4809,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I2 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4562,6 +4834,8 @@ public class com.android.hoststubgen.test.tinyframework.subclasstest.Class_I3 im
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/Class_I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4585,6 +4859,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I1
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I1
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4608,6 +4884,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I2 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I2
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4631,6 +4909,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.I3 exte
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/I3
super_class: #x // java/lang/Object
interfaces: 1, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4654,6 +4934,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IA
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IA
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4677,6 +4959,8 @@ public interface com.android.hoststubgen.test.tinyframework.subclasstest.IB
this_class: #x // com/android/hoststubgen/test/tinyframework/subclasstest/IB
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 1, attributes: 2
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4700,6 +4984,8 @@ public class com.supported.UnsupportedClass
this_class: #x // com/supported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 1, methods: 3, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -4779,6 +5065,8 @@ public class com.unsupported.UnsupportedClass
this_class: #x // com/unsupported/UnsupportedClass
super_class: #x // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
+Constant pool:
+{
private static {};
descriptor: ()V
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
@@ -4853,7 +5141,9 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #x // rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
super_class: #x // java/lang/Object
- interfaces: 0, fields: 1, methods: 3, attributes: 3
+ interfaces: 0, fields: 1, methods: 4, attributes: 3
+Constant pool:
+{
private final int mValue;
descriptor: I
flags: (0x0012) ACC_PRIVATE, ACC_FINAL
@@ -4866,8 +5156,8 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x000a) ACC_PRIVATE, ACC_STATIC
Code:
stack=2, locals=0, args_size=0
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
- x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
x: return
@@ -4876,7 +5166,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=2, args_size=2
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
x: ldc #x // String <init>
x: ldc #x // String (I)V
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -4890,7 +5180,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 11 10 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
11 10 1 value I
RuntimeVisibleAnnotations:
x: #x()
@@ -4901,7 +5191,7 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
flags: (0x0001) ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
- x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
x: ldc #x // String getValue
x: ldc #x // String ()I
x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
@@ -4912,7 +5202,35 @@ public class rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFramew
LineNumberTable:
LocalVariableTable:
Start Length Slot Name Signature
- 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ 11 5 0 this Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
+
+ public static rename_prefix.com.android.hoststubgen.test.tinyframework.TinyFrameworkToBeRenamed[] getArray(int);
+ descriptor: (I)[Lrename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=6, locals=1, args_size=1
+ x: ldc #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: ldc #x // String getArray
+ x: ldc #x // String (I)[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: anewarray #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iconst_0
+ x: new #x // class rename_prefix/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method "<init>":(I)V
+ x: aastore
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 16 0 value I
RuntimeVisibleAnnotations:
x: #x()
com.android.hoststubgen.hosthelper.HostStubGenProcessedAsKeep
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
index 2f35d35d608d..cbaad2e85717 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
@@ -68,8 +68,18 @@ class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace
class java.lang.Thread keep
method start ()V @com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo.startThread
+# Used to test constructor replacement.
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ConstructorTester keepclass
+ method <init> (I)V @com.android.hoststubgen.test.tinyframework.TinyFrameworkMethodCallReplace$ReplaceTo.newConstructorTester
+
# "rename" takes a type internal name, so '/'s is used as a separator.
# The leading / in the prefix is not needed (it'll be stripped), but it's added to make
# sure the stripping works.
rename ^.*/TinyFrameworkToBeRenamed$ /rename_prefix/
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlisted allow-annotation
+ method foo2 allow-annotation
+
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartialWithWholeClass_bad remove
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted$PartiallyAllowlistedWithoutAnnot_bad remove \ No newline at end of file
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/run-test-manually.sh b/ravenwood/tools/hoststubgen/test-tiny-framework/run-test-manually.sh
index 80ebf3adab3d..450da237d65d 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/run-test-manually.sh
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/run-test-manually.sh
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-source "${0%/*}"/../../common.sh
+set -e
+source "${0%/*}"/../common.sh
# This scripts run the "tiny-framework" test, but does most stuff from the command line, using
# the native java and javac commands.
@@ -49,7 +49,7 @@ tiny_test_classes=$out/tiny-test/classes/
tiny_test_jar=$out/tiny-test.jar
framework_compile_classpaths=(
- $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/hoststubgen-annotations/android_common/javac/hoststubgen-annotations.jar
+ $SOONG_INT/frameworks/base/ravenwood/tools/hoststubgen/hoststubgen-annotations/android_common/javac/hoststubgen-annotations.jar
)
test_compile_classpaths=(
@@ -58,7 +58,7 @@ test_compile_classpaths=(
)
test_runtime_classpaths=(
- $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/hoststubgen-helper-runtime/linux_glibc_common/javac/hoststubgen-helper-runtime.jar
+ $SOONG_INT/frameworks/base/ravenwood/tools/hoststubgen/hoststubgen-helper-runtime/linux_glibc_common/javac/hoststubgen-helper-runtime.jar
)
# This suite runs all tests in the JAR.
@@ -73,7 +73,7 @@ echo "# Building tiny-framework..."
run $JAVAC \
-cp $( \
join : \
- ${framework_compile_classpaths[@]} \
+ "${framework_compile_classpaths[@]}" \
) \
-d $tiny_framework_classes \
tiny-framework/src/**/*.java
@@ -83,7 +83,9 @@ run $JAR cvf $tiny_framework_jar \
# Build stub/impl jars
echo "# Generating the stub and impl jars..."
+# Run with HOSTSTUBGEN_OPTS="-Jagentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8700" to enable the debugger
run $HOSTSTUBGEN \
+ $HOSTSTUBGEN_OPTS \
@../hoststubgen-standard-options.txt \
--in-jar $tiny_framework_jar \
--out-jar $tiny_framework_host_jar \
@@ -91,8 +93,7 @@ run $HOSTSTUBGEN \
--gen-keep-all-file out/tiny-framework_keep_all.txt \
--gen-input-dump-file out/tiny-framework_dump.txt \
--package-redirect com.unsupported:com.supported \
- --annotation-allowed-classes-file annotation-allowed-classes-tiny-framework.txt \
- $HOSTSTUBGEN_OPTS
+ --annotation-allowed-classes-file annotation-allowed-classes-tiny-framework.txt
# Extract the jar files, so we can look into them.
extract $tiny_framework_host_jar
@@ -127,4 +128,4 @@ run $JAVA \
"${test_runtime_classpaths[@]}" \
) \
org.junit.runner.JUnitCore \
- ${test_classes[@]}
+ "${test_classes[@]}"
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
index 88fa492addb8..761748265726 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -28,8 +28,18 @@ GOLDEN_DIRS = [
# Run diff.
def run_diff(file1, file2):
- command = ['diff', '-u', '--ignore-blank-lines',
- '--ignore-space-change', file1, file2]
+ command = ['diff', '-u',
+ '--ignore-blank-lines',
+ '--ignore-space-change',
+
+ # Ignore the class file version.
+ '--ignore-matching-lines=^ *\(major\|minor\) version:$',
+
+ # We shouldn't need `--ignore-matching-lines`, but somehow
+ # the golden files were generated without these lines for b/388562869,
+ # so let's just ignore them.
+ '--ignore-matching-lines=^\(Constant.pool:\|{\)$',
+ file1, file2]
print(' '.join(command))
result = subprocess.run(command, stderr=sys.stdout)
@@ -82,4 +92,13 @@ class TestWithGoldenOutput(unittest.TestCase):
if __name__ == "__main__":
+ args = sys.argv
+
+ # This script is used by diff-and-update-golden.sh too.
+ if len(args) > 1 and args[1] == "run-diff":
+ if run_diff(args[2], args[3]):
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
unittest.main(verbosity=2)
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java
index 3415deb957ed..674937d15424 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotations.java
@@ -28,7 +28,7 @@ import android.hosttest.annotation.HostSideTestThrow;
@HostSideTestKeep
@HostSideTestClassLoadHook(
"com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded")
-public class TinyFrameworkAnnotations {
+public final class TinyFrameworkAnnotations {
@HostSideTestKeep
public TinyFrameworkAnnotations() {
}
@@ -42,7 +42,7 @@ public class TinyFrameworkAnnotations {
public int remove;
@HostSideTestKeep
- public int addOne(int value) {
+ public final int addOne(int value) {
return value + 1;
}
@@ -61,10 +61,10 @@ public class TinyFrameworkAnnotations {
}
@HostSideTestSubstitute(suffix = "_host")
- public static native int nativeAddThree(int value);
+ public final static native int nativeAddThree(int value);
// This method is private, but at runtime, it'll inherit the visibility of the original method
- private static int nativeAddThree_host(int value) {
+ private final static int nativeAddThree_host(int value) {
return value + 3;
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java
index 57c69a336654..d850be82719f 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkMethodCallReplace.java
@@ -41,10 +41,23 @@ public class TinyFrameworkMethodCallReplace {
return originalAdd(1, 2);
}
+ public static ConstructorTester constructorReplaceTester(int i) {
+ // This object construction will be replaced with ReplaceTo.newConstructorTester().
+ return new ConstructorTester(i);
+ }
+
private static int originalAdd(int a, int b) {
return a + b - 1; // Original is broken.
}
+ public static class ConstructorTester {
+ public int i;
+
+ public ConstructorTester(int i) {
+ this.i = i;
+ }
+ }
+
public static class ReplaceTo {
public static void startThread(Thread thread) {
thread.setDaemon(true);
@@ -54,5 +67,9 @@ public class TinyFrameworkMethodCallReplace {
public static int add(int a, int b) {
return a + b;
}
+
+ public static ConstructorTester newConstructorTester(int i) {
+ return new ConstructorTester(i + 1);
+ }
}
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.java
new file mode 100644
index 000000000000..dfc9de4915bc
--- /dev/null
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPartiallyAllowlisted.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestKeep;
+import android.hosttest.annotation.HostSideTestPartiallyAllowlisted;
+import android.hosttest.annotation.HostSideTestWholeClassKeep;
+
+/**
+ * Contains subclasses for tests for "partially-allowlisted".
+ */
+public class TinyFrameworkPartiallyAllowlisted {
+ /** */
+ @HostSideTestPartiallyAllowlisted
+ @HostSideTestKeep
+ public static class PartiallyAllowlisted {
+ /** */
+ public static int foo1(int value) {
+ return value + 1;
+ }
+
+ /** */
+ @HostSideTestKeep
+ public static int foo2(int value) {
+ return value + 2;
+ }
+ }
+
+ /** */
+ @HostSideTestPartiallyAllowlisted
+ @HostSideTestWholeClassKeep // This should be disallowed.
+ public static class PartialWithWholeClass_bad {
+ }
+
+ /** */
+ // Missing @HostSideTestPartiallyAllowlisted
+ @HostSideTestKeep
+ public static class PartiallyAllowlistedWithoutAnnot_bad {
+ /** */
+ public static int foo1(int value) {
+ return value + 1;
+ }
+
+ /** */
+ @HostSideTestKeep
+ public static int foo2(int value) {
+ return value + 2;
+ }
+ }
+
+ /** */
+ public static class NoAnnotations {
+ }
+}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java
index 707bc0ebb4db..74e4610187c4 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkRenamedClassCaller.java
@@ -25,4 +25,9 @@ public class TinyFrameworkRenamedClassCaller {
// so this code should work as-is.
return new TinyFrameworkToBeRenamed(value).getValue();
}
+
+ /** Calls the class that'll be renamed. */
+ public static int bar(int value) {
+ return TinyFrameworkToBeRenamed.getArray(value)[0].getValue();
+ }
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java
index 8319ced6109a..7dcc83e79e26 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkToBeRenamed.java
@@ -31,4 +31,8 @@ public class TinyFrameworkToBeRenamed {
public int getValue() {
return mValue;
}
+
+ public static TinyFrameworkToBeRenamed[] getArray(int value) {
+ return new TinyFrameworkToBeRenamed[] { new TinyFrameworkToBeRenamed(value) };
+ }
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java
index 1ae049371229..93387f5928a1 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkAnnotationsTest.java
@@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import com.android.hoststubgen.test.tinyframework.TinyFrameworkPartiallyAllowlisted.PartiallyAllowlisted;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -61,4 +63,19 @@ public class TinyFrameworkAnnotationsTest {
thrown.expectMessage("not yet supported");
tfc.unsupportedMethod();
}
+
+ @Test
+ public void testPartiallyAllowed() {
+ assertThat(PartiallyAllowlisted.foo2(1)).isEqualTo(3);
+ assertThrows(NoSuchMethodError.class, () -> PartiallyAllowlisted.foo1(1));
+
+ // Just make sure the following classes don't exist.
+ assertThrows(ClassNotFoundException.class,
+ () -> Class.forName("com.android.hoststubgen.test.tinyframework"
+ + ".TinyFrameworkPartiallyAllowlisted.PartialWithWholeClass_bad"));
+ assertThrows(ClassNotFoundException.class,
+ () -> Class.forName("com.android.hoststubgen.test.tinyframework"
+ + ".TinyFrameworkPartiallyAllowlisted.PartiallyAllowlistedWithoutAnnot_bad"
+ ));
+ }
}
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
index 68673dc2a5b8..89fcd30b3df5 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
@@ -308,6 +308,11 @@ public class TinyFrameworkClassTest {
}
@Test
+ public void testTypeRenameArray() {
+ assertThat(TinyFrameworkRenamedClassCaller.bar(2)).isEqualTo(2);
+ }
+
+ @Test
public void testMethodCallReplaceNonStatic() throws Exception {
assertThat(TinyFrameworkMethodCallReplace.nonStaticMethodCallReplaceTester())
.isEqualTo(true);
@@ -318,4 +323,10 @@ public class TinyFrameworkClassTest {
assertThat(TinyFrameworkMethodCallReplace.staticMethodCallReplaceTester())
.isEqualTo(3);
}
+
+ @Test
+ public void testConstructorCallReplace() throws Exception {
+ assertThat(TinyFrameworkMethodCallReplace.constructorReplaceTester(5).i)
+ .isEqualTo(6);
+ }
}
diff --git a/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt b/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt
index d4e75d43a54a..3e6615ec7667 100644
--- a/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt
+++ b/ravenwood/tools/hoststubgen/test/com/android/hoststubgen/utils/ClassPredicateTest.kt
@@ -20,22 +20,22 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Assert.fail
import org.junit.Test
-class ClassFilterTest {
+class ClassPredicateTest {
@Test
fun testDefaultTrue() {
- val f = ClassFilter.newNullFilter(true)
+ val f = ClassPredicate.newConstantPredicate(true)
assertThat(f.matches("a/b/c")).isEqualTo(true)
}
@Test
fun testDefaultFalse() {
- val f = ClassFilter.newNullFilter(false)
+ val f = ClassPredicate.newConstantPredicate(false)
assertThat(f.matches("a/b/c")).isEqualTo(false)
}
@Test
fun testComplex1() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
# ** this is a comment **
a.b.c # allow
!a.b.d # disallow
@@ -57,7 +57,7 @@ class ClassFilterTest {
@Test
fun testComplex2() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
a.b.c # allow
!a.* # disallow everything else in package "a".
!d.e.f # disallow d.e.f.
@@ -75,7 +75,7 @@ class ClassFilterTest {
@Test
fun testNestedClass() {
- val f = ClassFilter.buildFromString("a.b.c\nm.n.o\$p\n", false, "X")
+ val f = ClassPredicate.buildFromString("a.b.c\nm.n.o\$p\n", false, "X")
assertThat(f.matches("a/b/c")).isEqualTo(true)
assertThat(f.matches("a/b/c\$d")).isEqualTo(true)
assertThat(f.matches("a/b/c\$d\$e")).isEqualTo(true)
@@ -88,7 +88,7 @@ class ClassFilterTest {
@Test
fun testBadFilter1() {
try {
- ClassFilter.buildFromString("""
+ ClassPredicate.buildFromString("""
a*
""".trimIndent(), true, "FILENAME")
fail("ParseException didn't happen")
@@ -101,7 +101,7 @@ class ClassFilterTest {
@Test
fun testSuffix() {
- val f = ClassFilter.buildFromString("""
+ val f = ClassPredicate.buildFromString("""
*.Abc # allow
!* # Disallow by default
""".trimIndent(), true, "X")
@@ -112,4 +112,4 @@ class ClassFilterTest {
assertThat(f.matches("a/XyzAbc")).isEqualTo(false)
}
-} \ No newline at end of file
+}
diff --git a/ravenwood/tools/ravenhelper/Android.bp b/ravenwood/tools/ravenhelper/Android.bp
new file mode 100644
index 000000000000..3da6dd824c37
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/Android.bp
@@ -0,0 +1,37 @@
+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"],
+}
+
+java_binary_host {
+ name: "ravenhelper",
+ main_class: "com.android.platform.test.ravenwood.ravenhelper.RavenHelperMain",
+ srcs: ["src/**/*.kt"],
+ static_libs: [
+ "guava",
+ "hoststubgen-lib",
+ "junit",
+ "metalava-gradle-plugin-deps", // Get lint/PSI related classes from here.
+ "ow2-asm",
+ "ow2-asm-analysis",
+ "ow2-asm-commons",
+ "ow2-asm-tree",
+ "ow2-asm-util",
+ ],
+ visibility: ["//visibility:public"],
+}
+
+java_test_host {
+ name: "ravenhelpertest",
+ srcs: ["test/**/*.kt"],
+ static_libs: [
+ "ravenhelper",
+ "truth",
+ ],
+ test_suites: ["general-tests"],
+ visibility: ["//visibility:private"],
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt
new file mode 100644
index 000000000000..0be0c96c33d4
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/RavenHelperMain.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2025 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.
+ */
+@file:JvmName("RavenHelperMain")
+package com.android.platform.test.ravenwood.ravenhelper
+
+/*
+ * This file contains the main entry point for the "ravenhelper" command, which
+ * contains subcommands to help various tasks.
+ */
+
+import com.android.hoststubgen.GeneralUserErrorException
+import com.android.hoststubgen.LogLevel
+import com.android.hoststubgen.executableName
+import com.android.hoststubgen.log
+import com.android.hoststubgen.runMainWithBoilerplate
+import com.android.platform.test.ravenwood.ravenhelper.policytoannot.PtaProcessor
+import com.android.platform.test.ravenwood.ravenhelper.sourcemap.MarkMethodHandler
+
+interface SubcommandHandler {
+ fun handle(args: List<String>)
+}
+
+fun usage() {
+ System.out.println("""
+ Usage:
+ ravenhelper SUBCOMMAND options...
+
+ Subcommands:
+ pta: "policy-to-annotations" Convert policy file to annotations.
+ (See the pta-framework.sh script for usage.)
+
+ mm: "mark methods" Used to add annotations (such as @DisabledOnRavenwood)
+ to methods.
+
+ """.trimIndent())
+}
+
+fun main(args: Array<String>) {
+ executableName = "RavenHelper"
+ log.setConsoleLogLevel(LogLevel.Info)
+
+ runMainWithBoilerplate {
+ log.i("$executableName started")
+
+ if (args.size == 0) {
+ usage()
+ return
+ }
+
+ // Find the subcommand handler.
+ val subcommand = args[0]
+ val handler: SubcommandHandler = when (subcommand) {
+ "pta" -> PtaProcessor()
+ "mm" -> MarkMethodHandler()
+ else -> {
+ usage()
+ throw GeneralUserErrorException("Unknown subcommand '$subcommand'")
+ }
+ }
+
+ // Run the subcommand.
+ handler.handle(args.copyOfRange(1, args.size).toList())
+ }
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt
new file mode 100644
index 000000000000..33fb015cc131
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Annotations.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.platform.test.ravenwood.ravenhelper.policytoannot
+
+import com.android.hoststubgen.filters.FilterPolicy
+
+
+/**
+ * This class knows about the Ravenwood annotations.
+ */
+class Annotations {
+ enum class Target {
+ Class,
+ Field,
+ Method,
+ }
+
+ fun get(policy: FilterPolicy, target: Target): String? {
+ return when (policy) {
+ FilterPolicy.Keep ->
+ if (target == Target.Class) {
+ "@android.ravenwood.annotation.RavenwoodKeepPartialClass"
+ } else {
+ "@android.ravenwood.annotation.RavenwoodKeep"
+ }
+ FilterPolicy.KeepClass ->
+ "@android.ravenwood.annotation.RavenwoodKeepWholeClass"
+ FilterPolicy.Substitute ->
+ "@android.ravenwood.annotation.RavenwoodReplace"
+ FilterPolicy.Redirect ->
+ "@android.ravenwood.annotation.RavenwoodRedirect"
+ FilterPolicy.Throw ->
+ "@android.ravenwood.annotation.RavenwoodThrow"
+ FilterPolicy.Ignore ->
+ "@android.ravenwood.annotation.RavenwoodIgnore"
+ FilterPolicy.Remove ->
+ "@android.ravenwood.annotation.RavenwoodRemove"
+ FilterPolicy.AnnotationAllowed -> null // Can't convert to an annotation.
+ }
+ }
+
+ private fun withArg(annot: String, arg: String): String {
+ return "@$annot(\"$arg\")"
+ }
+
+ fun getClassLoadHookAnnotation(arg: String): String {
+ return withArg("android.ravenwood.annotation.RavenwoodClassLoadHook", arg)
+ }
+
+ fun getRedirectionClassAnnotation(arg: String): String {
+ return withArg("android.ravenwood.annotation.RavenwoodRedirectionClass", arg)
+ }
+}
+
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt
new file mode 100644
index 000000000000..256d1234e1e6
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/Operations.kt
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.policytoannot
+
+/*
+ * This file contains classes and functions about file edit operations, such as
+ * "insert a line", "delete a line".
+ */
+
+
+import com.android.hoststubgen.log
+import java.io.BufferedWriter
+import java.io.File
+import java.io.FileOutputStream
+import java.io.OutputStreamWriter
+
+enum class SourceOperationType {
+ /** Insert a line */
+ Insert,
+
+ /** delete a line */
+ Delete,
+
+ /** Insert a text at the beginning of a line */
+ Prepend,
+}
+
+data class SourceOperation(
+ /** Target file to edit. */
+ val sourceFile: String,
+
+ /** 1-based line number. Use -1 to add at the end of the file. */
+ val lineNumber: Int,
+
+ /** Operation type.*/
+ val type: SourceOperationType,
+
+ /** Operand -- text to insert or prepend. Ignored for delete. */
+ val text: String = "",
+
+ /** Human-readable description of why this operation was created */
+ val description: String,
+) {
+ override fun toString(): String {
+ return "SourceOperation(sourceFile='$sourceFile', " +
+ "lineNumber=$lineNumber, type=$type, text='$text' desc='$description')"
+ }
+}
+
+/**
+ * Stores list of [SourceOperation]s for each file.
+ */
+class SourceOperations {
+ var size: Int = 0
+ private set
+ private val fileOperations = mutableMapOf<String, MutableList<SourceOperation>>()
+
+ fun add(op: SourceOperation) {
+ log.forVerbose {
+ log.v("Adding operation: $op")
+ }
+ size++
+ fileOperations[op.sourceFile]?.let { ops ->
+ ops.add(op)
+ return
+ }
+ fileOperations[op.sourceFile] = mutableListOf(op)
+ }
+
+ /**
+ * Get the collected [SourceOperation]s for each file.
+ */
+ fun getOperations(): MutableMap<String, MutableList<SourceOperation>> {
+ return fileOperations
+ }
+}
+
+/**
+ * Create a shell script to apply all the operations (using sed).
+ */
+fun createShellScript(ops: SourceOperations, writer: BufferedWriter) {
+ // File header.
+ // Note ${'$'} is an ugly way to put a dollar sign ($) in a multi-line string.
+ writer.write(
+ """
+ #!/bin/bash
+
+ set -e # Finish when any command fails.
+
+ function apply() {
+ local file="${'$'}1"
+
+ # The script is given via stdin. Write it to file.
+ local sed="/tmp/pta-script.sed.tmp"
+ cat > "${'$'}sed"
+
+ echo "Running: sed -i -f \"${'$'}sed\" \"${'$'}file\""
+
+ if ! sed -i -f "${'$'}sed" "${'$'}file" ; then
+ echo 'Failed!' 1>&2
+ return 1
+ fi
+ }
+
+ """.trimIndent()
+ )
+
+ ops.getOperations().toSortedMap().forEach { (origFile, ops) ->
+ val file = File(origFile).absolutePath
+
+ writer.write("\n")
+
+ writer.write("#")
+ writer.write("=".repeat(78))
+ writer.write("\n")
+
+ writer.write("\n")
+
+ writer.write("apply \"$file\" <<'__END_OF_SCRIPT__'\n")
+ toSedScript(ops, writer)
+ writer.write("__END_OF_SCRIPT__\n")
+ }
+
+ writer.write("\n")
+
+ writer.write("echo \"All files updated successfully!\"\n")
+ writer.flush()
+}
+
+/**
+ * Create a sed script to apply a list of operations.
+ */
+private fun toSedScript(ops: List<SourceOperation>, writer: BufferedWriter) {
+ ops.sortedBy { it.lineNumber }.forEach { op ->
+ if (op.text.contains('\n')) {
+ throw RuntimeException("Operation $op may not contain newlines.")
+ }
+
+ // Convert each operation to a sed operation. Examples:
+ //
+ // - Insert "abc" to line 2
+ // 2i\
+ // abc
+ //
+ // - Insert "abc" to the end of the file
+ // $a\
+ // abc
+ //
+ // - Delete line 2
+ // 2d
+ //
+ // - Prepend abc to line 2
+ // 2s/^/abc/
+ //
+ // The line numbers are all the line numbers in the original file. Even though
+ // the script itself will change them because of inserts and deletes, we don't need to
+ // change the line numbers in the script.
+
+ // Write the target line number.
+ writer.write("\n")
+ writer.write("# ${op.description}\n")
+ if (op.lineNumber >= 0) {
+ writer.write(op.lineNumber.toString())
+ } else {
+ writer.write("$")
+ }
+
+ when (op.type) {
+ SourceOperationType.Insert -> {
+ if (op.lineNumber >= 0) {
+ writer.write("i\\\n") // "Insert"
+ } else {
+ // If it's the end of the file, we need to use "a" (append)
+ writer.write("a\\\n")
+ }
+ writer.write(op.text)
+ writer.write("\n")
+ }
+ SourceOperationType.Delete -> {
+ writer.write("d\n")
+ }
+ SourceOperationType.Prepend -> {
+ if (op.text.contains('/')) {
+ TODO("Operation $op contains character(s) that needs to be escaped.")
+ }
+ writer.write("s/^/${op.text}/\n")
+ }
+ }
+ }
+}
+
+fun createShellScript(ops: SourceOperations, scriptFile: String?): Boolean {
+ if (ops.size == 0) {
+ log.i("No files need to be updated.")
+ return false
+ }
+
+ val scriptWriter = BufferedWriter(
+ OutputStreamWriter(
+ scriptFile?.let { file ->
+ FileOutputStream(file)
+ } ?: System.out
+ ))
+
+ scriptWriter.use { writer ->
+ scriptFile?.let {
+ log.i("Creating script file at $it ...")
+ }
+ createShellScript(ops, writer)
+ }
+ return true
+} \ No newline at end of file
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt
new file mode 100644
index 000000000000..08bd95fd532b
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaOptions.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.policytoannot
+
+import com.android.hoststubgen.ArgIterator
+import com.android.hoststubgen.ArgumentsException
+import com.android.hoststubgen.SetOnce
+import com.android.hoststubgen.ensureFileExists
+import com.android.hoststubgen.log
+
+/**
+ * Options for the "ravenhelper pta" subcommand.
+ */
+class PtaOptions(
+ /** Text policy files */
+ var policyOverrideFiles: MutableList<String> = mutableListOf(),
+
+ /** Annotation allowed list file. */
+ var annotationAllowedClassesFile: SetOnce<String?> = SetOnce(null),
+
+ /** Source files or directories. */
+ var sourceFilesOrDirectories: MutableList<String> = mutableListOf(),
+
+ /** Output script file. */
+ var outputScriptFile: SetOnce<String?> = SetOnce(null),
+
+ /** Dump the operations (for debugging) */
+ var dumpOperations: SetOnce<Boolean> = SetOnce(false),
+) {
+ companion object {
+ fun parseArgs(args: List<String>): PtaOptions {
+ val ret = PtaOptions()
+ val ai = ArgIterator.withAtFiles(args.toTypedArray())
+
+ while (true) {
+ val arg = ai.nextArgOptional() ?: break
+
+ fun nextArg(): String = ai.nextArgRequired(arg)
+
+ if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
+ continue
+ }
+ try {
+ when (arg) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
+
+ "-p", "--policy-override-file" ->
+ ret.policyOverrideFiles.add(nextArg().ensureFileExists())
+
+ "-a", "--annotation-allowed-classes-file" ->
+ ret.annotationAllowedClassesFile.set(nextArg().ensureFileExists())
+
+ "-s", "--src" ->
+ ret.sourceFilesOrDirectories.add(nextArg().ensureFileExists())
+
+ "--dump" ->
+ ret.dumpOperations.set(true)
+
+ "-o", "--output-script" ->
+ ret.outputScriptFile.set(nextArg())
+
+ else -> throw ArgumentsException("Unknown option: $arg")
+ }
+ } catch (e: SetOnce.SetMoreThanOnceException) {
+ throw ArgumentsException("Duplicate or conflicting argument found: $arg")
+ }
+ }
+
+ if (ret.policyOverrideFiles.size == 0) {
+ throw ArgumentsException("Must specify at least one policy file")
+ }
+
+ if (ret.sourceFilesOrDirectories.size == 0) {
+ throw ArgumentsException("Must specify at least one source path")
+ }
+
+ return ret
+ }
+ }
+
+ override fun toString(): String {
+ return """
+ PtaOptions{
+ policyOverrideFiles=$policyOverrideFiles
+ annotationAllowedClassesFile=$annotationAllowedClassesFile
+ sourceFilesOrDirectories=$sourceFilesOrDirectories
+ outputScriptFile=$outputScriptFile
+ dumpOperations=$dumpOperations
+ }
+ """.trimIndent()
+ }
+} \ No newline at end of file
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
new file mode 100644
index 000000000000..a7f481a02533
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/policytoannot/PtaProcessor.kt
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.policytoannot
+
+import com.android.hoststubgen.LogLevel
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME
+import com.android.hoststubgen.asm.toJvmClassName
+import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.PolicyFileProcessor
+import com.android.hoststubgen.filters.SpecialClass
+import com.android.hoststubgen.filters.TextFileFilterPolicyParser
+import com.android.hoststubgen.filters.TextFilePolicyMethodReplaceFilter
+import com.android.hoststubgen.log
+import com.android.hoststubgen.utils.ClassPredicate
+import com.android.platform.test.ravenwood.ravenhelper.SubcommandHandler
+import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment
+import com.android.platform.test.ravenwood.ravenhelper.sourcemap.AllClassInfo
+import com.android.platform.test.ravenwood.ravenhelper.sourcemap.ClassInfo
+import com.android.platform.test.ravenwood.ravenhelper.sourcemap.MethodInfo
+import com.android.platform.test.ravenwood.ravenhelper.sourcemap.SourceLoader
+import java.io.FileReader
+import java.util.regex.Pattern
+
+/**
+ * This is the main routine of the "pta" -- policy-to-annotation -- subcommands.
+ */
+class PtaProcessor : SubcommandHandler {
+ override fun handle(args: List<String>) {
+ val options = PtaOptions.parseArgs(args)
+
+ log.v("Options: $options")
+
+ val converter = TextPolicyToAnnotationConverter(
+ options.policyOverrideFiles,
+ options.sourceFilesOrDirectories,
+ options.annotationAllowedClassesFile.get,
+ Annotations(),
+ options.dumpOperations.get || log.isEnabled(LogLevel.Debug),
+ )
+ converter.process()
+
+ createShellScript(converter.resultOperations, options.outputScriptFile.get)
+ }
+}
+
+/**
+ * This class implements the actual logic.
+ */
+private class TextPolicyToAnnotationConverter(
+ val policyFiles: List<String>,
+ val sourceFilesOrDirectories: List<String>,
+ val annotationAllowedClassesFile: String?,
+ val annotations: Annotations,
+ val dumpOperations: Boolean,
+) {
+ private val annotationAllowedClasses: ClassPredicate = annotationAllowedClassesFile.let { file ->
+ if (file == null) {
+ ClassPredicate.newConstantPredicate(true) // Allow all classes
+ } else {
+ ClassPredicate.loadFromFile(file, false)
+ }
+ }
+
+ val resultOperations = SourceOperations()
+ private val classes = AllClassInfo()
+ private val policyParser = TextFileFilterPolicyParser()
+ private val annotationNeedingClasses = mutableSetOf<String>()
+
+ /**
+ * Entry point.
+ */
+ fun process() {
+ // First, load
+ val env = createUastEnvironment()
+ try {
+ loadSources()
+
+ processPolicies()
+
+ addToAnnotationsAllowedListFile()
+
+ if (dumpOperations) {
+ log.withIndent {
+ resultOperations.getOperations().toSortedMap().forEach { (file, ops) ->
+ log.i("ops: $file")
+ ops.forEach { op ->
+ log.i(" line: ${op.lineNumber}: ${op.type}: \"${op.text}\" " +
+ "(${op.description})")
+ }
+ }
+ }
+ }
+ } finally {
+ env.dispose()
+ }
+ }
+
+ /**
+ * Load all the java source files into [classes].
+ */
+ private fun loadSources() {
+ val env = createUastEnvironment()
+ try {
+ val loader = SourceLoader(env)
+ loader.load(sourceFilesOrDirectories, classes)
+ } finally {
+ env.dispose()
+ }
+ }
+
+ private fun addToAnnotationsAllowedListFile() {
+ log.i("Generating operations to update annotation allowlist file...")
+ log.withIndent {
+ annotationNeedingClasses.sorted().forEach { className ->
+ if (!annotationAllowedClasses.matches(className.toJvmClassName())) {
+ resultOperations.add(
+ SourceOperation(
+ annotationAllowedClassesFile!!,
+ -1, // add to the end
+ SourceOperationType.Insert,
+ className,
+ "add to annotation allowlist"
+ ))
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the policy files with [Processor].
+ */
+ private fun processPolicies() {
+ log.i("Loading the policy files and generating operations...")
+ log.withIndent {
+ policyFiles.forEach { policyFile ->
+ log.i("Parsing $policyFile ...")
+ log.withIndent {
+ policyParser.parse(FileReader(policyFile), policyFile, Processor())
+ }
+ }
+ }
+ }
+
+ private inner class Processor : PolicyFileProcessor {
+
+ var classPolicyText = ""
+ var classPolicyLine = -1
+
+ // Whether the current class has a skip marker, in which case we ignore all members.
+ // Applicable only within a "simple class"
+ var classSkipping = false
+
+ var classLineConverted = false
+ var classHasMember = false
+
+ private fun currentLineHasSkipMarker(): Boolean {
+ val ret = policyParser.currentLineText.contains("no-pta")
+
+ if (ret) {
+ log.forVerbose {
+ log.v("Current line has a skip marker: ${policyParser.currentLineText}")
+ }
+ }
+
+ return ret
+ }
+
+ private fun shouldSkipCurrentLine(): Boolean {
+ // If a line contains a special marker "no-pta", we'll skip it.
+ return classSkipping || currentLineHasSkipMarker()
+ }
+
+ /** Print a warning about an unsupported policy directive. */
+ private fun warnOnPolicy(message: String, policyLine: String, lineNumber: Int) {
+ log.w("Warning: $message")
+ log.w(" policy: \"$policyLine\"")
+ log.w(" at ${policyParser.filename}:$lineNumber")
+ }
+
+ /** Print a warning about an unsupported policy directive. */
+ private fun warnOnCurrentPolicy(message: String) {
+ warnOnPolicy(message, policyParser.currentLineText, policyParser.lineNumber)
+ }
+
+ /** Print a warning about an unsupported policy directive on the class line. */
+ private fun warnOnClassPolicy(message: String) {
+ warnOnPolicy(message, classPolicyText, classPolicyLine)
+ }
+
+ override fun onPackage(name: String, policy: FilterPolicyWithReason) {
+ warnOnCurrentPolicy("'package' directive isn't supported (yet).")
+ }
+
+ override fun onRename(pattern: Pattern, prefix: String) {
+ // Rename will never be supported, so don't show a warning.
+ }
+
+ private fun addOperation(op: SourceOperation) {
+ resultOperations.add(op)
+ }
+
+ private fun commentOutPolicy(lineNumber: Int, description: String) {
+ addOperation(
+ SourceOperation(
+ policyParser.filename,
+ lineNumber,
+ SourceOperationType.Prepend,
+ "#[PTA]: ", // comment out.
+ description,
+ )
+ )
+ }
+
+ override fun onClassStart(className: String) {
+ classSkipping = currentLineHasSkipMarker()
+ classLineConverted = false
+ classHasMember = false
+ classPolicyLine = policyParser.lineNumber
+ classPolicyText = policyParser.currentLineText
+ }
+
+ override fun onClassEnd(className: String) {
+ if (classSkipping) {
+ classSkipping = false
+ return
+ }
+ if (!classLineConverted) {
+ // Class line is still needed in the policy file.
+ // (Because the source file wasn't found.)
+ return
+ }
+ if (!classHasMember) {
+ commentOutPolicy(classPolicyLine, "remove class policy on $className")
+ } else {
+ warnOnClassPolicy(
+ "Class policy on $className can't be removed because it still has members.")
+ }
+ }
+
+ private fun findClass(className: String): ClassInfo? {
+ val ci = classes.findClass(className)
+ if (ci == null) {
+ warnOnCurrentPolicy("Class not found: $className")
+ }
+ return ci
+ }
+
+ private fun addClassAnnotation(
+ className: String,
+ annotation: String,
+ ): Boolean {
+ val ci = findClass(className) ?: return false
+
+ // Add the annotation to the source file.
+ addOperation(
+ SourceOperation(
+ ci.location.file,
+ ci.location.line,
+ SourceOperationType.Insert,
+ ci.location.getIndent() + annotation,
+ "add class annotation to $className"
+ )
+ )
+ annotationNeedingClasses.add(className)
+ return true
+ }
+
+ override fun onSimpleClassPolicy(className: String, policy: FilterPolicyWithReason) {
+ if (shouldSkipCurrentLine()) {
+ return
+ }
+ log.v("Found simple class policy: $className - ${policy.policy}")
+
+ val annot = annotations.get(policy.policy, Annotations.Target.Class)!!
+ if (addClassAnnotation(className, annot)) {
+ classLineConverted = true
+ }
+ }
+
+ override fun onSubClassPolicy(superClassName: String, policy: FilterPolicyWithReason) {
+ warnOnCurrentPolicy("Subclass policies isn't supported (yet).")
+ }
+
+ override fun onRedirectionClass(fromClassName: String, toClassName: String) {
+ if (shouldSkipCurrentLine()) {
+ return
+ }
+
+ log.v("Found class redirection: $fromClassName - $toClassName")
+
+ if (addClassAnnotation(
+ fromClassName,
+ annotations.getRedirectionClassAnnotation(toClassName),
+ )) {
+ commentOutPolicy(policyParser.lineNumber,
+ "remove class redirection policy on $fromClassName")
+ }
+ }
+
+ override fun onClassLoadHook(className: String, callback: String) {
+ if (shouldSkipCurrentLine()) {
+ return
+ }
+
+ log.v("Found class load hook: $className - $callback")
+
+ if (addClassAnnotation(
+ className,
+ annotations.getClassLoadHookAnnotation(callback),
+ )) {
+ commentOutPolicy(policyParser.lineNumber,
+ "remove class load hook policy on $className")
+ }
+ }
+
+ override fun onSpecialClassPolicy(type: SpecialClass, policy: FilterPolicyWithReason) {
+ // This can't be converted to an annotation, so don't show a warning.
+ }
+
+ override fun onField(className: String, fieldName: String, policy: FilterPolicyWithReason) {
+ if (shouldSkipCurrentLine()) {
+ return
+ }
+
+ log.v("Found field policy: $className.$fieldName - ${policy.policy}")
+
+ val ci = findClass(className) ?: return
+
+ ci.findField(fieldName)?.let { fi ->
+ val annot = annotations.get(policy.policy, Annotations.Target.Field)!!
+
+ addOperation(
+ SourceOperation(
+ fi.location.file,
+ fi.location.line,
+ SourceOperationType.Insert,
+ fi.location.getIndent() + annot,
+ "add annotation to field $className.$fieldName",
+ )
+ )
+ commentOutPolicy(policyParser.lineNumber,
+ "remove field policy $className.$fieldName")
+
+ annotationNeedingClasses.add(className)
+ } ?: {
+ warnOnCurrentPolicy("Field not found: $className.$fieldName")
+ }
+ }
+
+ override fun onSimpleMethodPolicy(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ policy: FilterPolicyWithReason
+ ) {
+ if (shouldSkipCurrentLine()) {
+ return
+ }
+ val readableName = "$className.$methodName$methodDesc"
+ log.v("Found simple method policy: $readableName - ${policy.policy}")
+
+
+ // Inner method to get the matching methods for this policy.
+ //
+ // If this policy can't be converted for any reason, it'll return null.
+ // Otherwise, it'll return a pair of method list and the annotation string.
+ fun getMethods(): Pair<List<MethodInfo>, String>? {
+ if (methodName == CLASS_INITIALIZER_NAME) {
+ warnOnClassPolicy("Policy for class initializers not supported.")
+ return null
+ }
+ val ci = findClass(className) ?: return null
+ val methods = ci.findMethods(methodName, methodDesc)
+ if (methods == null) {
+ warnOnCurrentPolicy("Method not found: $readableName")
+ return null
+ }
+
+ // If the policy is "ignore", we can't convert it to an annotation, in which case
+ // annotations.get() will return null.
+ val annot = annotations.get(policy.policy, Annotations.Target.Method)
+ if (annot == null) {
+ warnOnCurrentPolicy("Annotation for policy '${policy.policy}' isn't available")
+ return null
+ }
+ return Pair(methods, annot)
+ }
+
+ val methodsAndAnnot = getMethods()
+
+ if (methodsAndAnnot == null) {
+ classHasMember = true
+ return // This policy can't be converted.
+ }
+ val methods = methodsAndAnnot.first
+ val annot = methodsAndAnnot.second
+
+ var found = false
+ methods.forEach { mi ->
+ found = true
+ addOperation(
+ SourceOperation(
+ mi.location.file,
+ mi.location.line,
+ SourceOperationType.Insert,
+ mi.location.getIndent() + annot,
+ "add annotation to method $readableName",
+ )
+ )
+ }
+ if (found) {
+ commentOutPolicy(
+ policyParser.lineNumber,
+ "remove method policy $readableName"
+ )
+
+ annotationNeedingClasses.add(className)
+ } else {
+ warnOnCurrentPolicy("Method not found: $readableName")
+ }
+ }
+
+ override fun onMethodInClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ targetName: String,
+ policy: FilterPolicyWithReason
+ ) {
+ warnOnCurrentPolicy("Found method replace but it's not supported yet: "
+ + "$className.$methodName$methodDesc - $targetName")
+ }
+
+ override fun onMethodOutClassReplace(
+ className: String,
+ methodName: String,
+ methodDesc: String,
+ replaceSpec: TextFilePolicyMethodReplaceFilter.MethodCallReplaceSpec,
+ ) {
+ // This can't be converted to an annotation.
+ classHasMember = true
+ }
+ }
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt
new file mode 100644
index 000000000000..6775135e1ac5
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/psi/PsiUtil.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.psi
+
+import com.android.tools.lint.UastEnvironment
+
+// PSI is a library to parse Java/Kotlin source files, which is part of JetBrains' IntelliJ/
+// Android Studio, and other IDEs.
+//
+// PSI is normally used by IntelliJ's plugins, and as such, there isn't really a good documentation
+// on how to use it from a standalone program. However, fortunately, Android Studio's Lint
+// and Metalava both use PSI. Metalava reuses some of the APIs exposed by Lint. We also use the
+// same Lint APIs used by Metalava here.
+//
+// Some code pointers around the relevant projects:
+//
+// - We stole code from Metalava, but the recent version of Metalava is too complicated,
+// and hard to understand. Older Metalava, such as this one:
+// https://android.git.corp.google.com/platform/tools/metalava/+/refs/heads/android13-dev
+// is easier to understand.
+//
+// - PSI is source code is available in IntelliJ's code base:
+// https://github.com/JetBrains/intellij-community.git
+//
+// - Lint is in Android studio.
+// https://android.googlesource.com/platform/tools/base/+/studio-master-dev/source.md
+
+
+/**
+ * Create [UastEnvironment] enough to parse Java source files.
+ */
+fun createUastEnvironment(): UastEnvironment {
+ val config = UastEnvironment.Configuration.create(
+ enableKotlinScripting = false,
+ useFirUast = false,
+ )
+
+ config.javaLanguageLevel = com.intellij.pom.java.LanguageLevel.JDK_21
+
+ // The following code exists in Metalava, but we don't seem to need it.
+ // We may need to when we need to support kotlin.
+// config.kotlinLanguageLevel = kotlinLanguageLevel
+// config.addSourceRoots(listOf(File(root)))
+// config.addClasspathRoots(classpath.map { it.absoluteFile })
+// options.jdkHome?.let {
+// if (options.isJdkModular(it)) {
+// config.kotlinCompilerConfig.put(JVMConfigurationKeys.JDK_HOME, it)
+// config.kotlinCompilerConfig.put(JVMConfigurationKeys.NO_JDK, false)
+// }
+// }
+
+ return UastEnvironment.create(config)
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt
new file mode 100644
index 000000000000..ee200bb39df2
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MapOptions.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.sourcemap
+
+import com.android.hoststubgen.ArgIterator
+import com.android.hoststubgen.ArgumentsException
+import com.android.hoststubgen.SetOnce
+import com.android.hoststubgen.ensureFileExists
+import com.android.hoststubgen.log
+
+/**
+ * Options for the "ravenhelper map" subcommand.
+ */
+class MapOptions(
+ /** Source files or directories. */
+ var sourceFilesOrDirectories: MutableList<String> = mutableListOf(),
+
+ /** Files containing target methods */
+ var targetMethodFiles: MutableList<String> = mutableListOf(),
+
+ /** Output script file. */
+ var outputScriptFile: SetOnce<String?> = SetOnce(null),
+
+ /** Text to insert. */
+ var text: SetOnce<String?> = SetOnce(null),
+) {
+ companion object {
+ fun parseArgs(args: List<String>): MapOptions {
+ val ret = MapOptions()
+ val ai = ArgIterator.withAtFiles(args.toTypedArray())
+
+ while (true) {
+ val arg = ai.nextArgOptional() ?: break
+
+ fun nextArg(): String = ai.nextArgRequired(arg)
+
+ if (log.maybeHandleCommandLineArg(arg) { nextArg() }) {
+ continue
+ }
+ try {
+ when (arg) {
+ // TODO: Write help
+ "-h", "--help" -> TODO("Help is not implemented yet")
+
+ "-s", "--src" ->
+ ret.sourceFilesOrDirectories.add(nextArg().ensureFileExists())
+
+ "-i", "--input" ->
+ ret.targetMethodFiles.add(nextArg().ensureFileExists())
+
+ "-o", "--output-script" ->
+ ret.outputScriptFile.set(nextArg())
+
+ "-t", "--text" ->
+ ret.text.set(nextArg())
+
+ else -> throw ArgumentsException("Unknown option: $arg")
+ }
+ } catch (e: SetOnce.SetMoreThanOnceException) {
+ throw ArgumentsException("Duplicate or conflicting argument found: $arg")
+ }
+ }
+
+ if (ret.sourceFilesOrDirectories.size == 0) {
+ throw ArgumentsException("Must specify at least one source path")
+ }
+
+ return ret
+ }
+ }
+
+ override fun toString(): String {
+ return """
+ PtaOptions{
+ sourceFilesOrDirectories=$sourceFilesOrDirectories
+ targetMethods=$targetMethodFiles
+ outputScriptFile=$outputScriptFile
+ text=$text
+ }
+ """.trimIndent()
+ }
+} \ No newline at end of file
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt
new file mode 100644
index 000000000000..8085253895f9
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/MarkMethodHandler.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.sourcemap
+
+import com.android.hoststubgen.GeneralUserErrorException
+import com.android.hoststubgen.log
+import com.android.platform.test.ravenwood.ravenhelper.SubcommandHandler
+import com.android.platform.test.ravenwood.ravenhelper.policytoannot.SourceOperation
+import com.android.platform.test.ravenwood.ravenhelper.policytoannot.SourceOperationType
+import com.android.platform.test.ravenwood.ravenhelper.policytoannot.SourceOperations
+import com.android.platform.test.ravenwood.ravenhelper.policytoannot.createShellScript
+import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment
+import java.io.BufferedReader
+import java.io.FileReader
+
+/**
+ * This is the main routine of the "mm" subcommands, which marks specified methods with
+ * a given line, which defaults to "@DisabledOnRavenwood". This can be used to add bulk-annotate
+ * tests methods that are failing.
+ *
+ * See the javadoc of [MarkMethodProcessor] for more details.
+ */
+class MarkMethodHandler : SubcommandHandler {
+ override fun handle(args: List<String>) {
+ val options = MapOptions.parseArgs(args)
+
+ log.i("Options: $options")
+
+ // Files from which we load a list of methods.
+ val inputFiles = if (options.targetMethodFiles.isEmpty()) {
+ log.w("[Reading method list from STDIN...]")
+ log.flush()
+ listOf("/dev/stdin")
+ } else {
+ options.targetMethodFiles
+ }
+
+ // A string to inject before each method.
+ val text = if (options.text.isSet) {
+ options.text.get!!
+ } else {
+ "@android.platform.test.annotations.DisabledOnRavenwood"
+ }
+
+ // Process.
+ val processor = MarkMethodProcessor(
+ options.sourceFilesOrDirectories,
+ inputFiles,
+ text,
+ )
+ processor.process()
+
+ // Create the output script.
+ createShellScript(processor.resultOperations, options.outputScriptFile.get)
+ }
+}
+
+/**
+ * Load a list of methods / classes from [targetMethodFiles], and inject [textToInsert] to
+ * each of them, to the source files under [sourceFilesOrDirectories]
+ *
+ * An example input files look like this -- this can be generated from atest output.
+ * <pre>
+
+ # We add @DisabledOnRavenwood to the following methods.
+ com.android.ravenwoodtest.tests.Test1#testA
+ com.android.ravenwoodtest.tests.Test1#testB
+ com.android.ravenwoodtest.tests.Test1#testC
+
+ # We add @DisabledOnRavenwood to the following class.
+ com.android.ravenwoodtest.tests.Test2
+
+ # Special case: we add the annotation to the class too.
+ com.android.ravenwoodtest.tests.Test3#initializationError
+ </pre>
+
+ */
+private class MarkMethodProcessor(
+ private val sourceFilesOrDirectories: List<String>,
+ private val targetMethodFiles: List<String>,
+ private val textToInsert: String,
+) {
+ private val classes = AllClassInfo()
+ val resultOperations = SourceOperations()
+
+ /**
+ * Entry point.
+ */
+ fun process() {
+ val env = createUastEnvironment()
+ try {
+ loadSources()
+
+ processInputFiles()
+ } finally {
+ env.dispose()
+ }
+ }
+
+ private fun loadSources() {
+ val env = createUastEnvironment()
+ try {
+ val loader = SourceLoader(env)
+ loader.load(sourceFilesOrDirectories, classes)
+ } finally {
+ env.dispose()
+ }
+ }
+
+ /**
+ * Process liput files. Input files looks like this:
+ * <pre>
+ * # We add @DisabledOnRavenwood to the following methods.
+ * com.android.ravenwoodtest.tests.Test1#testA
+ * com.android.ravenwoodtest.tests.Test1#testB
+ * com.android.ravenwoodtest.tests.Test1#testC
+ *
+ * # We add @DisabledOnRavenwood to the following class.
+ * com.android.ravenwoodtest.tests.Test2
+ *
+ * # Special case: we add the annotation to the class too.
+ * com.android.ravenwoodtest.tests.Test3#initializationError
+ * </pre>
+ */
+ private fun processInputFiles() {
+ targetMethodFiles.forEach { filename ->
+ BufferedReader(FileReader(filename)).use { reader ->
+ reader.readLines().forEach { line ->
+ if (line.isBlank() || line.startsWith('#')) {
+ return@forEach
+ }
+ processSingleLine(line)
+ }
+ }
+ }
+ }
+
+ private fun processSingleLine(line: String) {
+ val cm = line.split("#") // Class and method
+ if (cm.size > 2) {
+ throw GeneralUserErrorException("Input line \"$line\" contains too many #'s")
+ }
+ val className = cm[0]
+ val methodName = if (cm.size == 2 && cm[1] != "initializationError") {
+ cm[1]
+ } else {
+ ""
+ }
+
+ // Find class info
+ val ci = classes.findClass(className)
+ ?: throw GeneralUserErrorException("Class \"$className\" not found\"")
+
+ if (methodName == "") {
+ processClass(ci)
+ } else {
+ processMethod(ci, methodName)
+ }
+ }
+
+ private fun processClass(ci: ClassInfo) {
+ addOperation(ci.location, "Class ${ci.fullName}")
+ }
+
+ private fun processMethod(ci: ClassInfo, methodName: String) {
+ var methods = ci.methods[methodName]
+ ?: throw GeneralUserErrorException("method \"$methodName\" not found\"")
+ methods.forEach { mi ->
+ addOperation(mi.location, "Method ${mi.name}")
+ }
+ }
+
+ private fun addOperation(loc: Location, description: String) {
+ resultOperations.add(
+ SourceOperation(
+ loc.file,
+ loc.line,
+ SourceOperationType.Insert,
+ loc.getIndent() + textToInsert,
+ description
+ )
+ )
+ }
+}
diff --git a/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt
new file mode 100644
index 000000000000..58e4497f9f9c
--- /dev/null
+++ b/ravenwood/tools/ravenhelper/src/com/android/platform/test/ravenwood/ravenhelper/sourcemap/SourceMapGenerator.kt
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.platform.test.ravenwood.ravenhelper.sourcemap
+
+/*
+ * This file contains classes used to parse Java source files to build "source map" which
+ * basically tells you what classes/methods/fields are declared in what line of what file.
+ */
+
+import com.android.hoststubgen.GeneralUserErrorException
+import com.android.hoststubgen.log
+import com.android.tools.lint.UastEnvironment
+import com.intellij.openapi.editor.Document
+import com.intellij.openapi.vfs.StandardFileSystems
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiClassOwner
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
+import com.intellij.psi.PsiManager
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiNameIdentifierOwner
+import com.intellij.psi.SyntheticElement
+import java.io.File
+
+
+/**
+ * Represents the location of an item. (class, field or method)
+ */
+data class Location (
+ /** Full path filename. */
+ val file: String,
+
+ /** 1-based line number */
+ val line: Int,
+
+ /** Indent of the line */
+ val indent: Int,
+) {
+
+ fun getIndent(): String {
+ return " ".repeat(indent)
+ }
+
+ fun dump() {
+ log.i("Location: $file:$line (indent: $indent)")
+ }
+}
+
+/**
+ * Represents the type of item.
+ */
+enum class ItemType {
+ Class,
+ Field,
+ Method,
+}
+
+/** Holds a field's location. */
+data class FieldInfo (
+ val name: String,
+ val location: Location,
+) {
+ fun dump() {
+ log.i("Field: $name")
+ log.withIndent {
+ location.dump()
+ }
+ }
+}
+
+/** Holds a method's location. */
+data class MethodInfo (
+ val name: String,
+ /** "Simplified" description. */
+ val simpleDesc: String,
+ val location: Location,
+) {
+ fun dump() {
+ log.i("Method: $name$simpleDesc")
+ log.withIndent {
+ location.dump()
+ }
+ }
+}
+
+/** Holds a class's location and members. */
+data class ClassInfo (
+ val fullName: String,
+ val location: Location,
+ val fields: MutableMap<String, FieldInfo> = mutableMapOf(),
+ val methods: MutableMap<String, MutableList<MethodInfo>> = mutableMapOf(),
+) {
+ fun add(fi: FieldInfo) {
+ fields.put(fi.name, fi)
+ }
+
+ fun add(mi: MethodInfo) {
+ val list = methods.get(mi.name)
+ if (list != null) {
+ list.add(mi)
+ } else {
+ methods.put(mi.name, mutableListOf(mi))
+ }
+ }
+
+ fun dump() {
+ log.i("Class: $fullName")
+ log.withIndent {
+ location.dump()
+
+ // Sort and print fields and methods.
+ methods.toSortedMap().forEach { entry ->
+ entry.value.sortedBy { method -> method.simpleDesc }.forEach {
+ it.dump()
+ }
+ }
+ }
+ }
+
+ /** Find a field by name */
+ fun findField(fieldName: String): FieldInfo? {
+ return fields[fieldName]
+ }
+
+ /**
+ * Find a field by name and descriptor.
+ *
+ * If [descriptor] is "*", then all methods with the name will be returned.
+ */
+ fun findMethods(methodName: String, methodDesc: String): List<MethodInfo>? {
+ val list = methods[methodName] ?: return null
+
+ // Wildcard method policy.
+ if (methodDesc == "*") {
+ return list
+ }
+
+ val simpleDesc = simplifyMethodDesc(methodDesc)
+ list.forEach { mi ->
+ if (simpleDesc == mi.simpleDesc) {
+ return listOf(mi)
+ }
+ }
+ log.w("Method $fullName.$methodName found, but none match description '$methodDesc'")
+ return null
+ }
+}
+
+/**
+ * Stores all classes
+ */
+data class AllClassInfo (
+ val classes: MutableMap<String, ClassInfo> = mutableMapOf(),
+) {
+ fun add(ci: ClassInfo) {
+ classes.put(ci.fullName, ci)
+ }
+
+ fun dump() {
+ classes.toSortedMap { a, b -> a.compareTo(b) }.forEach {
+ it.value.dump()
+ }
+ }
+
+ fun findClass(name: String): ClassInfo? {
+ return classes.get(name)
+ }
+}
+
+fun typeToSimpleDesc(origType: String): String {
+ var type = origType
+
+ // Detect arrays.
+ var arrayPrefix = ""
+ while (type.endsWith("[]")) {
+ arrayPrefix += "["
+ type = type.substring(0, type.length - 2)
+ }
+
+ // Delete generic parameters. (delete everything after '<')
+ type.indexOf('<').let { pos ->
+ if (pos >= 0) {
+ type = type.substring(0, pos)
+ }
+ }
+
+ // Handle builtins.
+ val builtinType = when (type) {
+ "byte" -> "B"
+ "short" -> "S"
+ "int" -> "I"
+ "long" -> "J"
+ "float" -> "F"
+ "double" -> "D"
+ "boolean" -> "Z"
+ "char" -> "C"
+ "void" -> "V"
+ else -> null
+ }
+
+ builtinType?.let {
+ return arrayPrefix + builtinType
+ }
+
+ return arrayPrefix + "L" + type + ";"
+}
+
+/**
+ * Get a "simple" description of a method.
+ *
+ * "Simple" descriptions are similar to "real" ones, except:
+ * - No return type.
+ * - No package names in type names.
+ */
+fun getSimpleDesc(method: PsiMethod): String {
+ val sb = StringBuilder()
+
+ sb.append("(")
+
+ val params = method.parameterList
+ for (i in 0..<params.parametersCount) {
+ val param = params.getParameter(i)
+
+ val type = param?.type?.presentableText
+
+ if (type == null) {
+ throw RuntimeException(
+ "Unable to decode parameter list from method from ${params.parent}")
+ }
+
+ sb.append(typeToSimpleDesc(type))
+ }
+
+ sb.append(")")
+
+ return sb.toString()
+}
+
+private val reTypeFinder = "L.*/".toRegex()
+
+private fun simplifyMethodDesc(origMethodDesc: String): String {
+ // We don't need the return type, so remove everything after the ')'.
+ val pos = origMethodDesc.indexOf(')')
+ var desc = if (pos < 0) { origMethodDesc } else { origMethodDesc.substring(0, pos + 1) }
+
+ // Then we remove the package names from all the class names.
+ // i.e. convert "Ljava/lang/String" to "LString".
+
+ return desc.replace(reTypeFinder, "L")
+}
+
+/**
+ * Class that reads and parses java source files using PSI and populate [AllClassInfo].
+ */
+class SourceLoader(
+ val environment: UastEnvironment,
+) {
+ private val fileSystem = StandardFileSystems.local()
+ private val manager = PsiManager.getInstance(environment.ideaProject)
+
+ /** Classes that were parsed */
+ private var numParsedClasses = 0
+
+ /**
+ * Main entry point.
+ */
+ fun load(filesOrDirectories: List<String>, classes: AllClassInfo) {
+ val psiFiles = mutableListOf<PsiFile>()
+ log.i("Loading source files...")
+ log.iTime("Discovering source files") {
+ load(filesOrDirectories.map { File(it) }, psiFiles)
+ }
+
+ log.i("${psiFiles.size} file(s) found.")
+
+ if (psiFiles.size == 0) {
+ throw GeneralUserErrorException("No source files found.")
+ }
+
+ log.iTime("Parsing source files") {
+ log.withIndent {
+ for (file in psiFiles.asSequence().distinct()) {
+ val classesInFile = (file as? PsiClassOwner)?.classes?.toList()
+ classesInFile?.forEach { clazz ->
+ loadClass(clazz)?.let { classes.add(it) }
+
+ clazz.innerClasses.forEach { inner ->
+ loadClass(inner)?.let { classes.add(it) }
+ }
+ }
+ }
+ }
+ }
+ log.i("$numParsedClasses class(es) found.")
+ }
+
+ private fun load(filesOrDirectories: List<File>, result: MutableList<PsiFile>) {
+ filesOrDirectories.forEach {
+ load(it, result)
+ }
+ }
+
+ private fun load(file: File, result: MutableList<PsiFile>) {
+ if (file.isDirectory) {
+ file.listFiles()?.forEach { child ->
+ load(child, result)
+ }
+ return
+ }
+
+ // It's a file
+ when (file.extension) {
+ "java" -> {
+ // Load it.
+ }
+ "kt" -> {
+ log.w("Kotlin not supported, not loading ${file.path}")
+ return
+ }
+ else -> return // Silently skip
+ }
+ fileSystem.findFileByPath(file.path)?.let { virtualFile ->
+ manager.findFile(virtualFile)?.let { psiFile ->
+ result.add(psiFile)
+ }
+ }
+ }
+
+ private fun loadClass(clazz: PsiClass): ClassInfo? {
+ if (clazz is SyntheticElement) {
+ return null
+ }
+ log.forVerbose {
+ log.v("Class found: ${clazz.qualifiedName}")
+ }
+ numParsedClasses++
+
+ log.withIndent {
+ val ci = ClassInfo(
+ clazz.qualifiedName!!,
+ getLocation(clazz) ?: return null,
+ )
+
+ // Load fields.
+ clazz.fields.filter { it !is SyntheticElement }.forEach {
+ val name = it.name
+ log.forDebug { log.d("Field found: $name") }
+ val loc = getLocation(it) ?: return@forEach
+ ci.add(FieldInfo(name, loc))
+ }
+
+ // Load methods.
+ clazz.methods.filter { it !is SyntheticElement }.forEach {
+ val name = resolveMethodName(it)
+ val simpleDesc = getSimpleDesc(it)
+ log.forDebug { log.d("Method found: $name$simpleDesc") }
+ val loc = getLocation(it) ?: return@forEach
+ ci.add(MethodInfo(name, simpleDesc, loc))
+ }
+ return ci
+ }
+ }
+
+ private fun resolveMethodName(method: PsiMethod): String {
+ val clazz = method.containingClass!!
+ if (clazz.name == method.name) {
+ return "<init>" // It's a constructor.
+ }
+ return method.name
+ }
+
+ private fun getLocation(elem: PsiElement): Location? {
+ val lineAndIndent = getLineNumberAndIndent(elem)
+ if (lineAndIndent == null) {
+ log.w("Unable to determine location of $elem")
+ return null
+ }
+ return Location(
+ elem.containingFile.originalFile.virtualFile.path,
+ lineAndIndent.first,
+ lineAndIndent.second,
+ )
+ }
+
+ private fun getLineNumberAndIndent(element: PsiElement): Pair<Int, Int>? {
+ val psiFile: PsiFile = element.containingFile ?: return null
+ val document: Document = psiFile.viewProvider.document ?: return null
+
+ // Actual elements such as PsiClass, PsiMethod and PsiField contains the leading
+ // javadoc, etc, so use the "identifier"'s element, if available.
+ // For synthesized elements, this may return null.
+ val targetRange = (
+ (element as PsiNameIdentifierOwner).nameIdentifier?.textRange ?: element.textRange
+ ) ?: return null
+ val lineNumber = document.getLineNumber(targetRange.startOffset)
+ val lineStartOffset = document.getLineStartOffset(lineNumber)
+
+ val lineLeadingText = document.getText(
+ com.intellij.openapi.util.TextRange(lineStartOffset, targetRange.startOffset))
+
+ val indent = lineLeadingText.takeWhile { it.isWhitespace() }.length
+
+ // Line numbers are 0-based, add 1 for human-readable format
+ return Pair(lineNumber + 1, indent)
+ }
+} \ No newline at end of file
diff --git a/nfc/java/android/nfc/IAppCallback.aidl b/ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt
index b06bf06d5197..203fab1544c9 100644
--- a/nfc/java/android/nfc/IAppCallback.aidl
+++ b/ravenwood/tools/ravenhelper/test/com/android/platform/test/ravenwood/ravenhelper/RavenhelperTest.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2025 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.
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package com.android.platform.test.ravenwood.ravenhelper
-package android.nfc;
+import com.android.platform.test.ravenwood.ravenhelper.psi.createUastEnvironment
+import org.junit.Test
-import android.nfc.Tag;
-
-/**
- * @hide
- */
-interface IAppCallback
-{
- oneway void onTagDiscovered(in Tag tag);
-}
+class RavenhelperTest {
+ @Test
+ fun testPsiInitialization() {
+ val env = createUastEnvironment()
+ env.dispose()
+ }
+} \ No newline at end of file
diff --git a/ravenwood/tools/ravenizer/Android.bp b/ravenwood/tools/ravenizer/Android.bp
index 2892d0778ec6..a52a04b44f2d 100644
--- a/ravenwood/tools/ravenizer/Android.bp
+++ b/ravenwood/tools/ravenizer/Android.bp
@@ -19,7 +19,7 @@ java_binary_host {
"ow2-asm-tree",
"ow2-asm-util",
"junit",
- "ravenwood-junit-impl-for-ravenizer",
+ "ravenwood-junit-for-ravenizer",
],
visibility: ["//visibility:public"],
}
diff --git a/services/Android.bp b/services/Android.bp
index a7cb9bb9af24..473911f08cf7 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -312,9 +312,11 @@ system_java_library {
"services.wifi",
"service-blobstore",
"service-jobscheduler",
- "service-connectivity-b-pre-jarjar", // Move it to mainline module
"android.hidl.base-V1.0-java",
- ],
+ ] + select(release_flag("RELEASE_MOVE_VCN_TO_MAINLINE"), {
+ true: [],
+ default: ["service-connectivity-b-platform"],
+ }),
libs: [
"android.hidl.manager-V1.0-java",
diff --git a/services/accessibility/OWNERS b/services/accessibility/OWNERS
index 4e1175034b5b..ab1e9ffe3bfe 100644
--- a/services/accessibility/OWNERS
+++ b/services/accessibility/OWNERS
@@ -1,4 +1,7 @@
-# Bug component: 44215
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
# Android Accessibility Framework owners
danielnorman@google.com
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 3441d94facda..9ceca5d1dbfe 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -1589,7 +1589,13 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
* lock because this calls out to WindowManagerService.
*/
void addWindowTokensForAllDisplays() {
- final Display[] displays = mDisplayManager.getDisplays();
+ Display[] displays = {};
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ displays = mDisplayManager.getDisplays();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
for (int i = 0; i < displays.length; i++) {
final int displayId = displays[i].getDisplayId();
addWindowTokenForDisplay(displayId);
@@ -1625,7 +1631,13 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
public void onRemoved() {
- final Display[] displays = mDisplayManager.getDisplays();
+ Display[] displays = {};
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ displays = mDisplayManager.getDisplays();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
for (int i = 0; i < displays.length; i++) {
final int displayId = displays[i].getDisplayId();
onDisplayRemoved(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/OWNERS b/services/accessibility/java/com/android/server/accessibility/magnification/OWNERS
new file mode 100644
index 000000000000..ff812ad7e7e6
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/OWNERS
@@ -0,0 +1,8 @@
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 770744.
+
+juchengchou@google.com
+chenjean@google.com
+chihtinglo@google.com
diff --git a/services/art-wear-profile b/services/art-wear-profile
index 1e3090f9bf00..f080715643ca 100644
--- a/services/art-wear-profile
+++ b/services/art-wear-profile
@@ -7419,7 +7419,7 @@ PLcom/android/server/app/GameManagerService;->sendUserMessage(IILjava/lang/Strin
PLcom/android/server/app/GameManagerService;->updateConfigsForUser(IZ[Ljava/lang/String;)V
PLcom/android/server/app/GameManagerService;->writeGameModeInterventionsToFile(I)V
PLcom/android/server/app/GameManagerSettings;-><init>(Ljava/io/File;)V
-HPLcom/android/server/app/GameManagerSettings;->getConfigOverride(Ljava/lang/String;)Lcom/android/server/app/GameManagerService$GamePackageConfiguration;
+HPLcom/android/server/app/GameManagerSettings;->getConfigOverrideLocked(Ljava/lang/String;)Lcom/android/server/app/GameManagerService$GamePackageConfiguration;
HPLcom/android/server/app/GameManagerSettings;->getGameModeLocked(Ljava/lang/String;)I
PLcom/android/server/app/GameManagerSettings;->readPersistentDataLocked()Z
PLcom/android/server/appbinding/AppBindingConstants;-><init>(Ljava/lang/String;)V
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 6729231d68ab..e631403a9972 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -855,13 +855,12 @@ public class VirtualDeviceManagerService extends SystemService {
@Override
public void onAuthenticationPrompt(int uid) {
- synchronized (mVirtualDeviceManagerLock) {
- for (int i = 0; i < mVirtualDevices.size(); i++) {
- VirtualDeviceImpl device = mVirtualDevices.valueAt(i);
- device.showToastWhereUidIsRunning(uid,
- R.string.app_streaming_blocked_message_for_fingerprint_dialog,
- Toast.LENGTH_LONG, Looper.getMainLooper());
- }
+ ArrayList<VirtualDeviceImpl> virtualDevicesSnapshot = getVirtualDevicesSnapshot();
+ for (int i = 0; i < virtualDevicesSnapshot.size(); i++) {
+ VirtualDeviceImpl device = virtualDevicesSnapshot.get(i);
+ device.showToastWhereUidIsRunning(uid,
+ R.string.app_streaming_blocked_message_for_fingerprint_dialog,
+ Toast.LENGTH_LONG, Looper.getMainLooper());
}
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index b3d85f8aac48..34a47ac4b416 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -37,6 +37,7 @@ filegroup {
":framework_native_aidl",
":gsiservice_aidl",
":installd_aidl",
+ ":mmd_aidl",
":storaged_aidl",
":vold_aidl",
],
@@ -149,6 +150,9 @@ java_library_static {
// Java/AIDL sources to be moved out to CrashRecovery module
":services-crashrecovery-sources",
+
+ // Indicate whether VCN is in platform or mainline
+ ":vcn-location-sources",
],
libs: [
@@ -244,6 +248,8 @@ java_library_static {
"aconfig_new_storage_flags_lib",
"powerstats_flags_lib",
"locksettings_flags_lib",
+ "MmdProperties",
+ "mmd_flags_lib",
"profiling_flags_lib",
"android.adpf.sessionmanager_aidl-java",
"uprobestats_flags_java_lib",
@@ -284,9 +290,15 @@ java_genrule {
out: ["services.core.priorityboosted.jar"],
}
+java_genrule_combiner {
+ name: "services.core.combined",
+ static_libs: ["services.core.priorityboosted"],
+ headers: ["services.core.unboosted"],
+}
+
java_library {
name: "services.core",
- static_libs: ["services.core.priorityboosted"],
+ static_libs: ["services.core.combined"],
}
java_library_host {
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 36dff89d9d61..ec0e57a2ccf0 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -1697,7 +1697,7 @@ public class BinaryTransparencyService extends SystemService {
private class PackageUpdatedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- if (!intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
+ if (!Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
return;
}
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 1588e0421675..4713a8d23b18 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -50,6 +50,7 @@ import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.am.DropboxRateLimiter;
+import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -148,6 +149,10 @@ public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
+ if (!Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
+ return;
+ }
+
// Log boot events in the background to avoid blocking the main thread with I/O
new Thread() {
@Override
@@ -213,6 +218,8 @@ public class BootReceiver extends BroadcastReceiver {
} catch (Exception e) {
Slog.wtf(TAG, "Error watching for trace events", e);
return 0; // Unregister the handler.
+ } finally {
+ IoUtils.closeQuietly(fd);
}
return OnFileDescriptorEventListener.EVENT_INPUT;
}
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index c15cf34b8955..6858e2941ff9 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -31,6 +31,7 @@ per-file *Storage* = file:/core/java/android/os/storage/OWNERS
per-file *TimeUpdate* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
per-file DynamicSystemService.java = file:/packages/DynamicSystemInstallationService/OWNERS
per-file GestureLauncherService.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
+per-file GestureLauncherService.java = file:/INPUT_OWNERS
per-file MmsServiceBroker.java = file:/telephony/OWNERS
per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
per-file PackageWatchdog.java = file:/services/core/java/com/android/server/crashrecovery/OWNERS
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index b7bc4e4827ef..350ecab1dd5f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -41,6 +41,7 @@ import static android.os.storage.OnObbStateChangeListener.ERROR_NOT_MOUNTED;
import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED;
import static android.os.storage.OnObbStateChangeListener.MOUNTED;
import static android.os.storage.OnObbStateChangeListener.UNMOUNTED;
+import static android.mmd.flags.Flags.mmdEnabled;
import static com.android.internal.util.XmlUtils.readStringAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
@@ -126,6 +127,7 @@ import android.provider.Downloads;
import android.provider.MediaStore;
import android.provider.Settings;
import android.service.storage.ExternalStorageService;
+import android.sysprop.MmdProperties;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
@@ -155,6 +157,7 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.memory.ZramMaintenance;
import com.android.server.pm.Installer;
import com.android.server.pm.UserManagerInternal;
import com.android.server.storage.AppFuseBridge;
@@ -933,24 +936,28 @@ class StorageManagerService extends IStorageManager.Stub
// Start scheduling nominally-daily fstrim operations
MountServiceIdler.scheduleIdlePass(mContext);
- // Toggle zram-enable system property in response to settings
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.ZRAM_ENABLED),
- false /*notifyForDescendants*/,
- new ContentObserver(null /* current thread */) {
- @Override
- public void onChange(boolean selfChange) {
- refreshZramSettings();
- }
- });
- refreshZramSettings();
+ if (mmdEnabled() && MmdProperties.mmd_zram_enabled().orElse(false)) {
+ ZramMaintenance.startZramMaintenance(mContext);
+ } else {
+ // Toggle zram-enable system property in response to settings
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ZRAM_ENABLED),
+ false /*notifyForDescendants*/,
+ new ContentObserver(null /* current thread */) {
+ @Override
+ public void onChange(boolean selfChange) {
+ refreshZramSettings();
+ }
+ });
+ refreshZramSettings();
- // Schedule zram writeback unless zram is disabled by persist.sys.zram_enabled
- String zramPropValue = SystemProperties.get(ZRAM_ENABLED_PROPERTY);
- if (!zramPropValue.equals("0")
- && mContext.getResources().getBoolean(
+ // Schedule zram writeback unless zram is disabled by persist.sys.zram_enabled
+ String zramPropValue = SystemProperties.get(ZRAM_ENABLED_PROPERTY);
+ if (!zramPropValue.equals("0")
+ && mContext.getResources().getBoolean(
com.android.internal.R.bool.config_zramWriteback)) {
- ZramWriteback.scheduleZramWriteback(mContext);
+ ZramWriteback.scheduleZramWriteback(mContext);
+ }
}
configureTranscoding();
diff --git a/services/core/java/com/android/server/SystemTimeZone.java b/services/core/java/com/android/server/SystemTimeZone.java
index dd07081bda12..c8810f672320 100644
--- a/services/core/java/com/android/server/SystemTimeZone.java
+++ b/services/core/java/com/android/server/SystemTimeZone.java
@@ -133,6 +133,7 @@ public final class SystemTimeZone {
boolean timeZoneChanged = false;
synchronized (SystemTimeZone.class) {
String currentTimeZoneId = getTimeZoneId();
+ @TimeZoneConfidence int currentConfidence = getTimeZoneConfidence();
if (currentTimeZoneId == null || !currentTimeZoneId.equals(timeZoneId)) {
SystemProperties.set(TIME_ZONE_SYSTEM_PROPERTY, timeZoneId);
if (DEBUG) {
@@ -145,6 +146,8 @@ public final class SystemTimeZone {
String logMsg = "Time zone or confidence set: "
+ " (new) timeZoneId=" + timeZoneId
+ ", (new) confidence=" + confidence
+ + ", (old) timeZoneId=" + currentTimeZoneId
+ + ", (old) confidence=" + currentConfidence
+ ", logInfo=" + logInfo;
addDebugLogEntry(logMsg);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cd929c1883d0..ce8dd66c1011 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12851,6 +12851,28 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ final long kernelCmaUsage = Debug.getKernelCmaUsageKb();
+ if (kernelCmaUsage >= 0) {
+ pw.print(" Kernel CMA: ");
+ pw.println(stringifyKBSize(kernelCmaUsage));
+ // CMA memory can be in one of the following four states:
+ //
+ // 1. Free, in which case it is accounted for as part of MemFree, which
+ // is already considered in the lostRAM calculation below.
+ //
+ // 2. Allocated as part of a userspace allocated, in which case it is
+ // already accounted for in the total PSS value that was computed.
+ //
+ // 3. Allocated for storing compressed memory (ZRAM) on Android kernels.
+ // This is accounted for by calculating the amount of memory ZRAM
+ // consumes and including it in the lostRAM calculuation.
+ //
+ // 4. Allocated by a kernel driver, in which case, it is currently not
+ // attributed to any term that has been derived thus far. Since the
+ // allocations come from a kernel driver, add it to kernelUsed.
+ kernelUsed += kernelCmaUsage;
+ }
+
// Note: ION/DMA-BUF heap pools are reclaimable and hence, they are included as part of
// memInfo.getCachedSizeKb().
final long lostRAM = memInfo.getTotalSizeKb()
@@ -13368,12 +13390,32 @@ public class ActivityManagerService extends IActivityManager.Stub
proto.write(MemInfoDumpProto.CACHED_KERNEL_KB, memInfo.getCachedSizeKb());
proto.write(MemInfoDumpProto.FREE_KB, memInfo.getFreeSizeKb());
}
+ // CMA memory can be in one of the following four states:
+ //
+ // 1. Free, in which case it is accounted for as part of MemFree, which
+ // is already considered in the lostRAM calculation below.
+ //
+ // 2. Allocated as part of a userspace allocated, in which case it is
+ // already accounted for in the total PSS value that was computed.
+ //
+ // 3. Allocated for storing compressed memory (ZRAM) on Android Kernels.
+ // This is accounted for by calculating hte amount of memory ZRAM
+ // consumes and including it in the lostRAM calculation.
+ //
+ // 4. Allocated by a kernel driver, in which case, it is currently not
+ // attributed to any term that has been derived thus far, so subtract
+ // it from lostRAM.
+ long kernelCmaUsage = Debug.getKernelCmaUsageKb();
+ if (kernelCmaUsage < 0) {
+ kernelCmaUsage = 0;
+ }
long lostRAM = memInfo.getTotalSizeKb()
- (ss[INDEX_TOTAL_PSS] - ss[INDEX_TOTAL_SWAP_PSS])
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
// NR_SHMEM is subtracted twice (getCachedSizeKb() and getKernelUsedSizeKb())
+ memInfo.getShmemSizeKb()
- - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
+ - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()
+ - kernelCmaUsage;
proto.write(MemInfoDumpProto.USED_PSS_KB, ss[INDEX_TOTAL_PSS] - cachedPss);
proto.write(MemInfoDumpProto.USED_KERNEL_KB, memInfo.getKernelUsedSizeKb());
proto.write(MemInfoDumpProto.LOST_RAM_KB, lostRAM);
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 374abe0256c1..0bc816e78e7b 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -818,8 +818,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println("APP BATTERY STATE TRACKER:");
- // Force an update.
- updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+ if (mInjector.getActivityManagerInternal().isBooted()) {
+ // Force an update.
+ updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+ }
// Force a check.
scheduleBgBatteryUsageStatsCheck();
// Wait for its completion (as it runs in handler thread for the sake of thread safe)
@@ -878,8 +880,10 @@ final class AppBatteryTracker extends BaseAppStateTracker<AppBatteryPolicy>
@Override
void dumpAsProto(ProtoOutputStream proto, int uid) {
- // Force an update.
- updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+ if (mInjector.getActivityManagerInternal().isBooted()) {
+ // Force an update.
+ updateBatteryUsageStatsIfNecessary(mInjector.currentTimeMillis(), true);
+ }
synchronized (mLock) {
final SparseArray<ImmutableBatteryUsage> uidConsumers = mUidBatteryUsageInWindow;
if (uid != android.os.Process.INVALID_UID) {
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index 6e09a84e0f8c..e4e53f4124f3 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -1434,7 +1434,7 @@ public class ContentProviderHelper {
}
}
}
- } catch (RemoteException ignored) {
+ } catch (RemoteException|SecurityException ignored) {
}
});
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 1a6051b6ac9c..4b6d6bc955cc 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -21,6 +21,7 @@ per-file FgsTempAllowList.java = file:/ACTIVITY_MANAGER_OWNERS
per-file HostingRecord.java = file:/ACTIVITY_MANAGER_OWNERS
per-file App*ExitInfo* = file:/ACTIVITY_MANAGER_OWNERS
per-file appexitinfo.proto = file:/ACTIVITY_MANAGER_OWNERS
+per-file UidObserverController* = file:/ACTIVITY_MANAGER_OWNERS
per-file App*StartInfo* = file:/PERFORMANCE_OWNERS
per-file appstartinfo.proto = file:/PERFORMANCE_OWNERS
@@ -67,7 +68,7 @@ per-file CarUserSwitchingDialog.java = file:platform/packages/services/Car:/OWNE
per-file ActivityManager* = file:/ACTIVITY_SECURITY_OWNERS
# Aconfig Flags
-per-file flags.aconfig = yamasani@google.com, bills@google.com, nalini@google.com
+per-file flags.aconfig = yamasani@google.com, nalini@google.com
# Londoners
michaelwr@google.com #{LAST_RESORT_SUGGESTION}
@@ -76,4 +77,4 @@ narayan@google.com #{LAST_RESORT_SUGGESTION}
# Default
yamasani@google.com
hackbod@google.com #{LAST_RESORT_SUGGESTION}
-omakoto@google.com #{LAST_RESORT_SUGGESTION} \ No newline at end of file
+omakoto@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index 123780fb7567..99bdd10ff71b 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -112,23 +112,10 @@ public final class PhantomProcessList {
private final ActivityManagerService mService;
private final Handler mKillHandler;
- private static final int CGROUP_V1 = 0;
- private static final int CGROUP_V2 = 1;
- private static final String[] CGROUP_PATH_PREFIXES = {
- "/acct/uid_" /* cgroup v1 */,
- "/sys/fs/cgroup/uid_" /* cgroup v2 */
- };
- private static final String CGROUP_PID_PREFIX = "/pid_";
- private static final String CGROUP_PROCS = "/cgroup.procs";
-
- @VisibleForTesting
- int mCgroupVersion = CGROUP_V1;
-
PhantomProcessList(final ActivityManagerService service) {
mService = service;
mKillHandler = service.mProcessList.sKillHandler;
mInjector = new Injector();
- probeCgroupVersion();
}
@VisibleForTesting
@@ -157,9 +144,15 @@ public final class PhantomProcessList {
final int appPid = app.getPid();
InputStream input = mCgroupProcsFds.get(appPid);
if (input == null) {
- final String path = getCgroupFilePath(app.info.uid, appPid);
+ String path = null;
try {
+ path = getCgroupFilePath(app.info.uid, appPid);
input = mInjector.openCgroupProcs(path);
+ } catch (IllegalArgumentException e) {
+ if (DEBUG_PROCESSES) {
+ Slog.w(TAG, "Unable to obtain cgroup.procs path ", e);
+ }
+ return;
} catch (FileNotFoundException | SecurityException e) {
if (DEBUG_PROCESSES) {
Slog.w(TAG, "Unable to open " + path, e);
@@ -207,18 +200,9 @@ public final class PhantomProcessList {
}
}
- private void probeCgroupVersion() {
- for (int i = CGROUP_PATH_PREFIXES.length - 1; i >= 0; i--) {
- if ((new File(CGROUP_PATH_PREFIXES[i] + Process.SYSTEM_UID)).exists()) {
- mCgroupVersion = i;
- break;
- }
- }
- }
-
@VisibleForTesting
String getCgroupFilePath(int uid, int pid) {
- return CGROUP_PATH_PREFIXES[mCgroupVersion] + uid + CGROUP_PID_PREFIX + pid + CGROUP_PROCS;
+ return nativeGetCgroupProcsPath(uid, pid);
}
static String getProcessName(int pid) {
@@ -630,4 +614,7 @@ public final class PhantomProcessList {
return PhantomProcessList.getProcessName(pid);
}
}
+
+ private static native String nativeGetCgroupProcsPath(int uid, int pid)
+ throws IllegalArgumentException;
}
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 87f87c76725e..2905403931ab 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -115,6 +115,7 @@ public class SettingsToPropertiesMapper {
DeviceConfig.NAMESPACE_LMKD_NATIVE,
DeviceConfig.NAMESPACE_MEDIA_NATIVE,
DeviceConfig.NAMESPACE_MGLRU_NATIVE,
+ DeviceConfig.NAMESPACE_MMD_NATIVE,
DeviceConfig.NAMESPACE_NETD_NATIVE,
DeviceConfig.NAMESPACE_NNAPI_NATIVE,
DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java
index 7eeec32cf24a..f13bfac58e77 100644
--- a/services/core/java/com/android/server/am/UidObserverController.java
+++ b/services/core/java/com/android/server/am/UidObserverController.java
@@ -77,6 +77,7 @@ public class UidObserverController {
* This is for verifying the UID report flow.
*/
private static final boolean VALIDATE_UID_STATES = true;
+ @GuardedBy("mLock")
private final ActiveUids mValidateUids;
UidObserverController(@NonNull Handler handler) {
@@ -282,31 +283,30 @@ public class UidObserverController {
}
mUidObservers.finishBroadcast();
- if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
- for (int j = 0; j < numUidChanges; ++j) {
- final ChangeRecord item = mActiveUidChanges[j];
- if ((item.change & UidRecord.CHANGE_GONE) != 0) {
- mValidateUids.remove(item.uid);
- } else {
- UidRecord validateUid = mValidateUids.get(item.uid);
- if (validateUid == null) {
- validateUid = new UidRecord(item.uid, null);
- mValidateUids.put(item.uid, validateUid);
- }
- if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
- validateUid.setIdle(true);
- } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
- validateUid.setIdle(false);
+ synchronized (mLock) {
+ if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
+ for (int j = 0; j < numUidChanges; ++j) {
+ final ChangeRecord item = mActiveUidChanges[j];
+ if ((item.change & UidRecord.CHANGE_GONE) != 0) {
+ mValidateUids.remove(item.uid);
+ } else {
+ UidRecord validateUid = mValidateUids.get(item.uid);
+ if (validateUid == null) {
+ validateUid = new UidRecord(item.uid, null);
+ mValidateUids.put(item.uid, validateUid);
+ }
+ if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
+ validateUid.setIdle(true);
+ } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
+ validateUid.setIdle(false);
+ }
+ validateUid.setSetProcState(item.procState);
+ validateUid.setCurProcState(item.procState);
+ validateUid.setSetCapability(item.capability);
+ validateUid.setCurCapability(item.capability);
}
- validateUid.setSetProcState(item.procState);
- validateUid.setCurProcState(item.procState);
- validateUid.setSetCapability(item.capability);
- validateUid.setCurCapability(item.capability);
}
}
- }
-
- synchronized (mLock) {
for (int j = 0; j < numUidChanges; j++) {
final ChangeRecord changeRecord = mActiveUidChanges[j];
changeRecord.isPending = false;
@@ -433,7 +433,9 @@ public class UidObserverController {
}
UidRecord getValidateUidRecord(int uid) {
- return mValidateUids.get(uid);
+ synchronized (mLock) {
+ return mValidateUids.get(uid);
+ }
}
void dump(@NonNull PrintWriter pw, @Nullable String dumpPackage) {
@@ -488,12 +490,16 @@ public class UidObserverController {
boolean dumpValidateUids(@NonNull PrintWriter pw, @Nullable String dumpPackage, int dumpAppId,
@NonNull String header, boolean needSep) {
- return mValidateUids.dump(pw, dumpPackage, dumpAppId, header, needSep);
+ synchronized (mLock) {
+ return mValidateUids.dump(pw, dumpPackage, dumpAppId, header, needSep);
+ }
}
void dumpValidateUidsProto(@NonNull ProtoOutputStream proto, @Nullable String dumpPackage,
int dumpAppId, long fieldId) {
- mValidateUids.dumpProto(proto, dumpPackage, dumpAppId, fieldId);
+ synchronized (mLock) {
+ mValidateUids.dumpProto(proto, dumpPackage, dumpAppId, fieldId);
+ }
}
static final class ChangeRecord {
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index 6f8dc105850d..c0a97db7275b 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -1423,10 +1423,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
final GameManagerSettings settings = mSettings.get(userId);
// look for the existing GamePackageConfiguration override
- configOverride = settings.getConfigOverride(packageName);
+ configOverride = settings.getConfigOverrideLocked(packageName);
if (configOverride == null) {
configOverride = new GamePackageConfiguration(packageName);
- settings.setConfigOverride(packageName, configOverride);
+ settings.setConfigOverrideLocked(packageName, configOverride);
}
}
GamePackageConfiguration.GameModeConfiguration internalConfig =
@@ -1759,10 +1759,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
final GameManagerSettings settings = mSettings.get(userId);
// look for the existing GamePackageConfiguration override
- configOverride = settings.getConfigOverride(packageName);
+ configOverride = settings.getConfigOverrideLocked(packageName);
if (configOverride == null) {
configOverride = new GamePackageConfiguration(packageName);
- settings.setConfigOverride(packageName, configOverride);
+ settings.setConfigOverrideLocked(packageName, configOverride);
}
}
// modify GameModeConfiguration intervention settings
@@ -1801,7 +1801,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
final GameManagerSettings settings = mSettings.get(userId);
if (gameModeToReset != -1) {
- final GamePackageConfiguration configOverride = settings.getConfigOverride(
+ final GamePackageConfiguration configOverride = settings.getConfigOverrideLocked(
packageName);
if (configOverride == null) {
return;
@@ -1812,10 +1812,10 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
configOverride.removeModeConfig(gameModeToReset);
if (!configOverride.hasActiveGameModeConfig()) {
- settings.removeConfigOverride(packageName);
+ settings.removeConfigOverrideLocked(packageName);
}
} else {
- settings.removeConfigOverride(packageName);
+ settings.removeConfigOverrideLocked(packageName);
}
}
@@ -2030,7 +2030,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
synchronized (mLock) {
if (mSettings.containsKey(userId)) {
- overrideConfig = mSettings.get(userId).getConfigOverride(packageName);
+ overrideConfig = mSettings.get(userId).getConfigOverrideLocked(packageName);
}
}
if (overrideConfig == null || config == null) {
@@ -2075,7 +2075,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
synchronized (mLock) {
if (mSettings.containsKey(userId)) {
- mSettings.get(userId).removeGame(packageName);
+ mSettings.get(userId).removeGameLocked(packageName);
}
sendUserMessage(userId, WRITE_SETTINGS,
Intent.ACTION_PACKAGE_REMOVED, WRITE_DELAY_MILLIS);
diff --git a/services/core/java/com/android/server/app/GameManagerSettings.java b/services/core/java/com/android/server/app/GameManagerSettings.java
index b084cf3c3b12..c57a1f73d7d7 100644
--- a/services/core/java/com/android/server/app/GameManagerSettings.java
+++ b/services/core/java/com/android/server/app/GameManagerSettings.java
@@ -116,7 +116,7 @@ public class GameManagerSettings {
* Removes all game settings of a given package.
* This operation must be synced with an external lock.
*/
- void removeGame(String packageName) {
+ void removeGameLocked(String packageName) {
mGameModes.remove(packageName);
mConfigOverrides.remove(packageName);
}
@@ -125,7 +125,7 @@ public class GameManagerSettings {
* Returns the game config override of a given package or null if absent.
* This operation must be synced with an external lock.
*/
- GamePackageConfiguration getConfigOverride(String packageName) {
+ GamePackageConfiguration getConfigOverrideLocked(String packageName) {
return mConfigOverrides.get(packageName);
}
@@ -133,7 +133,7 @@ public class GameManagerSettings {
* Sets the game config override of a given package.
* This operation must be synced with an external lock.
*/
- void setConfigOverride(String packageName, GamePackageConfiguration configOverride) {
+ void setConfigOverrideLocked(String packageName, GamePackageConfiguration configOverride) {
mConfigOverrides.put(packageName, configOverride);
}
@@ -141,7 +141,7 @@ public class GameManagerSettings {
* Removes the game mode config override of a given package.
* This operation must be synced with an external lock.
*/
- void removeConfigOverride(String packageName) {
+ void removeConfigOverrideLocked(String packageName) {
mConfigOverrides.remove(packageName);
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 06c586f5e9c2..144799383fbb 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2587,7 +2587,6 @@ public class AppOpsService extends IAppOpsService.Stub {
Map<String, Ops> packages = uidState.pkgOps;
Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
- boolean uidChanged = false;
while (it.hasNext()) {
Map.Entry<String, Ops> ent = it.next();
String packageName = ent.getKey();
@@ -2620,7 +2619,6 @@ public class AppOpsService extends IAppOpsService.Stub {
newMode,
UserHandle.getUserId(curOp.uid));
changed = true;
- uidChanged = true;
final int uid = curOp.uidState.uid;
callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
previousMode, mOpModeWatchers.get(curOp.op));
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 09b8e212bfad..3cc89a5744c7 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -11820,7 +11820,7 @@ public class AudioService extends IAudioService.Stub
private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked(
AudioDeviceAttributes ada) {
- if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) {
+ if (ada == null || !AudioSystem.isBluetoothDevice(ada.getInternalType())) {
return ada;
}
AudioDeviceAttributes res = new AudioDeviceAttributes(ada);
@@ -12928,10 +12928,10 @@ public class AudioService extends IAudioService.Stub
int uid = intent.getIntExtra(Intent.EXTRA_UID, Process.INVALID_UID);
if (intent.getBooleanExtra(EXTRA_REPLACING, false) ||
intent.getBooleanExtra(EXTRA_ARCHIVAL, false)) return;
- if (action.equals(ACTION_PACKAGE_ADDED)) {
+ if (ACTION_PACKAGE_ADDED.equals(action)) {
audioserverExecutor.execute(() ->
provider.onModifyPackageState(uid, pkgName, false /* isRemoved */));
- } else if (action.equals(ACTION_PACKAGE_REMOVED)) {
+ } else if (ACTION_PACKAGE_REMOVED.equals(action)) {
audioserverExecutor.execute(() ->
provider.onModifyPackageState(uid, pkgName, true /* isRemoved */));
}
@@ -14575,6 +14575,7 @@ public class AudioService extends IAudioService.Stub
for (AudioMix mix : mMixes) {
mix.setVirtualDeviceId(mAttributionSource.getDeviceId());
}
+ mAudioSystem.registerPolicyMixes(mMixes, false);
return mAudioSystem.registerPolicyMixes(mMixes, true);
} finally {
Binder.restoreCallingIdentity(identity);
@@ -15099,11 +15100,13 @@ public class AudioService extends IAudioService.Stub
final String key = "additional_output_device_delay";
final String reply = AudioSystem.getParameters(
key + "=" + device.getInternalType() + "," + device.getAddress());
- long delayMillis;
- try {
- delayMillis = Long.parseLong(reply.substring(key.length() + 1));
- } catch (NullPointerException e) {
- delayMillis = 0;
+ long delayMillis = 0;
+ if (reply.contains(key)) {
+ try {
+ delayMillis = Long.parseLong(reply.substring(key.length() + 1));
+ } catch (NullPointerException e) {
+ delayMillis = 0;
+ }
}
return delayMillis;
}
@@ -15129,11 +15132,13 @@ public class AudioService extends IAudioService.Stub
final String key = "max_additional_output_device_delay";
final String reply = AudioSystem.getParameters(
key + "=" + device.getInternalType() + "," + device.getAddress());
- long delayMillis;
- try {
- delayMillis = Long.parseLong(reply.substring(key.length() + 1));
- } catch (NullPointerException e) {
- delayMillis = 0;
+ long delayMillis = 0;
+ if (reply.contains(key)) {
+ try {
+ delayMillis = Long.parseLong(reply.substring(key.length() + 1));
+ } catch (NullPointerException e) {
+ delayMillis = 0;
+ }
}
return delayMillis;
}
diff --git a/services/core/java/com/android/server/audio/FadeOutManager.java b/services/core/java/com/android/server/audio/FadeOutManager.java
index 4d5bce559a91..fedfe511b747 100644
--- a/services/core/java/com/android/server/audio/FadeOutManager.java
+++ b/services/core/java/com/android/server/audio/FadeOutManager.java
@@ -199,7 +199,9 @@ public final class FadeOutManager {
for (AudioPlaybackConfiguration apc : players) {
final VolumeShaper.Configuration volShaper =
mFadeConfigurations.getFadeOutVolumeShaperConfig(apc.getAudioAttributes());
- fa.addFade(apc, /* skipRamp= */ false, volShaper);
+ if (volShaper != null) {
+ fa.addFade(apc, /* skipRamp= */ false, volShaper);
+ }
}
}
}
@@ -249,7 +251,7 @@ public final class FadeOutManager {
final VolumeShaper.Configuration volShaper =
mFadeConfigurations.getFadeOutVolumeShaperConfig(apc.getAudioAttributes());
final FadedOutApp fa = mUidToFadedAppsMap.get(apc.getClientUid());
- if (fa == null) {
+ if (fa == null || volShaper == null) {
return;
}
fa.addFade(apc, /* skipRamp= */ true, volShaper);
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 2d802b21cf03..b6768c9c087a 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -38,7 +38,6 @@ import android.hardware.biometrics.AuthenticationStateListener;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.ComponentInfoInternal;
-import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IAuthService;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricService;
@@ -399,12 +398,6 @@ public class AuthService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
- // We can't do this above because we need the READ_DEVICE_CONFIG permission, which
- // the calling user may not possess.
- if (!Flags.lastAuthenticationTime()) {
- throw new UnsupportedOperationException();
- }
-
return mBiometricService.getLastAuthenticationTime(userId, authenticators);
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index b365ef7ff61c..402448209860 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -43,7 +43,6 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricStateListener;
-import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -100,8 +99,8 @@ import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
/**
@@ -810,10 +809,6 @@ public class BiometricService extends SystemService {
int userId, @Authenticators.Types int authenticators) {
super.getLastAuthenticationTime_enforcePermission();
- if (!Flags.lastAuthenticationTime()) {
- throw new UnsupportedOperationException();
- }
-
Slogf.d(TAG, "getLastAuthenticationTime(userId=%d, authenticators=0x%x)",
userId, authenticators);
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index e89f43bd7196..20c33275b8f1 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -876,7 +876,28 @@ final class CompatConfig {
}
@Nullable
+ @android.ravenwood.annotation.RavenwoodReplace(
+ blockedBy = PackageManager.class,
+ reason = "PackageManager.getApplicationInfo() isn't supported yet")
private Long getVersionCodeOrNull(String packageName) {
+ return getVersionCodeOrNullImpl(packageName);
+ }
+
+ @SuppressWarnings("unused")
+ @Nullable
+ private Long getVersionCodeOrNull$ravenwood(String packageName) {
+ try {
+ // It's possible that the context is mocked, try the real method first
+ return getVersionCodeOrNullImpl(packageName);
+ } catch (Throwable e) {
+ // For now, Ravenwood doesn't support the concept of "app updates", so let's
+ // just use a fixed version code for all packages.
+ return 1L;
+ }
+ }
+
+ @Nullable
+ private Long getVersionCodeOrNullImpl(String packageName) {
try {
ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
packageName, MATCH_ANY_USER);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4c5f65285a9e..ac0892b92646 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1960,6 +1960,10 @@ public class Vpn {
public void onUserAdded(int userId) {
// If the user is restricted tie them to the parent user's VPN
UserInfo user = mUserManager.getUserInfo(userId);
+ if (user == null) {
+ Log.e(TAG, "Can not retrieve UserInfo for userId=" + userId);
+ return;
+ }
if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
synchronized(Vpn.this) {
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
@@ -1989,6 +1993,14 @@ public class Vpn {
public void onUserRemoved(int userId) {
// clean up if restricted
UserInfo user = mUserManager.getUserInfo(userId);
+ // TODO: Retrieving UserInfo upon receiving the USER_REMOVED intent is not guaranteed.
+ // This could prevent the removal of associated ranges. To ensure proper range removal,
+ // store the user info when adding ranges. This allows using the user ID in the
+ // USER_REMOVED intent to handle the removal process.
+ if (user == null) {
+ Log.e(TAG, "Can not retrieve UserInfo for userId=" + userId);
+ return;
+ }
if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
synchronized(Vpn.this) {
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
diff --git a/services/core/java/com/android/server/crashrecovery/OWNERS b/services/core/java/com/android/server/crashrecovery/OWNERS
index daa02111f71f..02df9860030d 100644
--- a/services/core/java/com/android/server/crashrecovery/OWNERS
+++ b/services/core/java/com/android/server/crashrecovery/OWNERS
@@ -1,3 +1,2 @@
-ancr@google.com
harshitmahajan@google.com
robertogil@google.com
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index d37dd3018fde..798f4d9abeff 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -50,7 +50,6 @@ import android.view.RoundedCorners;
import android.view.SurfaceControl;
import com.android.internal.R;
-import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.function.pooled.PooledLambda;
@@ -764,6 +763,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
if (isDisplayPrivate(physicalAddress)) {
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
}
+
+ if (isDisplayStealTopFocusDisabled(physicalAddress)) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_FOCUS;
+ mInfo.flags |= DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED;
+ }
}
if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) {
@@ -1022,7 +1026,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
void handleHdrSdrNitsChanged(float displayNits, float sdrNits) {
final float newHdrSdrRatio;
- if (displayNits != INVALID_NITS && sdrNits != INVALID_NITS) {
+ if (displayNits != INVALID_NITS && sdrNits != INVALID_NITS
+ && (mBacklightAdapter.mUseSurfaceControlBrightness ||
+ mBacklightAdapter.mForceSurfaceControl)) {
// Ensure the ratio stays >= 1.0f as values below that are nonsensical
newHdrSdrRatio = Math.max(1.f, displayNits / sdrNits);
} else {
@@ -1450,6 +1456,23 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
return false;
}
+
+ private boolean isDisplayStealTopFocusDisabled(DisplayAddress.Physical physicalAddress) {
+ if (physicalAddress == null) {
+ return false;
+ }
+ final Resources res = getOverlayContext().getResources();
+ int[] ports = res.getIntArray(R.array.config_localNotStealTopFocusDisplayPorts);
+ if (ports != null) {
+ int port = physicalAddress.getPort();
+ for (int p : ports) {
+ if (p == port) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
private boolean hdrTypesEqual(int[] modeHdrTypes, int[] recordHdrTypes) {
@@ -1501,9 +1524,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
public static class Injector {
- // Ensure the callback is kept to preserve native weak reference lifecycle semantics.
@SuppressWarnings("unused")
- @KeepForWeakReference
private ProxyDisplayEventReceiver mReceiver;
public void setDisplayEventListenerLocked(Looper looper, DisplayEventListener listener) {
mReceiver = new ProxyDisplayEventReceiver(looper, listener);
diff --git a/services/core/java/com/android/server/display/color/OWNERS b/services/core/java/com/android/server/display/color/OWNERS
index 27adf127d880..8f5a9a0c10eb 100644
--- a/services/core/java/com/android/server/display/color/OWNERS
+++ b/services/core/java/com/android/server/display/color/OWNERS
@@ -1,4 +1,3 @@
christyfranks@google.com
-justinklaassen@google.com
-per-file DisplayTransformManager.java=michaelwr@google.com \ No newline at end of file
+per-file DisplayTransformManager.java=michaelwr@google.com
diff --git a/services/core/java/com/android/server/infra/OWNERS b/services/core/java/com/android/server/infra/OWNERS
index 4fea05d295b6..0f0d382e28f8 100644
--- a/services/core/java/com/android/server/infra/OWNERS
+++ b/services/core/java/com/android/server/infra/OWNERS
@@ -1,3 +1,4 @@
# Bug component: 655446
srazdan@google.com
+reemabajwa@google.com
diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS
index e507c6ba40a1..9d8aef943fa5 100644
--- a/services/core/java/com/android/server/inputmethod/OWNERS
+++ b/services/core/java/com/android/server/inputmethod/OWNERS
@@ -1,7 +1,6 @@
set noparent
roosa@google.com
-yukawa@google.com
tarandeep@google.com
fstern@google.com
cosminbaies@google.com
diff --git a/services/core/java/com/android/server/integrity/OWNERS b/services/core/java/com/android/server/integrity/OWNERS
index 33561fd728f9..352724aa0425 100644
--- a/services/core/java/com/android/server/integrity/OWNERS
+++ b/services/core/java/com/android/server/integrity/OWNERS
@@ -1,5 +1,4 @@
omernebil@google.com
khelmy@google.com
mdchurchill@google.com
-sturla@google.com
diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java
index 7e80cbcb583e..0944a5470ba0 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerService.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerService.java
@@ -48,7 +48,6 @@ import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
-import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.FrameworkStatsLog;
@@ -101,7 +100,6 @@ public class LocaleManagerService extends SystemService {
private LocaleManagerBackupHelper mBackupHelper;
- @KeepForWeakReference
private final PackageMonitor mPackageMonitor;
private final Object mWriteLock = new Object();
diff --git a/services/core/java/com/android/server/location/fudger/LocationFudger.java b/services/core/java/com/android/server/location/fudger/LocationFudger.java
index 0da1514872d6..44eb9063b44e 100644
--- a/services/core/java/com/android/server/location/fudger/LocationFudger.java
+++ b/services/core/java/com/android/server/location/fudger/LocationFudger.java
@@ -282,6 +282,15 @@ public class LocationFudger {
// requires latitude since longitudinal distances change with distance from equator.
private static double metersToDegreesLongitude(double distance, double lat) {
- return distance / APPROXIMATE_METERS_PER_DEGREE_AT_EQUATOR / Math.cos(Math.toRadians(lat));
+ // Needed to convert from longitude distance to longitude degree.
+ // X meters near the poles is more degrees than at the equator.
+ double cosLat = Math.cos(Math.toRadians(lat));
+ // If we are right on top of the pole, the degree is always 0.
+ // We return a very small value instead to avoid divide by zero errors
+ // later on.
+ if (cosLat == 0.0) {
+ return 0.0001;
+ }
+ return distance / APPROXIMATE_METERS_PER_DEGREE_AT_EQUATOR / cosLat;
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c314ab06fbad..a0e543300ce7 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -137,6 +137,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.pm.RoSystemFeatures;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
@@ -369,16 +370,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public void onBootPhase(int phase) {
super.onBootPhase(phase);
- if (phase == PHASE_ACTIVITY_MANAGER_READY) {
- mLockSettingsService.migrateOldDataAfterSystemReady();
- mLockSettingsService.deleteRepairModePersistentDataIfNeeded();
- } else if (phase == PHASE_BOOT_COMPLETED) {
- // In the case of an upgrade, PHASE_BOOT_COMPLETED means that a rollback to the old
- // build can no longer occur. This is the time to destroy any migrated protectors.
- mLockSettingsService.destroyMigratedProtectors();
-
- mLockSettingsService.loadEscrowData();
- }
+ mLockSettingsService.onBootPhase(phase);
}
@Override
@@ -397,6 +389,21 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ private void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ migrateOldDataAfterSystemReady();
+ deleteRepairModePersistentDataIfNeeded();
+ } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+ mHandler.post(() -> {
+ // In the case of an upgrade, PHASE_BOOT_COMPLETED means that a rollback to the old
+ // build can no longer occur. This is the time to destroy any migrated protectors.
+ destroyMigratedProtectors();
+
+ loadEscrowData();
+ });
+ }
+ }
+
@VisibleForTesting
protected static class SynchronizedStrongAuthTracker
extends LockPatternUtils.StrongAuthTracker {
@@ -432,9 +439,9 @@ public class LockSettingsService extends ILockSettings.Stub {
}
LockscreenCredential credential =
LockscreenCredential.createUnifiedProfilePassword(newPassword);
- Arrays.fill(newPasswordChars, '\u0000');
- Arrays.fill(newPassword, (byte) 0);
- Arrays.fill(randomLockSeed, (byte) 0);
+ LockPatternUtils.zeroize(newPasswordChars);
+ LockPatternUtils.zeroize(newPassword);
+ LockPatternUtils.zeroize(randomLockSeed);
return credential;
}
@@ -445,6 +452,7 @@ public class LockSettingsService extends ILockSettings.Stub {
* @param profileUserId profile user Id
* @param profileUserPassword profile original password (when it has separated lock).
*/
+ @GuardedBy("mSpManager")
private void tieProfileLockIfNecessary(int profileUserId,
LockscreenCredential profileUserPassword) {
// Only for profiles that shares credential with parent
@@ -903,14 +911,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// Hide notification first, as tie profile lock takes time
hideEncryptionNotification(new UserHandle(userId));
- if (android.app.admin.flags.Flags.fixRaceConditionInTieProfileLock()) {
- synchronized (mSpManager) {
- tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
- }
- } else {
- if (isCredentialSharableWithParent(userId)) {
- tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
- }
+ synchronized (mSpManager) {
+ tieProfileLockIfNecessary(userId, LockscreenCredential.createNone());
}
}
});
@@ -1324,7 +1326,7 @@ public class LockSettingsService extends ILockSettings.Stub {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN,
"Requires MANAGE_WEAK_ESCROW_TOKEN permission.");
- if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ if (!RoSystemFeatures.hasFeatureAutomotive(mContext)) {
throw new IllegalArgumentException(
"Weak escrow token are only for automotive devices.");
}
@@ -1374,11 +1376,7 @@ public class LockSettingsService extends ILockSettings.Stub {
mStorage.removeChildProfileLock(userId);
removeKeystoreProfileKey(userId);
} else {
- if (android.app.admin.flags.Flags.fixRaceConditionInTieProfileLock()) {
- synchronized (mSpManager) {
- tieProfileLockIfNecessary(userId, profileUserPassword);
- }
- } else {
+ synchronized (mSpManager) {
tieProfileLockIfNecessary(userId, profileUserPassword);
}
}
@@ -1540,7 +1538,7 @@ public class LockSettingsService extends ILockSettings.Stub {
+ userId);
}
} finally {
- Arrays.fill(password, (byte) 0);
+ LockPatternUtils.zeroize(password);
}
}
@@ -1573,7 +1571,7 @@ public class LockSettingsService extends ILockSettings.Stub {
decryptionResult = cipher.doFinal(encryptedPassword);
LockscreenCredential credential = LockscreenCredential.createUnifiedProfilePassword(
decryptionResult);
- Arrays.fill(decryptionResult, (byte) 0);
+ LockPatternUtils.zeroize(decryptionResult);
try {
long parentSid = getGateKeeperService().getSecureUserId(
mUserManager.getProfileParent(userId).id);
@@ -2266,7 +2264,7 @@ public class LockSettingsService extends ILockSettings.Stub {
} catch (RemoteException e) {
Slogf.wtf(TAG, e, "Failed to unlock CE storage for %s user %d", userType, userId);
} finally {
- Arrays.fill(secret, (byte) 0);
+ LockPatternUtils.zeroize(secret);
}
}
@@ -3616,7 +3614,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
// Escrow tokens are enabled on automotive builds.
- if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+ if (RoSystemFeatures.hasFeatureAutomotive(mContext)) {
return;
}
diff --git a/services/core/java/com/android/server/locksettings/UnifiedProfilePasswordCache.java b/services/core/java/com/android/server/locksettings/UnifiedProfilePasswordCache.java
index 21caf76d30d0..3d64f1890073 100644
--- a/services/core/java/com/android/server/locksettings/UnifiedProfilePasswordCache.java
+++ b/services/core/java/com/android/server/locksettings/UnifiedProfilePasswordCache.java
@@ -26,6 +26,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
import java.security.GeneralSecurityException;
@@ -154,7 +155,7 @@ public class UnifiedProfilePasswordCache {
}
LockscreenCredential result =
LockscreenCredential.createUnifiedProfilePassword(credential);
- Arrays.fill(credential, (byte) 0);
+ LockPatternUtils.zeroize(credential);
return result;
}
}
@@ -175,7 +176,7 @@ public class UnifiedProfilePasswordCache {
Slog.d(TAG, "Cannot delete key", e);
}
if (mEncryptedPasswords.contains(userId)) {
- Arrays.fill(mEncryptedPasswords.get(userId), (byte) 0);
+ LockPatternUtils.zeroize(mEncryptedPasswords.get(userId));
mEncryptedPasswords.remove(userId);
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
index bf1b3c3f0b35..85dc811a7811 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeySyncTask.java
@@ -162,7 +162,7 @@ public class KeySyncTask implements Runnable {
Log.e(TAG, "Unexpected exception thrown during KeySyncTask", e);
} finally {
if (mCredential != null) {
- Arrays.fill(mCredential, (byte) 0); // no longer needed.
+ LockPatternUtils.zeroize(mCredential); // no longer needed.
}
}
}
@@ -506,7 +506,7 @@ public class KeySyncTask implements Runnable {
try {
byte[] hash = MessageDigest.getInstance(LOCK_SCREEN_HASH_ALGORITHM).digest(bytes);
- Arrays.fill(bytes, (byte) 0);
+ LockPatternUtils.zeroize(bytes);
return hash;
} catch (NoSuchAlgorithmException e) {
// Impossible, SHA-256 must be supported on Android.
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS b/services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS
index bb487fb52c9f..ebf7e6bed064 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/OWNERS
@@ -1,4 +1,3 @@
aseemk@google.com
bozhu@google.com
dementyev@google.com
-robertberry@google.com
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 54303c01890a..7d8300a8148a 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -1082,7 +1082,7 @@ public class RecoverableKeyStoreManager {
int keyguardCredentialsType = lockPatternUtilsToKeyguardType(savedCredentialType);
try (LockscreenCredential credential =
createLockscreenCredential(keyguardCredentialsType, decryptedCredentials)) {
- Arrays.fill(decryptedCredentials, (byte) 0);
+ LockPatternUtils.zeroize(decryptedCredentials);
decryptedCredentials = null;
VerifyCredentialResponse verifyResponse =
lockSettingsService.verifyCredential(credential, userId, 0);
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySessionStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySessionStorage.java
index 0e66746f4160..f1ef333d223a 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySessionStorage.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverySessionStorage.java
@@ -19,8 +19,9 @@ package com.android.server.locksettings.recoverablekeystore.storage;
import android.annotation.Nullable;
import android.util.SparseArray;
+import com.android.internal.widget.LockPatternUtils;
+
import java.util.ArrayList;
-import java.util.Arrays;
import javax.security.auth.Destroyable;
@@ -187,8 +188,8 @@ public class RecoverySessionStorage implements Destroyable {
*/
@Override
public void destroy() {
- Arrays.fill(mLskfHash, (byte) 0);
- Arrays.fill(mKeyClaimant, (byte) 0);
+ LockPatternUtils.zeroize(mLskfHash);
+ LockPatternUtils.zeroize(mKeyClaimant);
}
}
}
diff --git a/services/core/java/com/android/server/logcat/OWNERS b/services/core/java/com/android/server/logcat/OWNERS
index 33e1873d91fa..2913cc9bf19e 100644
--- a/services/core/java/com/android/server/logcat/OWNERS
+++ b/services/core/java/com/android/server/logcat/OWNERS
@@ -3,6 +3,5 @@
cbrubaker@google.com
eunjeongshin@google.com
georgechan@google.com
-jsharkey@google.com
wenhaowang@google.com
xiaozhenl@google.com
diff --git a/services/core/java/com/android/server/media/TEST_MAPPING b/services/core/java/com/android/server/media/TEST_MAPPING
index 43e2afd8827d..dbf9915c6e0c 100644
--- a/services/core/java/com/android/server/media/TEST_MAPPING
+++ b/services/core/java/com/android/server/media/TEST_MAPPING
@@ -1,7 +1,10 @@
{
"presubmit": [
{
- "name": "CtsMediaBetterTogetherTestCases"
+ "name": "CtsMediaRouterTestCases"
+ },
+ {
+ "name": "CtsMediaSessionTestCases"
},
{
"name": "MediaRouterServiceTests"
diff --git a/services/core/java/com/android/server/memory/OWNERS b/services/core/java/com/android/server/memory/OWNERS
new file mode 100644
index 000000000000..dc0e89892e43
--- /dev/null
+++ b/services/core/java/com/android/server/memory/OWNERS
@@ -0,0 +1,3 @@
+include /MEMORY_OWNERS
+
+per-file ZramMaintenance.java = kawasin@google.com
diff --git a/services/core/java/com/android/server/memory/ZramMaintenance.java b/services/core/java/com/android/server/memory/ZramMaintenance.java
new file mode 100644
index 000000000000..560d2d741dd9
--- /dev/null
+++ b/services/core/java/com/android/server/memory/ZramMaintenance.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.memory;
+
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.IMmd;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.provider.DeviceConfig;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.time.Duration;
+
+/**
+ * Schedules zram maintenance (e.g. zram writeback, zram recompression).
+ *
+ * <p>ZramMaintenance notifies mmd the good timing to execute zram maintenance based on:
+ *
+ * <ul>
+ * <li>Enough interval has passed.
+ * <li>The system is idle.
+ * <li>The battery is not low.
+ * </ul>
+ */
+public class ZramMaintenance extends JobService {
+ private static final String TAG = ZramMaintenance.class.getName();
+ // Job id must be unique across all clients of the same uid. ZramMaintenance uses the bug number
+ // as the job id.
+ @VisibleForTesting
+ public static final int JOB_ID = 375432472;
+ private static final ComponentName sZramMaintenance =
+ new ComponentName("android", ZramMaintenance.class.getName());
+ @VisibleForTesting
+ public static final String KEY_CHECK_STATUS = "check_status";
+
+ private static final String SYSTEM_PROPERTY_PREFIX = "mm.";
+ private static final String FIRST_DELAY_SECONDS_PROP =
+ "zram.maintenance.first_delay_seconds";
+ // The default is 1 hour.
+ private static final long DEFAULT_FIRST_DELAY_SECONDS = 3600;
+ private static final String PERIODIC_DELAY_SECONDS_PROP =
+ "zram.maintenance.periodic_delay_seconds";
+ // The default is 1 hour.
+ private static final long DEFAULT_PERIODIC_DELAY_SECONDS = 3600;
+ private static final String REQUIRE_DEVICE_IDLE_PROP =
+ "zram.maintenance.require_device_idle";
+ private static final boolean DEFAULT_REQUIRE_DEVICE_IDLE =
+ true;
+ private static final String REQUIRE_BATTERY_NOT_LOW_PROP =
+ "zram.maintenance.require_battery_not_low";
+ private static final boolean DEFAULT_REQUIRE_BATTERY_NOT_LOW =
+ true;
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ new Thread("ZramMaintenance") {
+ @Override
+ public void run() {
+ try {
+ IBinder binder = ServiceManager.getService("mmd");
+ IMmd mmd = IMmd.Stub.asInterface(binder);
+ startJob(ZramMaintenance.this, params, mmd);
+ } finally {
+ jobFinished(params, false);
+ }
+ }
+ }.start();
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ return false;
+ }
+
+ /**
+ * This is public to test ZramMaintenance logic.
+ *
+ * <p>
+ * We need to pass mmd as parameter because we can't mock "IMmd.Stub.asInterface".
+ *
+ * <p>
+ * Since IMmd.isZramMaintenanceSupported() is blocking call, this method should be executed on
+ * a worker thread.
+ */
+ @VisibleForTesting
+ public static void startJob(Context context, JobParameters params, IMmd mmd) {
+ boolean checkStatus = params.getExtras().getBoolean(KEY_CHECK_STATUS);
+ if (mmd != null) {
+ try {
+ if (checkStatus && !mmd.isZramMaintenanceSupported()) {
+ Slog.i(TAG, "zram maintenance is not supported");
+ return;
+ }
+ // Status check is required before the first doZramMaintenanceAsync() call once.
+ checkStatus = false;
+
+ mmd.doZramMaintenanceAsync();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to binder call to mmd", e);
+ }
+ } else {
+ Slog.w(TAG, "binder not found");
+ }
+ Duration delay = Duration.ofSeconds(getLongProperty(PERIODIC_DELAY_SECONDS_PROP,
+ DEFAULT_PERIODIC_DELAY_SECONDS));
+ scheduleZramMaintenance(context, delay, checkStatus);
+ }
+
+ /**
+ * Starts periodical zram maintenance.
+ */
+ public static void startZramMaintenance(Context context) {
+ Duration delay = Duration.ofSeconds(
+ getLongProperty(FIRST_DELAY_SECONDS_PROP, DEFAULT_FIRST_DELAY_SECONDS));
+ scheduleZramMaintenance(context, delay, true);
+ }
+
+ private static void scheduleZramMaintenance(Context context, Duration delay,
+ boolean checkStatus) {
+ JobScheduler js = context.getSystemService(JobScheduler.class);
+
+ if (js != null) {
+ final PersistableBundle bundle = new PersistableBundle();
+ bundle.putBoolean(KEY_CHECK_STATUS, checkStatus);
+ js.schedule(new JobInfo.Builder(JOB_ID, sZramMaintenance)
+ .setMinimumLatency(delay.toMillis())
+ .setRequiresDeviceIdle(
+ getBooleanProperty(REQUIRE_DEVICE_IDLE_PROP,
+ DEFAULT_REQUIRE_DEVICE_IDLE))
+ .setRequiresBatteryNotLow(
+ getBooleanProperty(REQUIRE_BATTERY_NOT_LOW_PROP,
+ DEFAULT_REQUIRE_BATTERY_NOT_LOW))
+ .setExtras(bundle)
+ .build());
+ }
+ }
+
+ private static long getLongProperty(String name, long defaultValue) {
+ return DeviceConfig.getLong(DeviceConfig.NAMESPACE_MM, name,
+ SystemProperties.getLong(SYSTEM_PROPERTY_PREFIX + name, defaultValue));
+ }
+
+ private static boolean getBooleanProperty(String name, boolean defaultValue) {
+ return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_MM, name,
+ SystemProperties.getBoolean(SYSTEM_PROPERTY_PREFIX + name, defaultValue));
+ }
+}
diff --git a/services/core/java/com/android/server/notification/OWNERS b/services/core/java/com/android/server/notification/OWNERS
index 9f16662fd749..43c68d10b3ce 100644
--- a/services/core/java/com/android/server/notification/OWNERS
+++ b/services/core/java/com/android/server/notification/OWNERS
@@ -2,8 +2,7 @@
juliacr@google.com
yurilin@google.com
-aroederer@google.com
matiashe@google.com
valiiftime@google.com
jeffdq@google.com
-dsandler@android.com \ No newline at end of file
+dsandler@android.com
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 6303ecd53dbb..253365fba595 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -81,7 +81,6 @@ import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.content.PackageMonitor;
import com.android.internal.content.om.OverlayConfig;
import com.android.internal.util.ArrayUtils;
@@ -263,7 +262,6 @@ public final class OverlayManagerService extends SystemService {
private final OverlayActorEnforcer mActorEnforcer;
- @KeepForWeakReference
private final PackageMonitor mPackageMonitor = new OverlayManagerPackageMonitor();
private int mPrevStartedUserId = -1;
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index b48b39c2edd5..502384d81a4a 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -1533,7 +1533,7 @@ final class InstallPackageHelper {
boolean systemApp = false;
boolean replace = false;
synchronized (mPm.mLock) {
- final PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
+ PackageSetting ps = mPm.mSettings.getPackageLPr(pkgName);
// Check if installing already existing package
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mPm.mSettings.getRenamedPackageLPr(pkgName);
@@ -1544,14 +1544,15 @@ final class InstallPackageHelper {
// name. We must continue using the original name, so
// rename the new package here.
parsedPackage.setPackageName(oldName);
- pkgName = parsedPackage.getPackageName();
- replace = true;
+ pkgName = oldName;
+ ps = mPm.mSettings.getPackageLPr(oldName);
if (DEBUG_INSTALL) {
Slog.d(TAG, "Replacing existing renamed package: oldName="
+ oldName + " pkgName=" + pkgName);
}
- } else if (ps != null) {
- // This package, under its official name, already exists
+ }
+ if (ps != null) {
+ // This package, under its official name or its old name, already exists
// on the device; we should replace it.
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing package: " + pkgName);
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 62b89f3252e6..f98ec04f84d8 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -1,7 +1,6 @@
hackbod@android.com
hackbod@google.com
jsharkey@android.com
-jsharkey@google.com
narayan@google.com
include /PACKAGE_MANAGER_OWNERS
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 891d66a5d238..c799b8b969c8 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -5218,7 +5218,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
"Session " + sessionId + " is a parent of multi-package session and "
+ "requestUserPreapproval on the parent session isn't supported.");
}
-
+ if (statusReceiver == null) {
+ throw new IllegalArgumentException("Status receiver cannot be null.");
+ }
synchronized (mLock) {
assertPreparedAndNotSealedLocked("request of session " + sessionId);
mPreapprovalDetails = details;
@@ -5571,6 +5573,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
*/
private static void sendOnUserActionRequired(Context context, IntentSender target,
int sessionId, Intent intent) {
+ if (target == null) {
+ Slog.e(TAG, "Missing receiver for pending user action.");
+ return;
+ }
final Intent fillIn = new Intent();
fillIn.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_PENDING_USER_ACTION);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index aadf11227d89..2154d37698a2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1476,7 +1476,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
ArchiveState archiveState;
synchronized (mLock) {
PackageSetting ps = mSettings.getPackageLPr(packageName);
- if (ps == null) {
+ if (ps == null || snapshot.shouldFilterApplication(ps, binderUid, userId)) {
return null;
}
var psi = ps.getUserStateOrDefault(userId);
@@ -3020,6 +3020,16 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mDexOptHelper.performPackageDexOptUpgradeIfNeeded();
}
+ public void updateMetricsIfNeeded() {
+ final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+ if (displayManager != null) {
+ final Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ display.getMetrics(mMetrics);
+ }
+ }
+ }
+
private void notifyPackageUseInternal(String packageName, int reason) {
long time = System.currentTimeMillis();
synchronized (mLock) {
@@ -4238,8 +4248,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
CarrierAppUtils.disableCarrierAppsUntilPrivileged(
mContext.getOpPackageName(), UserHandle.USER_SYSTEM, mContext);
- disableSkuSpecificApps();
-
// Read the compatibilty setting when the system is ready.
boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
mContext.getContentResolver(),
@@ -4372,29 +4380,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
}
}
- //TODO: b/111402650
- private void disableSkuSpecificApps() {
- String[] apkList = mContext.getResources().getStringArray(
- R.array.config_disableApksUnlessMatchedSku_apk_list);
- String[] skuArray = mContext.getResources().getStringArray(
- R.array.config_disableApkUnlessMatchedSku_skus_list);
- if (ArrayUtils.isEmpty(apkList)) {
- return;
- }
- String sku = SystemProperties.get("ro.boot.hardware.sku");
- if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
- return;
- }
- final Computer snapshot = snapshotComputer();
- for (String packageName : apkList) {
- setSystemAppHiddenUntilInstalled(snapshot, packageName, true);
- final List<UserInfo> users = mInjector.getUserManagerInternal().getUsers(false);
- for (int i = 0; i < users.size(); i++) {
- setSystemAppInstallState(snapshot, packageName, false, users.get(i).id);
- }
- }
- }
-
public PackageFreezer freezePackage(String packageName, int userId, String killReason,
int exitInfoReason, InstallRequest request) {
return freezePackage(packageName, userId, killReason, exitInfoReason, request,
diff --git a/services/core/java/com/android/server/pm/dex/OWNERS b/services/core/java/com/android/server/pm/dex/OWNERS
index 5ca8ddd1fe17..70af4e7d36b2 100644
--- a/services/core/java/com/android/server/pm/dex/OWNERS
+++ b/services/core/java/com/android/server/pm/dex/OWNERS
@@ -1,4 +1,3 @@
-alanstokes@google.com
jiakaiz@google.com
ngeoffray@google.com
mast@google.com
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index ecffd382f542..3f9144f0d980 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -136,7 +136,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
final LocationManagerInternal locationManagerInternal = LocalServices.getService(
LocationManagerInternal.class);
- locationManagerInternal.setLocationPackageTagsListener(
+ if (locationManagerInternal != null) {
+ locationManagerInternal.setLocationPackageTagsListener(
(uid, packageTagsList) -> {
synchronized (mLock) {
if (packageTagsList.isEmpty()) {
@@ -158,6 +159,7 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat
mLocationTags);
}
});
+ }
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
diff --git a/services/core/java/com/android/server/power/OWNERS b/services/core/java/com/android/server/power/OWNERS
index c1fad33fef0f..a1531a810c3c 100644
--- a/services/core/java/com/android/server/power/OWNERS
+++ b/services/core/java/com/android/server/power/OWNERS
@@ -2,6 +2,8 @@ michaelwr@google.com
santoscordon@google.com
petsjonkin@google.com
brup@google.com
+flc@google.com
+wilczynskip@google.com
per-file ThermalManagerService.java=file:/THERMAL_OWNERS
per-file LowPowerStandbyController.java=qingxun@google.com
diff --git a/services/core/java/com/android/server/power/ShutdownCheckPoints.java b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
index dafaa7d5f134..399e214aa955 100644
--- a/services/core/java/com/android/server/power/ShutdownCheckPoints.java
+++ b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
@@ -350,17 +350,23 @@ public final class ShutdownCheckPoints {
private final ShutdownCheckPoints mInstance;
private final File mBaseFile;
+ private final File mBaseDir;
private final int mFileCountLimit;
FileDumperThread(ShutdownCheckPoints instance, File baseFile, int fileCountLimit) {
mInstance = instance;
mBaseFile = baseFile;
+ mBaseDir = baseFile.getParentFile();
mFileCountLimit = fileCountLimit;
}
@Override
public void run() {
- mBaseFile.getParentFile().mkdirs();
+ if (!mBaseDir.exists()) {
+ mBaseDir.mkdirs();
+ mBaseDir.setExecutable(true, false);
+ mBaseDir.setReadable(true, false);
+ }
File[] checkPointFiles = listCheckPointsFiles();
int filesToDelete = checkPointFiles.length - mFileCountLimit + 1;
@@ -375,7 +381,7 @@ public final class ShutdownCheckPoints {
private File[] listCheckPointsFiles() {
String filePrefix = mBaseFile.getName() + "-";
- File[] files = mBaseFile.getParentFile().listFiles(new FilenameFilter() {
+ File[] files = mBaseDir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (!name.startsWith(filePrefix)) {
@@ -412,6 +418,7 @@ public final class ShutdownCheckPoints {
}
}
mBaseFile.renameTo(file);
+ file.setReadable(true, false);
}
}
}
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 6f1810711b3a..0dc8fe19745a 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -749,34 +749,29 @@ public class BatteryStatsImpl extends BatteryStats {
@Override
public void handleMessage(Message msg) {
BatteryCallback cb = mCallback;
+ if (cb == null) {
+ return;
+ }
switch (msg.what) {
case MSG_REPORT_CPU_UPDATE_NEEDED:
- if (cb != null) {
- cb.batteryNeedsCpuUpdate();
- }
+ cb.batteryNeedsCpuUpdate();
break;
case MSG_REPORT_POWER_CHANGE:
- if (cb != null) {
- cb.batteryPowerChanged(msg.arg1 != 0);
- }
+ cb.batteryPowerChanged(msg.arg1 != 0);
break;
case MSG_REPORT_CHARGING:
- if (cb != null) {
- final String action;
- synchronized (BatteryStatsImpl.this) {
- action = mCharging ? BatteryManager.ACTION_CHARGING
- : BatteryManager.ACTION_DISCHARGING;
- }
- Intent intent = new Intent(action);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- cb.batterySendBroadcast(intent);
+ final String action;
+ synchronized (BatteryStatsImpl.this) {
+ action = mCharging ? BatteryManager.ACTION_CHARGING
+ : BatteryManager.ACTION_DISCHARGING;
}
+ Intent intent = new Intent(action);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ cb.batterySendBroadcast(intent);
break;
case MSG_REPORT_RESET_STATS:
- if (cb != null) {
- cb.batteryStatsReset();
- }
- }
+ cb.batteryStatsReset();
+ }
}
}
diff --git a/services/core/java/com/android/server/power/stats/OWNERS b/services/core/java/com/android/server/power/stats/OWNERS
index 4068e2bc03b7..208b2ddb5e54 100644
--- a/services/core/java/com/android/server/power/stats/OWNERS
+++ b/services/core/java/com/android/server/power/stats/OWNERS
@@ -1 +1,4 @@
+# Bug component: 987260
+set noparent
+
include /BATTERY_STATS_OWNERS
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
index e80a86d73f90..4fd026a6dc52 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsLogger.java
@@ -285,14 +285,20 @@ public final class PowerStatsLogger extends Handler {
}
private void updateCacheFile(String cacheFilename, byte[] data) {
+ AtomicFile atomicCachedFile = null;
+ FileOutputStream fos = null;
try {
- final AtomicFile atomicCachedFile =
+ atomicCachedFile =
new AtomicFile(new File(mDataStoragePath, cacheFilename));
- final FileOutputStream fos = atomicCachedFile.startWrite();
+ fos = atomicCachedFile.startWrite();
fos.write(data);
atomicCachedFile.finishWrite(fos);
} catch (IOException e) {
Slog.e(TAG, "Failed to write current data to cached file", e);
+ if (fos != null) {
+ atomicCachedFile.failWrite(fos);
+ }
+ return;
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 14539d544bf9..50db1e4ac30e 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -84,8 +84,12 @@ class RollbackStore {
*/
private static List<Rollback> loadRollbacks(File rollbackDataDir) {
List<Rollback> rollbacks = new ArrayList<>();
- rollbackDataDir.mkdirs();
- for (File rollbackDir : rollbackDataDir.listFiles()) {
+ File[] rollbackDirs = rollbackDataDir.listFiles();
+ if (rollbackDirs == null) {
+ Slog.e(TAG, "Folder doesn't exist: " + rollbackDataDir);
+ return rollbacks;
+ }
+ for (File rollbackDir : rollbackDirs) {
if (rollbackDir.isDirectory()) {
try {
rollbacks.add(loadRollback(rollbackDir));
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index fa4bf228c683..7a31a0006bb9 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -3,5 +3,6 @@
include /core/java/android/security/OWNERS
per-file *AttestationVerification* = file:/core/java/android/security/attestationverification/OWNERS
+per-file *CertificateRevocationStatus* = file:/core/java/android/security/attestationverification/OWNERS
per-file FileIntegrity*.java = victorhsieh@google.com
per-file KeyChainSystemService.java = file:platform/packages/apps/KeyChain:/OWNERS
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index 81217014bafe..a64e38e60ad1 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -131,7 +131,6 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.camera.flags.Flags;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.os.BackgroundThread;
@@ -536,8 +535,12 @@ public final class SensorPrivacyService extends SystemService {
user.getIdentifier());
String inputMethodPackageName = null;
if (inputMethodComponent != null) {
- inputMethodPackageName = ComponentName.unflattenFromString(
- inputMethodComponent).getPackageName();
+ ComponentName component = ComponentName.unflattenFromString(inputMethodComponent);
+ if (component != null) {
+ inputMethodPackageName = component.getPackageName();
+ } else {
+ Log.w(TAG, "Failed to parse inputMethodComponent: " + inputMethodComponent);
+ }
}
int capability;
@@ -2004,11 +2007,7 @@ public final class SensorPrivacyService extends SystemService {
}
private class CallStateHelper {
- // TelephonyCallback instances are only weakly referenced when registered, so we need
- // to ensure these fields are kept during optimization to preserve lifecycle semantics.
- @KeepForWeakReference
private final OutgoingEmergencyStateCallback mEmergencyStateCallback;
- @KeepForWeakReference
private final CallStateCallback mCallStateCallback;
private boolean mIsInEmergencyCall;
diff --git a/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java b/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
index 2088e411f842..383135233049 100644
--- a/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
+++ b/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
@@ -142,11 +142,8 @@ class AggregatedMobileDataStatsPuller {
private final RateLimiter mRateLimiter;
AggregatedMobileDataStatsPuller(@NonNull NetworkStatsManager networkStatsManager) {
- if (DEBUG) {
- if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
- TAG + "-AggregatedMobileDataStatsPullerInit");
- }
+ if (DEBUG && Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, TAG + "-Init");
}
mRateLimiter = new RateLimiter(/* window= */ Duration.ofSeconds(1));
@@ -173,10 +170,16 @@ class AggregatedMobileDataStatsPuller {
public void noteUidProcessState(int uid, int state, long unusedElapsedRealtime,
long unusedUptime) {
- mMobileDataStatsHandler.post(
+ if (mRateLimiter.tryAcquire()) {
+ mMobileDataStatsHandler.post(
() -> {
noteUidProcessStateImpl(uid, state);
});
+ } else {
+ synchronized (mLock) {
+ mUidPreviousState.put(uid, state);
+ }
+ }
}
public int pullDataBytesTransfer(List<StatsEvent> data) {
@@ -209,29 +212,27 @@ class AggregatedMobileDataStatsPuller {
}
private void noteUidProcessStateImpl(int uid, int state) {
- if (mRateLimiter.tryAcquire()) {
- // noteUidProcessStateImpl can be called back to back several times while
- // the updateNetworkStats loops over several stats for multiple uids
- // and during the first call in a batch of proc state change event it can
- // contain info for uid with unknown previous state yet which can happen due to a few
- // reasons:
- // - app was just started
- // - app was started before the ActivityManagerService
- // as result stats would be created with state == ActivityManager.PROCESS_STATE_UNKNOWN
- if (mNetworkStatsManager != null) {
- updateNetworkStats(mNetworkStatsManager);
- } else {
- Slog.w(TAG, "noteUidProcessStateLocked() can not get mNetworkStatsManager");
- }
+ // noteUidProcessStateImpl can be called back to back several times while
+ // the updateNetworkStats loops over several stats for multiple uids
+ // and during the first call in a batch of proc state change event it can
+ // contain info for uid with unknown previous state yet which can happen due to a few
+ // reasons:
+ // - app was just started
+ // - app was started before the ActivityManagerService
+ // as result stats would be created with state == ActivityManager.PROCESS_STATE_UNKNOWN
+ if (mNetworkStatsManager != null) {
+ updateNetworkStats(mNetworkStatsManager);
+ } else {
+ Slog.w(TAG, "noteUidProcessStateLocked() can not get mNetworkStatsManager");
+ }
+ synchronized (mLock) {
+ mUidPreviousState.put(uid, state);
}
- mUidPreviousState.put(uid, state);
}
private void updateNetworkStats(NetworkStatsManager networkStatsManager) {
- if (DEBUG) {
- if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, TAG + "-updateNetworkStats");
- }
+ if (DEBUG && Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, TAG + "-updateNetworkStats");
}
final NetworkStats latestStats = networkStatsManager.getMobileUidStats();
@@ -256,20 +257,25 @@ class AggregatedMobileDataStatsPuller {
}
private void updateNetworkStatsDelta(NetworkStats delta) {
+ if (DEBUG && Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, TAG + "-updateNetworkStatsDelta");
+ }
synchronized (mLock) {
for (NetworkStats.Entry entry : delta) {
- if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) {
- continue;
- }
- MobileDataStats stats = getUidStatsForPreviousStateLocked(entry.getUid());
- if (stats != null) {
- stats.addTxBytes(entry.getTxBytes());
- stats.addRxBytes(entry.getRxBytes());
- stats.addTxPackets(entry.getTxPackets());
- stats.addRxPackets(entry.getRxPackets());
+ if (entry.getRxPackets() != 0 || entry.getTxPackets() != 0) {
+ MobileDataStats stats = getUidStatsForPreviousStateLocked(entry.getUid());
+ if (stats != null) {
+ stats.addTxBytes(entry.getTxBytes());
+ stats.addRxBytes(entry.getRxBytes());
+ stats.addTxPackets(entry.getTxPackets());
+ stats.addRxPackets(entry.getRxPackets());
+ }
}
}
}
+ if (DEBUG) {
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ }
}
@GuardedBy("mLock")
@@ -298,18 +304,12 @@ class AggregatedMobileDataStatsPuller {
}
private static boolean isEmpty(NetworkStats stats) {
- long totalRxPackets = 0;
- long totalTxPackets = 0;
for (NetworkStats.Entry entry : stats) {
- if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) {
- continue;
+ if (entry.getRxPackets() != 0 || entry.getTxPackets() != 0) {
+ // at least one non empty entry located
+ return false;
}
- totalRxPackets += entry.getRxPackets();
- totalTxPackets += entry.getTxPackets();
- // at least one non empty entry located
- break;
}
- final long totalPackets = totalRxPackets + totalTxPackets;
- return totalPackets == 0;
+ return true;
}
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 40ea9319c6be..21e02f3f7898 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -4893,7 +4893,7 @@ public class StatsPullAtomService extends SystemService {
Slog.e(TAG, "Disconnected from keystore service. Cannot pull.", e);
return StatsManager.PULL_SKIP;
} catch (ServiceSpecificException e) {
- Slog.e(TAG, "pulling keystore metrics failed", e);
+ Slog.e(TAG, "Pulling keystore atom with tag " + atomTag + " failed", e);
return StatsManager.PULL_SKIP;
} finally {
Binder.restoreCallingIdentity(callingToken);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index f8877ad912b5..a05e7e0acd8d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -1517,10 +1517,13 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
getUiState(displayId).setImeWindowState(vis, backDisposition, showImeSwitcher);
mHandler.post(() -> {
- if (mBar == null) return;
- try {
- mBar.setImeWindowStatus(displayId, vis, backDisposition, showImeSwitcher);
- } catch (RemoteException ex) { }
+ IStatusBar bar = mBar;
+ if (bar != null) {
+ try {
+ bar.setImeWindowStatus(displayId, vis, backDisposition, showImeSwitcher);
+ } catch (RemoteException ex) {
+ }
+ }
});
}
}
diff --git a/services/core/java/com/android/server/uri/OWNERS b/services/core/java/com/android/server/uri/OWNERS
index cdc07ed7c67a..6599db7936c0 100644
--- a/services/core/java/com/android/server/uri/OWNERS
+++ b/services/core/java/com/android/server/uri/OWNERS
@@ -1,3 +1,2 @@
jsharkey@android.com
-jsharkey@google.com
varunshah@google.com
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3467f947ece4..496e64f5f7a1 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -359,7 +359,6 @@ import android.window.WindowOnBackInvokedDispatcher;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.KeepForWeakReference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
@@ -893,8 +892,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
private RemoteCallbackList<IScreenCaptureObserver> mCaptureCallbacks;
- // Ensure the field is kept during optimization to preserve downstream weak refs.
- @KeepForWeakReference
private final ColorDisplayService.ColorTransformController mColorTransformController =
(matrix, translation) -> mWmService.mH.post(() -> {
synchronized (mWmService.mGlobalLock) {
diff --git a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
index 1208b6ef396f..08ceb61e14a8 100644
--- a/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
+++ b/services/core/java/com/android/server/wm/ActivityServiceConnectionsHolder.java
@@ -142,6 +142,8 @@ public class ActivityServiceConnectionsHolder<T> {
/** Used by {@link ActivityRecord#dump}. */
@Override
public String toString() {
- return String.valueOf(mConnections);
+ synchronized (mActivity) {
+ return String.valueOf(mConnections);
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index a077a0b9a2ca..b20558ff79cc 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1662,6 +1662,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
activityIdleInternal(null /* idleActivity */, false /* fromTimeout */,
true /* processPausingActivities */, null /* configuration */);
+ if (rootTask.getParent() == null) {
+ // The activities in the task may already be finishing. Then the task could be removed
+ // when performing the idle check.
+ return;
+ }
+
// Reparent all the tasks to the bottom of the display
final DisplayContent toDisplay =
mRootWindowContainer.getDisplayContent(DEFAULT_DISPLAY);
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index 3aa355869d85..00279921953d 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -110,8 +110,10 @@ class CameraStateMonitor {
}
void startListeningToCameraState() {
- mCameraManager.registerAvailabilityCallback(
- mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
+ if (mCameraManager != null) {
+ mCameraManager.registerAvailabilityCallback(
+ mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
+ }
mIsRunning = true;
}
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 6ccceb9cf564..e05a87d2ceb5 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -368,6 +368,15 @@ final class ContentRecorder implements WindowContainerListener {
return;
}
+ final SurfaceControl sourceSurface = mRecordedWindowContainer.getSurfaceControl();
+ if (sourceSurface == null || !sourceSurface.isValid()) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Unable to start recording for display %d since the "
+ + "surface is null or have been released.",
+ mDisplayContent.getDisplayId());
+ return;
+ }
+
final int contentToRecord = mContentRecordingSession.getContentToRecord();
// TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are inaccurate.
@@ -395,8 +404,7 @@ final class ContentRecorder implements WindowContainerListener {
mDisplayContent.getDisplayId(), mDisplayContent.getDisplayInfo().state);
// Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
- mRecordedSurface = SurfaceControl.mirrorSurface(
- mRecordedWindowContainer.getSurfaceControl());
+ mRecordedSurface = SurfaceControl.mirrorSurface(sourceSurface);
SurfaceControl.Transaction transaction =
mDisplayContent.mWmService.mTransactionFactory.get()
// Set the mMirroredSurface's parent to the root SurfaceControl for this
@@ -473,16 +481,18 @@ final class ContentRecorder implements WindowContainerListener {
case RECORD_CONTENT_TASK:
// Given the WindowToken of the region to record, retrieve the associated
// SurfaceControl.
- if (tokenToRecord == null) {
+ final WindowContainer wc = tokenToRecord != null
+ ? WindowContainer.fromBinder(tokenToRecord) : null;
+ if (wc == null) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
- "Content Recording: Unable to start recording due to null token for "
- + "display %d",
+ "Content Recording: Unable to start recording due to null token or " +
+ "null window container for " + "display %d",
mDisplayContent.getDisplayId());
return null;
}
- Task taskToRecord = WindowContainer.fromBinder(tokenToRecord).asTask();
- if (taskToRecord == null) {
+ final Task taskToRecord = wc.asTask();
+ if (taskToRecord == null || !taskToRecord.isAttached()) {
handleStartRecordingFailed();
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Unable to retrieve task to start recording for "
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c2141a7103be..2f646fbde35a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -841,11 +841,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
final ActivityRecord focusedApp = mFocusedApp;
+ final boolean canReceiveKeys = w.canReceiveKeys();
ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s",
- w, w.mAttrs.flags, w.canReceiveKeys(),
+ w, w.mAttrs.flags, canReceiveKeys,
w.canReceiveKeysReason(false /* fromUserTouch */));
- if (!w.canReceiveKeys()) {
+ if (!canReceiveKeys) {
return false;
}
@@ -3877,7 +3878,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (mTmpWindow == null) {
ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows, display=%d",
getDisplayId());
- return null;
}
return mTmpWindow;
}
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 4230cd868c03..98ed6f76b2f9 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -101,7 +101,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
// isLeashReadyForDispatching (used to dispatch the leash of the control) is
// depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
// again, so that the control with leash can be eventually dispatched
- if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending) {
+ if (!mGivenInsetsReady && isServerVisible() && !givenInsetsPending
+ && mControlTarget != null) {
mGivenInsetsReady = true;
ImeTracker.forLogging().onProgress(mStatsToken,
ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED);
@@ -324,7 +325,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
if (target != imeControlTarget) {
// TODO(b/353463205): check if fromUser=false is correct here
boolean imeVisible = target.isRequestedVisible(WindowInsets.Type.ime());
- ImeTracker.Token statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE,
+ ImeTracker.Token statsToken = ImeTracker.forLogging().onStart(
+ imeVisible ? ImeTracker.TYPE_SHOW : ImeTracker.TYPE_HIDE,
ImeTracker.ORIGIN_SERVER,
imeVisible ? SoftInputShowHideReason.SHOW_INPUT_TARGET_CHANGED
: SoftInputShowHideReason.HIDE_INPUT_TARGET_CHANGED,
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 7276007481ab..d1585d06ae40 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -384,7 +384,7 @@ class InsetsSourceProvider {
}
final boolean serverVisibleChanged = mServerVisible != isServerVisible;
setServerVisible(isServerVisible);
- if (mControl != null) {
+ if (mControl != null && mControlTarget != null) {
final boolean positionChanged = updateInsetsControlPosition(windowState);
if (!(positionChanged || mHasPendingPosition)
// The insets hint would be updated while changing the position. Here updates it
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index cf145f94f787..cd3398950099 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -371,7 +371,7 @@ class InsetsStateController {
array.add(provider);
}
- void notifyControlChanged(InsetsControlTarget target, InsetsSourceProvider provider) {
+ void notifyControlChanged(@NonNull InsetsControlTarget target, InsetsSourceProvider provider) {
addToPendingControlMaps(target, provider);
notifyPendingInsetsControlChanged();
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 98521d36ad44..243a5326b545 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -3,7 +3,6 @@ set noparent
ogunwale@google.com
jjaggi@google.com
racarr@google.com
-chaviw@google.com
vishnun@google.com
akulian@google.com
roosa@google.com
@@ -21,6 +20,7 @@ jiamingliu@google.com
pdwilliams@google.com
charlesccchen@google.com
marziana@google.com
+mcarli@google.com
# Files related to background activity launches
per-file Background*Start* = set noparent
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 755d4c8c9fc5..6dd7d35856df 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -348,12 +348,14 @@ class PinnedTaskController {
* Notifies listeners that the PIP needs to be adjusted for the IME.
*/
private void notifyImeVisibilityChanged(boolean imeVisible, int imeHeight) {
- if (mPinnedTaskListener != null) {
- try {
- mPinnedTaskListener.onImeVisibilityChanged(imeVisible, imeHeight);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering bounds changed event.", e);
- }
+ if (mPinnedTaskListener == null) {
+ return;
+ }
+
+ try {
+ mPinnedTaskListener.onImeVisibilityChanged(imeVisible, imeHeight);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering ime visibility changed event.", e);
}
}
@@ -361,15 +363,14 @@ class PinnedTaskController {
* Notifies listeners that the PIP movement bounds have changed.
*/
private void notifyMovementBoundsChanged(boolean fromImeAdjustment) {
- synchronized (mService.mGlobalLock) {
- if (mPinnedTaskListener == null) {
- return;
- }
- try {
- mPinnedTaskListener.onMovementBoundsChanged(fromImeAdjustment);
- } catch (RemoteException e) {
- Slog.e(TAG_WM, "Error delivering actions changed event.", e);
- }
+ if (mPinnedTaskListener == null) {
+ return;
+ }
+
+ try {
+ mPinnedTaskListener.onMovementBoundsChanged(fromImeAdjustment);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering movement bounds changed event.", e);
}
}
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index 7fdc2c67b5ce..44f000da3d73 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -1515,9 +1515,9 @@ class RecentTasks {
boolean skipExcludedCheck) {
if (!skipExcludedCheck) {
// Keep the most recent task of home display even if it is excluded from recents.
- final boolean isExcludeFromRecents =
- (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+ final boolean isExcludeFromRecents = task.getBaseIntent() != null
+ && (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
if (isExcludeFromRecents) {
if (DEBUG_RECENTS_TRIM_TASKS) {
Slog.d(TAG,
diff --git a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
index 38e011509885..efc68aac0323 100644
--- a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
+++ b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
@@ -95,8 +95,9 @@ public class ScreenRecordingCallbackController {
if (mediaProjectionInfo.getLaunchCookie() == null) {
mRecordedWC = (WindowContainer) mWms.mRoot.getDefaultDisplay();
} else {
- mRecordedWC = mWms.mRoot.getActivity(activity -> activity.mLaunchCookie
- == mediaProjectionInfo.getLaunchCookie().binder).getTask();
+ final ActivityRecord matchingActivity = mWms.mRoot.getActivity(activity ->
+ activity.mLaunchCookie == mediaProjectionInfo.getLaunchCookie().binder);
+ mRecordedWC = matchingActivity != null ? matchingActivity.getTask() : null;
}
}
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index a5454546341b..3eb13c52cca6 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -407,10 +407,8 @@ class SnapshotPersistQueue {
bitmap.recycle();
final File file = mPersistInfoProvider.getHighResolutionBitmapFile(mId, mUserId);
- try {
- FileOutputStream fos = new FileOutputStream(file);
+ try (FileOutputStream fos = new FileOutputStream(file)) {
swBitmap.compress(JPEG, COMPRESS_QUALITY, fos);
- fos.close();
} catch (IOException e) {
Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
return false;
@@ -428,10 +426,8 @@ class SnapshotPersistQueue {
swBitmap.recycle();
final File lowResFile = mPersistInfoProvider.getLowResolutionBitmapFile(mId, mUserId);
- try {
- FileOutputStream lowResFos = new FileOutputStream(lowResFile);
+ try (FileOutputStream lowResFos = new FileOutputStream(lowResFile)) {
lowResBitmap.compress(JPEG, COMPRESS_QUALITY, lowResFos);
- lowResFos.close();
} catch (IOException e) {
Slog.e(TAG, "Unable to open " + lowResFile + " for persisting.", e);
return false;
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index c1a33c468cee..2bec0f414a0c 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -844,7 +844,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
*/
void positionTaskBehindHome(Task task) {
final Task home = getOrCreateRootHomeTask();
- final WindowContainer homeParent = home.getParent();
+ final WindowContainer homeParent = home != null ? home.getParent() : null;
final Task homeParentTask = homeParent != null ? homeParent.asTask() : null;
if (homeParentTask == null) {
// reparent throws if parent didn't change...
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index d89dc0b8e81c..91cd9498a356 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -245,18 +245,20 @@ public class TaskPersister implements PersisterQueue.Listener {
private static String fileToString(File file) {
final String newline = System.lineSeparator();
+ BufferedReader reader = null;
try {
- BufferedReader reader = new BufferedReader(new FileReader(file));
+ reader = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer((int) file.length() * 2);
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + newline);
}
- reader.close();
return sb.toString();
} catch (IOException ioe) {
Slog.e(TAG, "Couldn't read file " + file.getName());
return null;
+ } finally {
+ IoUtils.closeQuietly(reader);
}
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 1fc609b7d03a..43e45e18f01e 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1415,6 +1415,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (!tr.isAttached() || !tr.isVisibleRequested()
|| !tr.inPinnedWindowingMode()) return;
final ActivityRecord currTop = tr.getTopNonFinishingActivity();
+ if (currTop == null) return;
if (currTop.inPinnedWindowingMode()) return;
Slog.e(TAG, "Enter-PIP was started but not completed, this is a Shell/SysUI"
+ " bug. This state breaks gesture-nav, so attempting clean-up.");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0b6ca75c5f0d..6238d4bd8fb8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -726,8 +726,14 @@ public class WindowManagerService extends IWindowManager.Stub
new WallpaperVisibilityListeners();
IDisplayChangeWindowController mDisplayChangeController = null;
- private final DeathRecipient mDisplayChangeControllerDeath =
- () -> mDisplayChangeController = null;
+ private final DeathRecipient mDisplayChangeControllerDeath = new DeathRecipient() {
+ @Override
+ public void binderDied() {
+ synchronized (mGlobalLock) {
+ mDisplayChangeController = null;
+ }
+ }
+ };
final DisplayWindowListenerController mDisplayNotificationController;
final TaskSystemBarsListenerController mTaskSystemBarsListenerController;
@@ -10062,9 +10068,10 @@ public class WindowManagerService extends IWindowManager.Stub
throw new SecurityException("Access denied to process: " + pid
+ ", must have permission " + Manifest.permission.ACCESS_FPS_COUNTER);
}
-
- if (mRoot.anyTaskForId(taskId) == null) {
- throw new IllegalArgumentException("no task with taskId: " + taskId);
+ synchronized (mGlobalLock) {
+ if (mRoot.anyTaskForId(taskId) == null) {
+ throw new IllegalArgumentException("no task with taskId: " + taskId);
+ }
}
mTaskFpsCallbackController.registerListener(taskId, callback);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index cebe790bb1b9..eb30514006f1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3303,7 +3303,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// just kill it. And if it is a window of foreground activity, the activity can be
// restarted automatically if needed.
Slog.w(TAG, "Exception thrown during dispatchAppVisibility " + this, e);
- if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid) {
+ if (android.os.Process.getUidForPid(mSession.mPid) == mSession.mUid
+ && android.os.Process.getThreadGroupLeader(mSession.mPid) == mSession.mPid) {
android.os.Process.killProcess(mSession.mPid);
}
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 4c0cee404b68..85169b8a8752 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -11,7 +11,6 @@ cc_library_static {
name: "libservices.core",
defaults: ["libservices.core-libs"],
- cpp_std: "c++2a",
cflags: [
"-Wall",
"-Werror",
@@ -80,6 +79,7 @@ cc_library_static {
":lib_oomConnection_native",
":lib_anrTimer_native",
":lib_lazilyRegisteredServices_native",
+ ":lib_phantomProcessList_native",
],
include_dirs: [
@@ -265,3 +265,10 @@ filegroup {
"com_android_server_vr_VrManagerService.cpp",
],
}
+
+filegroup {
+ name: "lib_phantomProcessList_native",
+ srcs: [
+ "com_android_server_am_PhantomProcessList.cpp",
+ ],
+}
diff --git a/services/core/jni/BroadcastRadio/OWNERS b/services/core/jni/BroadcastRadio/OWNERS
index ea4421eae96a..a993823f88f7 100644
--- a/services/core/jni/BroadcastRadio/OWNERS
+++ b/services/core/jni/BroadcastRadio/OWNERS
@@ -1,2 +1 @@
twasilczyk@google.com
-randolphs@google.com
diff --git a/services/core/jni/com_android_server_am_PhantomProcessList.cpp b/services/core/jni/com_android_server_am_PhantomProcessList.cpp
new file mode 100644
index 000000000000..0c5e6d85919a
--- /dev/null
+++ b/services/core/jni/com_android_server_am_PhantomProcessList.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <processgroup/processgroup.h>
+
+namespace android {
+namespace {
+
+jstring getCgroupProcsPath(JNIEnv* env, jobject clazz, jint uid, jint pid) {
+ if (uid < 0) {
+ jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", "uid is negative: %d", uid);
+ return nullptr;
+ }
+
+ std::string path;
+ if (!CgroupGetAttributePathForProcess("CgroupProcs", uid, pid, path)) {
+ path.clear();
+ }
+
+ return env->NewStringUTF(path.c_str());
+}
+
+const JNINativeMethod sMethods[] = {
+ {"nativeGetCgroupProcsPath", "(II)Ljava/lang/String;", (void*)getCgroupProcsPath},
+};
+
+} // anonymous namespace
+
+int register_android_server_am_PhantomProcessList(JNIEnv* env) {
+ const char* className = "com/android/server/am/PhantomProcessList";
+ return jniRegisterNativeMethods(env, className, sMethods, NELEM(sMethods));
+}
+
+} // namespace android \ No newline at end of file
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 09fd8d4ac02e..ddcff7bfafaf 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -71,6 +71,7 @@ int register_com_android_server_display_DisplayControl(JNIEnv* env);
int register_com_android_server_SystemClockTime(JNIEnv* env);
int register_android_server_display_smallAreaDetectionController(JNIEnv* env);
int register_com_android_server_accessibility_BrailleDisplayConnection(JNIEnv* env);
+int register_android_server_am_PhantomProcessList(JNIEnv* env);
// Note: Consider adding new JNI entrypoints for optional services to
// LazyJniRegistrar instead, and relying on lazy registration.
@@ -137,5 +138,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_com_android_server_SystemClockTime(env);
register_android_server_display_smallAreaDetectionController(env);
register_com_android_server_accessibility_BrailleDisplayConnection(env);
+ register_android_server_am_PhantomProcessList(env);
return JNI_VERSION_1_4;
}
diff --git a/services/core/jni/stats/OWNERS b/services/core/jni/stats/OWNERS
index 2611e5b6cee2..8d87925fbe45 100644
--- a/services/core/jni/stats/OWNERS
+++ b/services/core/jni/stats/OWNERS
@@ -1,8 +1,6 @@
jeffreyhuang@google.com
-jtnguyen@google.com
muhammadq@google.com
sharaieko@google.com
singhtejinder@google.com
tsaichristine@google.com
yaochen@google.com
-yro@google.com
diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
index 6393e11b7432..1db9e8d545e4 100644
--- a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
+++ b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/Android.bp
@@ -1,7 +1,7 @@
aconfig_declarations {
name: "device_state_flags",
package: "com.android.server.policy.feature.flags",
- container: "system",
+ container: "system_ext",
srcs: [
"device_state_flags.aconfig",
],
diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
index 21e33dd1b99a..f827b5508015 100644
--- a/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
+++ b/services/foldables/devicestateprovider/src/com/android/server/policy/feature/device_state_flags.aconfig
@@ -1,5 +1,5 @@
package: "com.android.server.policy.feature.flags"
-container: "system"
+container: "system_ext"
flag {
name: "enable_dual_display_blocking"
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index a8e6f689b424..dae481a3c215 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1999,9 +1999,9 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_
// Create new lib file without signature info
incfs::NewFileParams libFileParams = {
.size = entry.uncompressed_length,
- .signature = {},
// Metadata of the new lib file is its relative path
.metadata = {targetLibPath.c_str(), (IncFsSize)targetLibPath.size()},
+ .signature = {},
};
incfs::FileId libFileId = idFromMetadata(targetLibPath);
if (auto res = mIncFs->makeFile(ifs->control, targetLibPathAbsolute, 0755, libFileId,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 92dbf63b3cf7..1472da687199 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -293,6 +293,7 @@ import com.android.server.usage.StorageStatsService;
import com.android.server.usage.UsageStatsService;
import com.android.server.usb.UsbService;
import com.android.server.utils.TimingsTraceAndSlog;
+import com.android.server.vcn.VcnLocation;
import com.android.server.vibrator.VibratorManagerService;
import com.android.server.voiceinteraction.VoiceInteractionManagerService;
import com.android.server.vr.VrManagerService;
@@ -438,7 +439,7 @@ public final class SystemServer implements Dumpable {
"/apex/com.android.uwb/javalib/service-uwb.jar";
private static final String UWB_SERVICE_CLASS = "com.android.server.uwb.UwbService";
private static final String BLUETOOTH_APEX_SERVICE_JAR_PATH =
- "/apex/com.android.btservices/javalib/service-bluetooth.jar";
+ "/apex/com.android.bt/javalib/service-bluetooth.jar";
private static final String BLUETOOTH_SERVICE_CLASS =
"com.android.server.bluetooth.BluetoothService";
private static final String DEVICE_LOCK_SERVICE_CLASS =
@@ -885,6 +886,17 @@ public final class SystemServer implements Dumpable {
SystemServiceRegistry.sEnableServiceNotFoundWtf = true;
+ // Prepare the thread pool for init tasks that can be parallelized
+ SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
+ mDumper.addDumpable(tp);
+
+ if (android.server.Flags.earlySystemConfigInit()) {
+ // SystemConfig init is expensive, so enqueue the work as early as possible to allow
+ // concurrent execution before it's needed (typically by ActivityManagerService).
+ // As native library loading is also expensive, this is a good place to start.
+ startSystemConfigInit(t);
+ }
+
// Initialize native services.
System.loadLibrary("android_servers");
@@ -917,9 +929,6 @@ public final class SystemServer implements Dumpable {
mDumper.addDumpable(mSystemServiceManager);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
- // Prepare the thread pool for init tasks that can be parallelized
- SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
- mDumper.addDumpable(tp);
// Lazily load the pre-installed system font map in SystemServer only if we're not doing
// the optimized font loading in the FontManagerService.
@@ -1073,6 +1082,14 @@ public final class SystemServer implements Dumpable {
}
}
+ private void startSystemConfigInit(TimingsTraceAndSlog t) {
+ Slog.i(TAG, "Reading configuration...");
+ final String tagSystemConfig = "ReadingSystemConfig";
+ t.traceBegin(tagSystemConfig);
+ SystemServerInitThreadPool.submit(SystemConfig::getInstance, tagSystemConfig);
+ t.traceEnd();
+ }
+
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
@@ -1111,11 +1128,11 @@ public final class SystemServer implements Dumpable {
mDumper.addDumpable(watchdog);
t.traceEnd();
- Slog.i(TAG, "Reading configuration...");
- final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
- t.traceBegin(TAG_SYSTEM_CONFIG);
- SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
- t.traceEnd();
+ // Legacy entry point for starting SystemConfig init, only needed if the early init flag is
+ // disabled and we haven't already triggered init before bootstrap services.
+ if (!android.server.Flags.earlySystemConfigInit()) {
+ startSystemConfigInit(t);
+ }
// Orchestrates some ProtoLogging functionality.
if (android.tracing.Flags.clientSideProtoLogging()) {
@@ -1929,6 +1946,10 @@ public final class SystemServer implements Dumpable {
}
t.traceEnd();
+ t.traceBegin("UpdateMetricsIfNeeded");
+ mPackageManagerService.updateMetricsIfNeeded();
+ t.traceEnd();
+
t.traceBegin("PerformFstrimIfNeeded");
try {
mPackageManagerService.performFstrimIfNeeded();
@@ -2234,10 +2255,13 @@ public final class SystemServer implements Dumpable {
t.traceBegin("StartVcnManagementService");
try {
- // TODO: b/375213246 When VCN is in mainline module, load it from the apex path.
- // Whether VCN will be in apex or in the platform will be gated by a build system
- // flag.
- mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+ if (VcnLocation.IS_VCN_IN_MAINLINE) {
+ mSystemServiceManager.startServiceFromJar(
+ CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS,
+ CONNECTIVITY_SERVICE_APEX_PATH);
+ } else {
+ mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
+ }
} catch (Throwable e) {
reportWtf("starting VCN Management Service", e);
}
@@ -3093,18 +3117,13 @@ 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_AWARE)
|| (com.android.ranging.flags.Flags.rangingCsEnabled()
&& context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) {
+ PackageManager.FEATURE_BLUETOOTH_LE))) {
t.traceBegin("RangingService");
- // TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next.
- try {
- mSystemServiceManager.startServiceFromJar(RANGING_SERVICE_CLASS,
- RANGING_APEX_SERVICE_JAR_PATH);
- } catch (Throwable e) {
- Slog.d(TAG, "service-ranging.jar not found, not starting RangingService");
- }
+ mSystemServiceManager.startServiceFromJar(RANGING_SERVICE_CLASS,
+ RANGING_APEX_SERVICE_JAR_PATH);
t.traceEnd();
}
}
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 0d222fb4409e..141966dd6306 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -10,6 +10,13 @@ flag {
}
flag {
+ namespace: "system_performance"
+ name: "early_system_config_init"
+ description: "Perform earlier initialization of SystemConfig in system server startup."
+ bug: "383869534"
+}
+
+flag {
name: "remove_text_service"
namespace: "wear_frameworks"
description: "Remove TextServiceManagerService on Wear"
diff --git a/services/musicrecognition/OWNERS b/services/musicrecognition/OWNERS
index 037b04831260..820be004efd5 100644
--- a/services/musicrecognition/OWNERS
+++ b/services/musicrecognition/OWNERS
@@ -1,5 +1,4 @@
# Bug component: 830636
oni@google.com
-volnov@google.com
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index d2c91ff2ef60..232bb83fdf9f 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -286,14 +286,21 @@ class AppIdPermissionPolicy : SchemePolicy() {
return@forEach
}
var newFlags = oldFlags
+ val isSystemOrInstalled =
+ packageState.isSystem || packageState.getUserStateOrDefault(userId).isInstalled
newFlags =
if (
- newFlags.hasBits(PermissionFlags.ROLE) ||
- newFlags.hasBits(PermissionFlags.PREGRANT)
+ isSystemOrInstalled && (
+ newFlags.hasBits(PermissionFlags.ROLE) ||
+ newFlags.hasBits(PermissionFlags.PREGRANT)
+ )
) {
newFlags or PermissionFlags.RUNTIME_GRANTED
} else {
- newFlags andInv PermissionFlags.RUNTIME_GRANTED
+ newFlags andInv (
+ PermissionFlags.RUNTIME_GRANTED or PermissionFlags.ROLE or
+ PermissionFlags.PREGRANT
+ )
}
newFlags = newFlags andInv USER_SETTABLE_MASK
if (newFlags.hasBits(PermissionFlags.LEGACY_GRANTED)) {
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 228e32e98cc7..fc585c9e0f96 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -16,6 +16,11 @@
package com.android.server.profcollect;
+import static android.content.Intent.ACTION_BATTERY_LOW;
+import static android.content.Intent.ACTION_BATTERY_OKAY;
+import static android.content.Intent.ACTION_SCREEN_OFF;
+import static android.content.Intent.ACTION_SCREEN_ON;
+
import android.Manifest;
import android.annotation.RequiresPermission;
import android.app.job.JobInfo;
@@ -32,6 +37,7 @@ import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
@@ -70,10 +76,12 @@ public final class ProfcollectForwardingService extends SystemService {
private int mUsageSetting;
private boolean mUploadEnabled;
- private static boolean sVerityEnforced;
- private boolean mAdbActive;
+ static boolean sVerityEnforced;
+ static boolean sIsInteractive;
+ static boolean sAdbActive;
+ static boolean sIsBatteryLow;
- private IProfCollectd mIProfcollect;
+ private static IProfCollectd sIProfcollect;
private static ProfcollectForwardingService sSelfService;
private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
@@ -86,17 +94,28 @@ public final class ProfcollectForwardingService extends SystemService {
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) {
+ if (ACTION_BATTERY_LOW.equals(intent.getAction())) {
+ sIsBatteryLow = true;
+ } else if (ACTION_BATTERY_OKAY.equals(intent.getAction())) {
+ sIsBatteryLow = false;
+ } else if (ACTION_SCREEN_ON.equals(intent.getAction())) {
+ Log.d(LOG_TAG, "Received broadcast that the device became interactive, was "
+ + sIsInteractive);
+ sIsInteractive = true;
+ } else if (ACTION_SCREEN_OFF.equals(intent.getAction())) {
+ Log.d(LOG_TAG, "Received broadcast that the device became noninteractive, was "
+ + sIsInteractive);
+ sIsInteractive = false;
+ } else if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) {
Log.d(LOG_TAG, "Received broadcast to pack and upload reports");
createAndUploadReport(sSelfService);
- }
- if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) {
+ } else if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) {
boolean isADB = intent.getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false);
if (isADB) {
boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
Log.d(LOG_TAG, "Received broadcast that ADB became " + connected
- + ", was " + mAdbActive);
- mAdbActive = connected;
+ + ", was " + sAdbActive);
+ sAdbActive = connected;
}
}
}
@@ -129,6 +148,10 @@ public final class ProfcollectForwardingService extends SystemService {
context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled);
final IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_BATTERY_LOW);
+ filter.addAction(ACTION_BATTERY_OKAY);
+ filter.addAction(ACTION_SCREEN_ON);
+ filter.addAction(ACTION_SCREEN_OFF);
filter.addAction(INTENT_UPLOAD_PROFILES);
filter.addAction(UsbManager.ACTION_USB_STATE);
context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
@@ -153,14 +176,24 @@ public final class ProfcollectForwardingService extends SystemService {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
UsbManager usbManager = getContext().getSystemService(UsbManager.class);
if (usbManager == null) {
- mAdbActive = false;
- return;
+ sAdbActive = false;
+ Log.d(LOG_TAG, "USBManager is not ready");
+ } else {
+ sAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1);
+ Log.d(LOG_TAG, "ADB is " + sAdbActive + " on system startup");
+ }
+
+ PowerManager powerManager = getContext().getSystemService(PowerManager.class);
+ if (powerManager == null) {
+ sIsInteractive = true;
+ Log.d(LOG_TAG, "PowerManager is not ready");
+ } else {
+ sIsInteractive = powerManager.isInteractive();
+ Log.d(LOG_TAG, "Device is interactive " + sIsInteractive + " on system startup");
}
- mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1);
- Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup");
}
if (phase == PHASE_BOOT_COMPLETED) {
- if (mIProfcollect == null) {
+ if (sIProfcollect == null) {
return;
}
BackgroundThread.get().getThreadHandler().post(() -> {
@@ -172,22 +205,22 @@ public final class ProfcollectForwardingService extends SystemService {
}
private void registerProviderStatusCallback() {
- if (mIProfcollect == null) {
+ if (sIProfcollect == null) {
return;
}
try {
- mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback);
+ sIProfcollect.registerProviderStatusCallback(mProviderStatusCallback);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to register provider status callback: " + e.getMessage());
}
}
private boolean serviceHasSupportedTraceProvider() {
- if (mIProfcollect == null) {
+ if (sIProfcollect == null) {
return false;
}
try {
- return !mIProfcollect.get_supported_provider().isEmpty();
+ return !sIProfcollect.get_supported_provider().isEmpty();
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to get supported provider: " + e.getMessage());
return false;
@@ -209,7 +242,7 @@ public final class ProfcollectForwardingService extends SystemService {
IProfCollectd.Stub.asInterface(
ServiceManager.getServiceOrThrow("profcollectd"));
profcollectd.asBinder().linkToDeath(new ProfcollectdDeathRecipient(), /*flags*/0);
- mIProfcollect = profcollectd;
+ sIProfcollect = profcollectd;
return true;
} catch (ServiceManager.ServiceNotFoundException | RemoteException e) {
Log.w(LOG_TAG, "Failed to connect profcollectd binder service.");
@@ -233,7 +266,8 @@ public final class ProfcollectForwardingService extends SystemService {
break;
case MESSAGE_REGISTER_SCHEDULERS:
registerObservers();
- ProfcollectBGJobService.schedule(getContext());
+ PeriodicTraceJobService.schedule(getContext());
+ ReportProcessJobService.schedule(getContext());
break;
default:
throw new AssertionError("Unknown message: " + message);
@@ -246,27 +280,66 @@ public final class ProfcollectForwardingService extends SystemService {
public void binderDied() {
Log.w(LOG_TAG, "profcollectd has died");
- mIProfcollect = null;
+ sIProfcollect = null;
tryConnectNativeService();
}
}
/**
- * Background trace process service.
+ * Background report process and upload service.
*/
- public static class ProfcollectBGJobService extends JobService {
- // Unique ID in system service
- private static final int JOB_IDLE_PROCESS = 260817;
+ public static class PeriodicTraceJobService extends JobService {
+ // Unique ID in system server
+ private static final int PERIODIC_TRACE_JOB_ID = 241207;
private static final ComponentName JOB_SERVICE_NAME = new ComponentName(
"android",
- ProfcollectBGJobService.class.getName());
+ PeriodicTraceJobService.class.getName());
/**
* Attach the service to the system job scheduler.
*/
public static void schedule(Context context) {
+ final int interval = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
+ "collection_interval", 600);
JobScheduler js = context.getSystemService(JobScheduler.class);
- js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME)
+ js.schedule(new JobInfo.Builder(PERIODIC_TRACE_JOB_ID, JOB_SERVICE_NAME)
+ .setPeriodic(TimeUnit.SECONDS.toMillis(interval))
+ // PRIORITY_DEFAULT is the highest priority we can request for a periodic job.
+ .setPriority(JobInfo.PRIORITY_DEFAULT)
+ .build());
+ }
+
+ @Override
+ public boolean onStartJob(JobParameters params) {
+ if (sIProfcollect != null) {
+ Utils.traceSystem(sIProfcollect, "periodic");
+ }
+ jobFinished(params, false);
+ return true;
+ }
+
+ @Override
+ public boolean onStopJob(JobParameters params) {
+ return false;
+ }
+ }
+
+ /**
+ * Background report process and upload service.
+ */
+ public static class ReportProcessJobService extends JobService {
+ // Unique ID in system server
+ private static final int REPORT_PROCESS_JOB_ID = 260817;
+ private static final ComponentName JOB_SERVICE_NAME = new ComponentName(
+ "android",
+ ReportProcessJobService.class.getName());
+
+ /**
+ * Attach the service to the system job scheduler.
+ */
+ public static void schedule(Context context) {
+ JobScheduler js = context.getSystemService(JobScheduler.class);
+ js.schedule(new JobInfo.Builder(REPORT_PROCESS_JOB_ID, JOB_SERVICE_NAME)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
.setPeriodic(BG_PROCESS_INTERVAL)
@@ -283,7 +356,6 @@ public final class ProfcollectForwardingService extends SystemService {
@Override
public boolean onStopJob(JobParameters params) {
- // TODO: Handle this?
return false;
}
}
@@ -311,14 +383,8 @@ public final class ProfcollectForwardingService extends SystemService {
private class AppLaunchObserver extends ActivityMetricsLaunchObserver {
@Override
public void onIntentStarted(Intent intent, long timestampNanos) {
- if (mIProfcollect == null) {
- return;
- }
- if (mAdbActive) {
- return;
- }
if (Utils.withFrequency("applaunch_trace_freq", 5)) {
- Utils.traceSystem(mIProfcollect, "applaunch");
+ Utils.traceSystem(sIProfcollect, "applaunch");
}
}
}
@@ -336,15 +402,9 @@ public final class ProfcollectForwardingService extends SystemService {
}
private void traceOnDex2oatStart() {
- if (mIProfcollect == null) {
- return;
- }
- if (mAdbActive) {
- return;
- }
if (Utils.withFrequency("dex2oat_trace_freq", 25)) {
// Dex2oat could take a while before it starts. Add a short delay before start tracing.
- Utils.traceSystem(mIProfcollect, "dex2oat", /* delayMs */ 1000);
+ Utils.traceSystem(sIProfcollect, "dex2oat", /* delayMs */ 1000);
}
}
@@ -367,12 +427,12 @@ public final class ProfcollectForwardingService extends SystemService {
private static void createAndUploadReport(ProfcollectForwardingService pfs) {
BackgroundThread.get().getThreadHandler().post(() -> {
- if (pfs.mIProfcollect == null) {
+ if (pfs.sIProfcollect == null) {
return;
}
String reportName;
try {
- reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip";
+ reportName = pfs.sIProfcollect.report(pfs.mUsageSetting) + ".zip";
} catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to create report: " + e.getMessage());
return;
@@ -411,7 +471,7 @@ public final class ProfcollectForwardingService extends SystemService {
return;
}
if (Utils.withFrequency("camera_trace_freq", 10)) {
- Utils.traceProcess(mIProfcollect,
+ Utils.traceProcess(sIProfcollect,
"camera",
"android.hardware.camera.provider",
/* durationMs */ 5000);
diff --git a/services/profcollect/src/com/android/server/profcollect/Utils.java b/services/profcollect/src/com/android/server/profcollect/Utils.java
index a8016a0b641e..c109f5cf05b6 100644
--- a/services/profcollect/src/com/android/server/profcollect/Utils.java
+++ b/services/profcollect/src/com/android/server/profcollect/Utils.java
@@ -28,28 +28,29 @@ import com.android.internal.os.BackgroundThread;
import java.time.Instant;
import java.util.concurrent.ThreadLocalRandom;
-public final class Utils {
+final class Utils {
private static Instant lastTraceTime = Instant.EPOCH;
private static final int TRACE_COOLDOWN_SECONDS = 30;
- public static boolean withFrequency(String configName, int defaultFrequency) {
+ static boolean withFrequency(String configName, int defaultFrequency) {
int threshold = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, configName, defaultFrequency);
int randomNum = ThreadLocalRandom.current().nextInt(100);
return randomNum < threshold;
}
- public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName) {
- if (mIProfcollect == null) {
- return false;
- }
- if (isInCooldownOrReset()) {
+ /**
+ * Request a system-wide trace.
+ * Will be ignored if the device does not meet trace criteria or is being rate limited.
+ */
+ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName) {
+ if (!checkPrerequisites(iprofcollectd)) {
return false;
}
BackgroundThread.get().getThreadHandler().post(() -> {
try {
- mIProfcollect.trace_system(eventName);
+ iprofcollectd.trace_system(eventName);
} catch (RemoteException | ServiceSpecificException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
@@ -57,16 +58,17 @@ public final class Utils {
return true;
}
- public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName, int delayMs) {
- if (mIProfcollect == null) {
- return false;
- }
- if (isInCooldownOrReset()) {
+ /**
+ * Request a system-wide trace after a delay.
+ * Will be ignored if the device does not meet trace criteria or is being rate limited.
+ */
+ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName, int delayMs) {
+ if (!checkPrerequisites(iprofcollectd)) {
return false;
}
BackgroundThread.get().getThreadHandler().postDelayed(() -> {
try {
- mIProfcollect.trace_system(eventName);
+ iprofcollectd.trace_system(eventName);
} catch (RemoteException | ServiceSpecificException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
@@ -74,17 +76,18 @@ public final class Utils {
return true;
}
- public static boolean traceProcess(IProfCollectd mIProfcollect,
+ /**
+ * Request a single-process trace.
+ * Will be ignored if the device does not meet trace criteria or is being rate limited.
+ */
+ static boolean traceProcess(IProfCollectd iprofcollectd,
String eventName, String processName, int durationMs) {
- if (mIProfcollect == null) {
- return false;
- }
- if (isInCooldownOrReset()) {
+ if (!checkPrerequisites(iprofcollectd)) {
return false;
}
BackgroundThread.get().getThreadHandler().post(() -> {
try {
- mIProfcollect.trace_process(eventName,
+ iprofcollectd.trace_process(eventName,
processName,
durationMs);
} catch (RemoteException | ServiceSpecificException e) {
@@ -105,4 +108,17 @@ public final class Utils {
}
return true;
}
+
+ private static boolean checkPrerequisites(IProfCollectd iprofcollectd) {
+ if (iprofcollectd == null) {
+ return false;
+ }
+ if (isInCooldownOrReset()) {
+ return false;
+ }
+ return ProfcollectForwardingService.sVerityEnforced
+ && !ProfcollectForwardingService.sAdbActive
+ && ProfcollectForwardingService.sIsInteractive
+ && !ProfcollectForwardingService.sIsBatteryLow;
+ }
}
diff --git a/services/proguard.flags b/services/proguard.flags
index 0e1f68e03d7d..8d8b418ced0b 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -15,7 +15,10 @@
# APIs referenced by dependent JAR files and modules
# TODO(b/300514883): Pull @SystemApi keep rules from system-api.pro.
--keep interface android.annotation.SystemApi
+# TODO(b/373579455): Evaluate if <init> needs to be kept.
+-keep interface android.annotation.SystemApi {
+ void <init>();
+}
-keep @android.annotation.SystemApi class * {
public protected *;
}
diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp
index 6c4158e60ebb..8e0eb6b14432 100644
--- a/services/robotests/Android.bp
+++ b/services/robotests/Android.bp
@@ -63,7 +63,6 @@ android_robolectric_test {
instrumentation_for: "FrameworksServicesLib",
- upstream: true,
strict_mode: false,
}
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index 3ace3fb11506..95b38e56f276 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -66,7 +66,6 @@ android_robolectric_test {
instrumentation_for: "BackupFrameworksServicesLib",
- upstream: true,
strict_mode: false,
diff --git a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
index 12370954e9a5..8b357862dcbc 100644
--- a/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
+++ b/services/tests/PermissionServiceMockingTests/src/com/android/server/permission/test/AppIdPermissionPolicyPermissionResetTest.kt
@@ -72,7 +72,8 @@ class AppIdPermissionPolicyPermissionResetTest : BasePermissionPolicyTest() {
} else {
mockPackageState(
APP_ID_1,
- mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0))
+ mockAndroidPackage(PACKAGE_NAME_1, requestedPermissions = setOf(PERMISSION_NAME_0)),
+ true
)
}
setPermissionFlags(APP_ID_1, USER_ID_0, PERMISSION_NAME_0, oldFlags)
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 5db6a8f12e52..9117cc8e5ab8 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -918,6 +918,30 @@ public class VpnTest extends VpnTestBase {
}
@Test
+ public void testOnUserAddedAndRemoved_nullUserInfo() throws Exception {
+ final Vpn vpn = createVpn(PRIMARY_USER.id);
+ final Set<Range<Integer>> initialRange = rangeSet(PRIMARY_USER_RANGE);
+ // Note since mVpnProfile is a Ikev2VpnProfile, this starts an IkeV2VpnRunner.
+ startLegacyVpn(vpn, mVpnProfile);
+ // Set an initial Uid range and mock the network agent
+ vpn.mNetworkCapabilities.setUids(initialRange);
+ vpn.mNetworkAgent = mMockNetworkAgent;
+
+ // Add the restricted user and then remove it immediately. So the getUserInfo() will return
+ // null for the given restricted user id.
+ setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A);
+ doReturn(null).when(mUserManager).getUserInfo(RESTRICTED_PROFILE_A.id);
+ vpn.onUserAdded(RESTRICTED_PROFILE_A.id);
+ // Expect no range change to the NetworkCapabilities.
+ assertEquals(initialRange, vpn.mNetworkCapabilities.getUids());
+
+ // Remove the restricted user
+ vpn.onUserRemoved(RESTRICTED_PROFILE_A.id);
+ // Expect no range change to the NetworkCapabilities.
+ assertEquals(initialRange, vpn.mNetworkCapabilities.getUids());
+ }
+
+ @Test
public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller()
throws Exception {
mTestDeps.mIgnoreCallingUidChecks = false;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index f5bed999d5a0..1eb96d2256f1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -388,6 +388,34 @@ public class LocalDisplayAdapterTest {
PORT_C, false);
}
+ /**
+ * Confirm that display is marked as trusted, has own focus, disables steal top focus when it
+ * is listed in com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts.
+ */
+ @Test
+ public void testStealTopFocusDisabledDisplay() throws Exception {
+ setUpDisplay(new FakeDisplay(PORT_A));
+ setUpDisplay(new FakeDisplay(PORT_B));
+ setUpDisplay(new FakeDisplay(PORT_C));
+ updateAvailableDisplays();
+
+ doReturn(new int[]{ PORT_B }).when(mMockedResources).getIntArray(
+ com.android.internal.R.array.config_localNotStealTopFocusDisplayPorts);
+ mAdapter.registerLocked();
+
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ // This should not have the flags
+ assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(),
+ PORT_A, false);
+ // This should have the flags
+ assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(),
+ PORT_B, true);
+ // This should not have the flags
+ assertNotStealTopFocusFlag(mListener.addedDisplays.get(2).getDisplayDeviceInfoLocked(),
+ PORT_C, false);
+ }
+
@Test
public void testSupportedDisplayModesGetOverriddenWhenDisplayIsUpdated()
throws InterruptedException {
@@ -452,6 +480,42 @@ public class LocalDisplayAdapterTest {
}
/**
+ * Confirm that all local displays are not trusted, do not have their own focus, and do not
+ * steal top focus when config_localNotStealTopFocusDisplayPorts is empty:
+ */
+ @Test
+ public void testDisplayFlagsForNoConfigLocalNotStealTopFocusDisplayPorts() throws Exception {
+ setUpDisplay(new FakeDisplay(PORT_A));
+ setUpDisplay(new FakeDisplay(PORT_C));
+ updateAvailableDisplays();
+
+ // config_localNotStealTopFocusDisplayPorts is null
+ mAdapter.registerLocked();
+
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+ // This should not have the flags
+ assertNotStealTopFocusFlag(mListener.addedDisplays.get(0).getDisplayDeviceInfoLocked(),
+ PORT_A, false);
+ // This should not have the flags
+ assertNotStealTopFocusFlag(mListener.addedDisplays.get(1).getDisplayDeviceInfoLocked(),
+ PORT_C, false);
+ }
+
+ private static void assertNotStealTopFocusFlag(
+ DisplayDeviceInfo info, int expectedPort, boolean shouldHaveFlags) {
+ final DisplayAddress.Physical address = (DisplayAddress.Physical) info.address;
+ assertNotNull(address);
+ assertEquals(expectedPort, address.getPort());
+ assertEquals(DISPLAY_MODEL, address.getModel());
+ assertEquals(shouldHaveFlags,
+ (info.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0);
+ assertEquals(shouldHaveFlags, (info.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0);
+ // display is always trusted since it is created by the system
+ assertEquals(true, (info.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0);
+ }
+
+ /**
* Confirm that external display uses physical density.
*/
@Test
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index 94d4b9522d60..03bd73c52083 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -24,6 +24,7 @@ cc_library_shared {
":lib_freezer_native",
":lib_oomConnection_native",
":lib_lazilyRegisteredServices_native",
+ ":lib_phantomProcessList_native",
"onload.cpp",
],
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index 9b4c8178b092..30fa7de94af1 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -28,6 +28,7 @@ int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_Freezer(JNIEnv* env);
int register_android_server_am_OomConnection(JNIEnv* env);
int register_android_server_utils_LazyJniRegistrar(JNIEnv* env);
+int register_android_server_am_PhantomProcessList(JNIEnv* env);
};
using namespace android;
@@ -46,5 +47,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_am_Freezer(env);
register_android_server_am_OomConnection(env);
register_android_server_utils_LazyJniRegistrar(env);
+ register_android_server_am_PhantomProcessList(env);
return JNI_VERSION_1_4;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
index d203de537b81..cf83396d059a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java
@@ -397,6 +397,12 @@ public final class CachedAppOptimizerTest {
// When we override new reasonable throttle values after init...
mCountDown = new CountDownLatch(8);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ CachedAppOptimizer.KEY_COMPACT_THROTTLE_MIN_OOM_ADJ,
+ Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_MIN_OOM_ADJ + 1), false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ CachedAppOptimizer.KEY_COMPACT_THROTTLE_MAX_OOM_ADJ,
+ Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_MAX_OOM_ADJ - 1), false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
CachedAppOptimizer.KEY_COMPACT_THROTTLE_1,
Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1), false);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -414,12 +420,6 @@ public final class CachedAppOptimizerTest {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
CachedAppOptimizer.KEY_COMPACT_THROTTLE_6,
Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1), false);
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
- CachedAppOptimizer.KEY_COMPACT_THROTTLE_MIN_OOM_ADJ,
- Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_MIN_OOM_ADJ + 1), false);
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
- CachedAppOptimizer.KEY_COMPACT_THROTTLE_MAX_OOM_ADJ,
- Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_MAX_OOM_ADJ - 1), false);
assertThat(mCountDown.await(7, TimeUnit.SECONDS)).isTrue();
// Then those flags values are reflected in the compactor.
diff --git a/services/tests/ondeviceintelligencetests/OWNERS b/services/tests/ondeviceintelligencetests/OWNERS
index a4fc7582a785..d08d34ad3108 100644
--- a/services/tests/ondeviceintelligencetests/OWNERS
+++ b/services/tests/ondeviceintelligencetests/OWNERS
@@ -1,3 +1,2 @@
shiqing@google.com
sandeepbandaru@google.com
-shivanker@google.com
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 009ce88cfd6c..d702cae248a9 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -33,9 +33,6 @@ android_test {
"test-apps/DisplayManagerTestApp/src/**/*.java",
],
- kotlincflags: [
- "-Werror",
- ],
static_libs: [
"a11ychecker",
"aatf",
diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS
index d8a9400d5180..69feb1d86983 100644
--- a/services/tests/servicestests/src/com/android/server/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/OWNERS
@@ -6,5 +6,6 @@ per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
per-file BatteryServiceTest.java = file:platform/hardware/interfaces:/health/OWNERS
per-file GestureLauncherServiceTest.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
+per-file GestureLauncherServiceTest.java = file:/INPUT_OWNERS
per-file PinnerServiceTest.java = file:/apct-tests/perftests/OWNERS
per-file SecurityStateTest.java = file:/SECURITY_STATE_OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/OWNERS b/services/tests/servicestests/src/com/android/server/accessibility/OWNERS
index b74281edbf52..c7c23f081044 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/accessibility/OWNERS
@@ -1 +1,6 @@
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 44215.
+
include /core/java/android/view/accessibility/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/OWNERS b/services/tests/servicestests/src/com/android/server/accessibility/magnification/OWNERS
new file mode 100644
index 000000000000..9592bfdfa73b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 1530954
+#
+# The above component is for automated test bugs. If you are a human looking to report
+# a bug in this codebase then please use component 770744.
+
+include /services/accessibility/java/com/android/server/accessibility/magnification/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
index fde3422b1ff3..17f5ebb3b02a 100644
--- a/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/app/GameManagerServiceSettingsTests.java
@@ -130,9 +130,9 @@ public class GameManagerServiceSettingsTests {
assertEquals(GameManager.GAME_MODE_STANDARD, settings.getGameModeLocked(PACKAGE_NAME_4));
// test game mode configs
- assertNull(settings.getConfigOverride(PACKAGE_NAME_1));
- assertNull(settings.getConfigOverride(PACKAGE_NAME_3));
- GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2);
+ assertNull(settings.getConfigOverrideLocked(PACKAGE_NAME_1));
+ assertNull(settings.getConfigOverrideLocked(PACKAGE_NAME_3));
+ GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_2);
assertNotNull(config);
assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_STANDARD));
@@ -152,7 +152,7 @@ public class GameManagerServiceSettingsTests {
assertEquals(batteryConfig.getFpsStr(), GameModeConfiguration.DEFAULT_FPS);
assertFalse(batteryConfig.getUseAngle());
- config = settings.getConfigOverride(PACKAGE_NAME_4);
+ config = settings.getConfigOverrideLocked(PACKAGE_NAME_4);
assertNotNull(config);
GameModeConfiguration customConfig = config.getGameModeConfiguration(
GameManager.GAME_MODE_CUSTOM);
@@ -177,7 +177,7 @@ public class GameManagerServiceSettingsTests {
GameManagerSettings settings = new GameManagerSettings(context.getFilesDir());
assertTrue(settings.readPersistentDataLocked());
- final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_1);
+ final GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_1);
assertNotNull(config);
final GameModeConfiguration batteryConfig = config.getGameModeConfiguration(
GameManager.GAME_MODE_BATTERY);
@@ -218,7 +218,7 @@ public class GameManagerServiceSettingsTests {
assertEquals(2, settings.getGameModeLocked(PACKAGE_NAME_2));
assertEquals(3, settings.getGameModeLocked(PACKAGE_NAME_3));
- final GamePackageConfiguration config = settings.getConfigOverride(PACKAGE_NAME_2);
+ final GamePackageConfiguration config = settings.getConfigOverrideLocked(PACKAGE_NAME_2);
assertNotNull(config);
final GameModeConfiguration batteryConfig = config.getGameModeConfiguration(
GameManager.GAME_MODE_BATTERY);
@@ -248,7 +248,7 @@ public class GameManagerServiceSettingsTests {
GameModeConfiguration batteryConfig = config.getOrAddDefaultGameModeConfiguration(
GameManager.GAME_MODE_BATTERY);
batteryConfig.setScaling(0.77f);
- settings.setConfigOverride(PACKAGE_NAME_2, config);
+ settings.setConfigOverrideLocked(PACKAGE_NAME_2, config);
// set config for app4
config = new GamePackageConfiguration(PACKAGE_NAME_4);
@@ -256,15 +256,15 @@ public class GameManagerServiceSettingsTests {
GameManager.GAME_MODE_CUSTOM);
customConfig.setScaling(0.4f);
customConfig.setFpsStr("30");
- settings.setConfigOverride(PACKAGE_NAME_4, config);
+ settings.setConfigOverrideLocked(PACKAGE_NAME_4, config);
settings.writePersistentDataLocked();
// clear the settings in memory
- settings.removeGame(PACKAGE_NAME_1);
- settings.removeGame(PACKAGE_NAME_2);
- settings.removeGame(PACKAGE_NAME_3);
- settings.removeGame(PACKAGE_NAME_4);
+ settings.removeGameLocked(PACKAGE_NAME_1);
+ settings.removeGameLocked(PACKAGE_NAME_2);
+ settings.removeGameLocked(PACKAGE_NAME_3);
+ settings.removeGameLocked(PACKAGE_NAME_4);
// read back in and verify
assertTrue(settings.readPersistentDataLocked());
@@ -273,9 +273,9 @@ public class GameManagerServiceSettingsTests {
assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_3));
assertEquals(1, settings.getGameModeLocked(PACKAGE_NAME_4));
- config = settings.getConfigOverride(PACKAGE_NAME_1);
+ config = settings.getConfigOverrideLocked(PACKAGE_NAME_1);
assertNull(config);
- config = settings.getConfigOverride(PACKAGE_NAME_2);
+ config = settings.getConfigOverrideLocked(PACKAGE_NAME_2);
assertNotNull(config);
batteryConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_BATTERY);
assertNotNull(batteryConfig);
@@ -292,7 +292,7 @@ public class GameManagerServiceSettingsTests {
assertEquals(performanceConfig.getFpsStr(), "60");
assertTrue(performanceConfig.getUseAngle());
- config = settings.getConfigOverride(PACKAGE_NAME_4);
+ config = settings.getConfigOverrideLocked(PACKAGE_NAME_4);
assertNotNull(config);
customConfig = config.getGameModeConfiguration(GameManager.GAME_MODE_CUSTOM);
assertNotNull(customConfig);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index 605fed09dd9f..c7efa318af99 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -45,7 +45,6 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.biometrics.AuthenticationStateListener;
import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -504,23 +503,9 @@ public class AuthServiceTest {
eq(callback));
}
- @Test(expected = UnsupportedOperationException.class)
- public void testGetLastAuthenticationTime_flaggedOff_throwsUnsupportedOperationException()
- throws Exception {
- mSetFlagsRule.disableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
- setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
-
- mAuthService = new AuthService(mContext, mInjector);
- mAuthService.onStart();
-
- mAuthService.mImpl.getLastAuthenticationTime(0,
- BiometricManager.Authenticators.BIOMETRIC_STRONG);
- }
-
@Test
- public void testGetLastAuthenticationTime_flaggedOn_callsBiometricService()
+ public void testGetLastAuthenticationTime_callsBiometricService()
throws Exception {
- mSetFlagsRule.enableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
mAuthService = new AuthService(mContext, mInjector);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 88829c1a99b3..8b6a4a22d691 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -1973,20 +1973,9 @@ public class BiometricServiceTest {
verifyNoMoreInteractions(callback);
}
- @Test(expected = UnsupportedOperationException.class)
- public void testGetLastAuthenticationTime_flagOff_throwsUnsupportedOperationException()
- throws RemoteException {
- mSetFlagsRule.disableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
-
- mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
- mBiometricService.mImpl.getLastAuthenticationTime(0, Authenticators.BIOMETRIC_STRONG);
- }
-
@Test
- public void testGetLastAuthenticationTime_flagOn_callsKeystoreAuthorization()
+ public void testGetLastAuthenticationTime_callsKeystoreAuthorization()
throws RemoteException {
- mSetFlagsRule.enableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
-
final int[] hardwareAuthenticators = new int[] {
HardwareAuthenticatorType.PASSWORD,
HardwareAuthenticatorType.FINGERPRINT
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 87c9db2fe565..acbce36c3d7f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -354,14 +354,20 @@ public abstract class BaseLockSettingsServiceTests {
@After
public void tearDown_baseServices() throws Exception {
- mStorage.closeDatabase();
+ if (mStorage != null) {
+ mStorage.closeDatabase();
+ }
File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db");
assertTrue(!db.exists() || db.delete());
- File storageDir = mStorage.mStorageDir;
- assertTrue(FileUtils.deleteContents(storageDir));
+ if (mStorage != null) {
+ File storageDir = mStorage.mStorageDir;
+ assertTrue(FileUtils.deleteContents(storageDir));
+ }
- mPasswordSlotManager.cleanup();
+ if (mPasswordSlotManager != null) {
+ mPasswordSlotManager.cleanup();
+ }
}
protected void flushHandlerTasks() {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 02b86db6ab6f..387b89a41eba 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -124,7 +124,9 @@ public class LockSettingsStorageTests {
@After
public void tearDown() throws Exception {
- mStorage.closeDatabase();
+ if (mStorage != null) {
+ mStorage.closeDatabase();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
index 2faf6a2b29d1..2c2b9374fdf9 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/PasswordSlotManagerTests.java
@@ -49,7 +49,9 @@ public class PasswordSlotManagerTests {
@After
public void tearDown() throws Exception {
- mManager.cleanup();
+ if (mManager != null) {
+ mManager.cleanup();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
index 1514de04fb08..5add74e5b69e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
@@ -156,9 +156,12 @@ public class KeySyncTaskTest {
@After
public void tearDown() {
- mRecoverableKeyStoreDb.close();
- mDatabaseFile.delete();
-
+ if (mRecoverableKeyStoreDb != null) {
+ mRecoverableKeyStoreDb.close();
+ }
+ if (mDatabaseFile != null) {
+ mDatabaseFile.delete();
+ }
File file = new File(InstrumentationRegistry.getTargetContext().getFilesDir(),
SNAPSHOT_TOP_LEVEL_DIRECTORY);
FileUtils.deleteContentsAndDir(file);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
index c09e09c8404f..46eaba7dace6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/PlatformKeyManagerTest.java
@@ -117,8 +117,12 @@ public class PlatformKeyManagerTest {
@After
public void tearDown() {
- mRecoverableKeyStoreDb.close();
- mDatabaseFile.delete();
+ if (mRecoverableKeyStoreDb != null) {
+ mRecoverableKeyStoreDb.close();
+ }
+ if (mDatabaseFile != null) {
+ mDatabaseFile.delete();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
index 64130266b2c4..e6a6e36e75d6 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyGeneratorTest.java
@@ -89,8 +89,12 @@ public class RecoverableKeyGeneratorTest {
keyStore.load(/*param=*/ null);
keyStore.deleteEntry(WRAPPING_KEY_ALIAS);
- mRecoverableKeyStoreDb.close();
- mDatabaseFile.delete();
+ if (mRecoverableKeyStoreDb != null) {
+ mRecoverableKeyStoreDb.close();
+ }
+ if (mDatabaseFile != null) {
+ mDatabaseFile.delete();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 7641fb957cc8..878c838e734b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -230,9 +230,15 @@ public class RecoverableKeyStoreManagerTest {
@After
public void tearDown() {
- mRemoteLockscreenValidationSessionStorage.finishSession(mUserId);
- mRecoverableKeyStoreDb.close();
- mDatabaseFile.delete();
+ if (mRemoteLockscreenValidationSessionStorage != null) {
+ mRemoteLockscreenValidationSessionStorage.finishSession(mUserId);
+ }
+ if (mRecoverableKeyStoreDb != null) {
+ mRecoverableKeyStoreDb.close();
+ }
+ if (mDatabaseFile != null) {
+ mDatabaseFile.delete();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
index bbd9223718ae..fb98fab52ca0 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelperTest.java
@@ -18,6 +18,8 @@ package com.android.server.locksettings.recoverablekeystore.storage;
import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
@@ -36,8 +38,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class RecoverableKeyStoreDbHelperTest {
@@ -110,7 +110,9 @@ public class RecoverableKeyStoreDbHelperTest {
@After
public void tearDown() throws Exception {
- mDatabase.close();
+ if (mDatabase != null) {
+ mDatabase.close();
+ }
}
private void createV2Tables() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
index 8bc14fc54ae1..a77d8bcd3875 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbTest.java
@@ -72,8 +72,12 @@ public class RecoverableKeyStoreDbTest {
@After
public void tearDown() {
- mRecoverableKeyStoreDb.close();
- mDatabaseFile.delete();
+ if (mRecoverableKeyStoreDb != null) {
+ mRecoverableKeyStoreDb.close();
+ }
+ if (mDatabaseFile != null) {
+ mDatabaseFile.delete();
+ }
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/OWNERS b/services/tests/servicestests/src/com/android/server/media/projection/OWNERS
index 832bcd9d70e6..3caf7faa13ec 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/media/projection/OWNERS
@@ -1 +1,2 @@
+# Bug component: 1345447
include /media/java/android/media/projection/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/memory/OWNERS b/services/tests/servicestests/src/com/android/server/memory/OWNERS
new file mode 100644
index 000000000000..4df08c1fbc2e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/memory/OWNERS
@@ -0,0 +1,3 @@
+include /MEMORY_OWNERS
+
+per-file ZramMaintenanceTest.kt = kawasin@google.com
diff --git a/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt b/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt
new file mode 100644
index 000000000000..1f59f45b05bf
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/memory/ZramMaintenanceTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.memory
+
+import android.app.job.JobInfo
+import android.app.job.JobParameters
+import android.app.job.JobScheduler
+import android.os.IMmd
+import android.os.PersistableBundle
+import android.os.RemoteException
+import android.testing.TestableContext
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+
+import com.google.common.truth.Truth.assertThat
+
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+private fun generateJobParameters(jobId: Int, extras: PersistableBundle): JobParameters {
+ return JobParameters(
+ null, "", jobId, extras, null, null, 0, false, false, false, null, null, null
+ )
+}
+
+@SmallTest
+@RunWith(JUnit4::class)
+class ZramMaintenanceTest {
+ private val context = TestableContext(InstrumentationRegistry.getInstrumentation().context)
+
+ @Captor
+ private lateinit var jobInfoCaptor: ArgumentCaptor<JobInfo>
+
+ @Mock
+ private lateinit var mockJobScheduler: JobScheduler
+
+ @Mock
+ private lateinit var mockMmd: IMmd
+
+ @Before
+ @Throws(RemoteException::class)
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ context.addMockSystemService(JobScheduler::class.java, mockJobScheduler)
+ }
+
+ @Test
+ fun startZramMaintenance() {
+ ZramMaintenance.startZramMaintenance(context)
+
+ verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+ val job = jobInfoCaptor.value
+ assertThat(job.id).isEqualTo(ZramMaintenance.JOB_ID)
+ assertThat(job.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isTrue()
+ }
+
+ @Test
+ fun startJobForFirstTime() {
+ val extras = PersistableBundle()
+ extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+ val params = generateJobParameters(
+ ZramMaintenance.JOB_ID,
+ extras,
+ )
+ `when`(mockMmd.isZramMaintenanceSupported()).thenReturn(true)
+
+ ZramMaintenance.startJob(context, params, mockMmd)
+
+ verify(mockMmd, times(1)).isZramMaintenanceSupported()
+ verify(mockMmd, times(1)).doZramMaintenanceAsync()
+ verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+ val nextJob = jobInfoCaptor.value
+ assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+ assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isFalse()
+ }
+
+ @Test
+ fun startJobWithoutCheckStatus() {
+ val extras = PersistableBundle()
+ extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, false)
+ val params = generateJobParameters(
+ ZramMaintenance.JOB_ID,
+ extras,
+ )
+
+ ZramMaintenance.startJob(context, params, mockMmd)
+
+ verify(mockMmd, never()).isZramMaintenanceSupported()
+ verify(mockMmd, times(1)).doZramMaintenanceAsync()
+ verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+ val nextJob = jobInfoCaptor.value
+ assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+ assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isFalse()
+ }
+
+ @Test
+ fun startJobZramIsDisabled() {
+ val extras = PersistableBundle()
+ extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+ val params = generateJobParameters(
+ ZramMaintenance.JOB_ID,
+ extras,
+ )
+ `when`(mockMmd.isZramMaintenanceSupported()).thenReturn(false)
+
+ ZramMaintenance.startJob(context, params, mockMmd)
+
+ verify(mockMmd, times(1)).isZramMaintenanceSupported()
+ verify(mockMmd, never()).doZramMaintenanceAsync()
+ verify(mockJobScheduler, never()).schedule(any())
+ }
+
+ @Test
+ fun startJobMmdIsNotReadyYet() {
+ val extras = PersistableBundle()
+ extras.putBoolean(ZramMaintenance.KEY_CHECK_STATUS, true)
+ val params = generateJobParameters(
+ ZramMaintenance.JOB_ID,
+ extras,
+ )
+
+ ZramMaintenance.startJob(context, params, null)
+
+ verify(mockJobScheduler, times(1)).schedule(jobInfoCaptor.capture())
+ val nextJob = jobInfoCaptor.value
+ assertThat(nextJob.id).isEqualTo(ZramMaintenance.JOB_ID)
+ assertThat(nextJob.extras.getBoolean(ZramMaintenance.KEY_CHECK_STATUS)).isTrue()
+ }
+} \ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index a0f2395f5203..d70ffd2ec050 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -159,7 +159,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Test for the first launch path, no settings file available.
*/
- public void testFirstInitialize() {
+ public void FirstInitialize() {
assertResetTimes(START_TIME, START_TIME + INTERVAL);
}
@@ -167,7 +167,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* Test for {@link ShortcutService#getLastResetTimeLocked()} and
* {@link ShortcutService#getNextResetTimeLocked()}.
*/
- public void testUpdateAndGetNextResetTimeLocked() {
+ public void UpdateAndGetNextResetTimeLocked() {
assertResetTimes(START_TIME, START_TIME + INTERVAL);
// Advance clock.
@@ -196,7 +196,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Test for the restoration from saved file.
*/
- public void testInitializeFromSavedFile() {
+ public void InitializeFromSavedFile() {
mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
@@ -220,7 +220,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Add various broken cases.
}
- public void testLoadConfig() {
+ public void LoadConfig() {
mService.updateConfigurationLocked(
ConfigConstants.KEY_RESET_INTERVAL_SEC + "=123,"
+ ConfigConstants.KEY_MAX_SHORTCUTS + "=4,"
@@ -261,22 +261,22 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// === Test for app side APIs ===
/** Test for {@link android.content.pm.ShortcutManager#getMaxShortcutCountForActivity()} */
- public void testGetMaxDynamicShortcutCount() {
+ public void GetMaxDynamicShortcutCount() {
assertEquals(MAX_SHORTCUTS, mManager.getMaxShortcutCountForActivity());
}
/** Test for {@link android.content.pm.ShortcutManager#getRemainingCallCount()} */
- public void testGetRemainingCallCount() {
+ public void GetRemainingCallCount() {
assertEquals(MAX_UPDATES_PER_INTERVAL, mManager.getRemainingCallCount());
}
- public void testGetIconMaxDimensions() {
+ public void GetIconMaxDimensions() {
assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxWidth());
assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxHeight());
}
/** Test for {@link android.content.pm.ShortcutManager#getRateLimitResetTime()} */
- public void testGetRateLimitResetTime() {
+ public void GetRateLimitResetTime() {
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
@@ -284,7 +284,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(START_TIME + 5 * INTERVAL, mManager.getRateLimitResetTime());
}
- public void testSetDynamicShortcuts() {
+ public void SetDynamicShortcuts() {
setCaller(CALLING_PACKAGE_1, USER_0);
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
@@ -354,7 +354,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testAddDynamicShortcuts() {
+ public void AddDynamicShortcuts() {
setCaller(CALLING_PACKAGE_1, USER_0);
final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -402,7 +402,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPushDynamicShortcut() {
+ public void PushDynamicShortcut() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
+ ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1");
@@ -543,7 +543,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0));
}
- public void testPushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
+ public void PushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
throws InterruptedException {
mService.updateConfigurationLocked(
ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=500");
@@ -594,7 +594,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
eq(CALLING_PACKAGE_2), any(), eq(USER_0));
}
- public void testUnlimitedCalls() {
+ public void UnlimitedCalls() {
setCaller(CALLING_PACKAGE_1, USER_0);
final ShortcutInfo si1 = makeShortcut("shortcut1");
@@ -625,7 +625,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(3, mManager.getRemainingCallCount());
}
- public void testPublishWithNoActivity() {
+ public void PublishWithNoActivity() {
// If activity is not explicitly set, use the default one.
mRunningUsers.put(USER_10, true);
@@ -731,7 +731,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPublishWithNoActivity_noMainActivityInPackage() {
+ public void PublishWithNoActivity_noMainActivityInPackage() {
mRunningUsers.put(USER_10, true);
runWithCaller(CALLING_PACKAGE_2, USER_10, () -> {
@@ -750,7 +750,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testDeleteDynamicShortcuts() {
+ public void DeleteDynamicShortcuts() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
final ShortcutInfo si2 = makeShortcut("shortcut2");
final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -791,7 +791,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(2, mManager.getRemainingCallCount());
}
- public void testDeleteAllDynamicShortcuts() {
+ public void DeleteAllDynamicShortcuts() {
final ShortcutInfo si1 = makeShortcut("shortcut1");
final ShortcutInfo si2 = makeShortcut("shortcut2");
final ShortcutInfo si3 = makeShortcut("shortcut3");
@@ -820,7 +820,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(1, mManager.getRemainingCallCount());
}
- public void testIcons() throws IOException {
+ public void Icons() throws IOException {
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
final Icon res512x512 = Icon.createWithResource(getTestContext(), R.drawable.black_512x512);
@@ -1034,7 +1034,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
*/
}
- public void testCleanupDanglingBitmaps() throws Exception {
+ public void CleanupDanglingBitmaps() throws Exception {
assertBitmapDirectories(USER_0, EMPTY_STRINGS);
assertBitmapDirectories(USER_10, EMPTY_STRINGS);
@@ -1203,7 +1203,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
maxSize));
}
- public void testShrinkBitmap() {
+ public void ShrinkBitmap() {
checkShrinkBitmap(32, 32, R.drawable.black_512x512, 32);
checkShrinkBitmap(511, 511, R.drawable.black_512x512, 511);
checkShrinkBitmap(512, 512, R.drawable.black_512x512, 512);
@@ -1226,7 +1226,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
return out.getFile();
}
- public void testOpenIconFileForWrite() throws IOException {
+ public void OpenIconFileForWrite() throws IOException {
mInjectedCurrentTimeMillis = 1000;
final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
@@ -1300,7 +1300,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertFalse(p11_1_3.getName().contains("_"));
}
- public void testUpdateShortcuts() {
+ public void UpdateShortcuts() {
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"),
@@ -1431,7 +1431,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testUpdateShortcuts_icons() {
+ public void UpdateShortcuts_icons() {
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1")
@@ -1525,7 +1525,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testShortcutManagerGetShortcuts_shortcutTypes() {
+ public void ShortcutManagerGetShortcuts_shortcutTypes() {
// Create 3 manifest and 3 dynamic shortcuts
addManifestShortcutResource(
@@ -1616,7 +1616,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s1", "s2");
}
- public void testCachedShortcuts() {
+ public void CachedShortcuts() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1700,7 +1700,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s2");
}
- public void testCachedShortcuts_accessShortcutsPermission() {
+ public void CachedShortcuts_accessShortcutsPermission() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"),
makeLongLivedShortcut("s2"), makeLongLivedShortcut("s3"),
@@ -1742,7 +1742,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertShortcutIds(mManager.getShortcuts(ShortcutManager.FLAG_MATCH_CACHED), "s3");
}
- public void testCachedShortcuts_canPassShortcutLimit() {
+ public void CachedShortcuts_canPassShortcutLimit() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=4");
@@ -1780,7 +1780,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// === Test for launcher side APIs ===
- public void testGetShortcuts() {
+ public void GetShortcuts() {
// Set up shortcuts.
@@ -1997,7 +1997,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
"s1", "s3");
}
- public void testGetShortcuts_shortcutKinds() throws Exception {
+ public void GetShortcuts_shortcutKinds() throws Exception {
// Create 3 manifest and 3 dynamic shortcuts
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -2108,7 +2108,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testGetShortcuts_resolveStrings() throws Exception {
+ public void GetShortcuts_resolveStrings() throws Exception {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
ShortcutInfo si = new ShortcutInfo.Builder(mClientContext)
.setId("id")
@@ -2156,7 +2156,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testGetShortcuts_personsFlag() {
+ public void GetShortcuts_personsFlag() {
ShortcutInfo s = new ShortcutInfo.Builder(mClientContext, "id")
.setShortLabel("label")
.setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
@@ -2204,7 +2204,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
// TODO resource
- public void testGetShortcutInfo() {
+ public void GetShortcutInfo() {
// Create shortcuts.
setCaller(CALLING_PACKAGE_1);
final ShortcutInfo s1_1 = makeShortcut(
@@ -2279,7 +2279,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals("ABC", findById(list, "s1").getTitle());
}
- public void testPinShortcutAndGetPinnedShortcuts() {
+ public void PinShortcutAndGetPinnedShortcuts() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2360,7 +2360,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* This is similar to the above test, except it used "disable" instead of "remove". It also
* does "enable".
*/
- public void testDisableAndEnableShortcuts() {
+ public void DisableAndEnableShortcuts() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
final ShortcutInfo s1_1 = makeShortcutWithTimestamp("s1", 1000);
final ShortcutInfo s1_2 = makeShortcutWithTimestamp("s2", 2000);
@@ -2485,7 +2485,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testDisableShortcuts_thenRepublish() {
+ public void DisableShortcuts_thenRepublish() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
@@ -2555,7 +2555,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPinShortcutAndGetPinnedShortcuts_multi() {
+ public void PinShortcutAndGetPinnedShortcuts_multi() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
@@ -2831,7 +2831,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPinShortcutAndGetPinnedShortcuts_assistant() {
+ public void PinShortcutAndGetPinnedShortcuts_assistant() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
@@ -2887,7 +2887,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
+ public void PinShortcutAndGetPinnedShortcuts_crossProfile_plusLaunch() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
@@ -3476,7 +3476,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testStartShortcut() {
+ public void StartShortcut() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
final ShortcutInfo s1_1 = makeShortcut(
@@ -3611,7 +3611,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check extra, etc
}
- public void testLauncherCallback() throws Throwable {
+ public void LauncherCallback() throws Throwable {
// Disable throttling for this test.
mService.updateConfigurationLocked(
ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "=99999999,"
@@ -3777,7 +3777,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.isEmpty();
}
- public void testLauncherCallback_crossProfile() throws Throwable {
+ public void LauncherCallback_crossProfile() throws Throwable {
prepareCrossProfileDataSet();
final Handler h = new Handler(Looper.getMainLooper());
@@ -3900,7 +3900,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// === Test for persisting ===
- public void testSaveAndLoadUser_empty() {
+ public void SaveAndLoadUser_empty() {
assertTrue(mManager.setDynamicShortcuts(list()));
Log.i(TAG, "Saved state");
@@ -3917,7 +3917,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Try save and load, also stop/start the user.
*/
- public void testSaveAndLoadUser() {
+ public void SaveAndLoadUser() {
// First, create some shortcuts and save.
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4058,7 +4058,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check all other fields
}
- public void testLoadCorruptedShortcuts() throws Exception {
+ public void LoadCorruptedShortcuts() throws Exception {
initService();
addPackage("com.android.chrome", 0, 0);
@@ -4072,7 +4072,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertNull(ShortcutPackage.loadFromFile(mService, user, corruptedShortcutPackage, false));
}
- public void testSaveCorruptAndLoadUser() throws Exception {
+ public void SaveCorruptAndLoadUser() throws Exception {
// First, create some shortcuts and save.
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.black_64x16);
@@ -4228,7 +4228,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check all other fields
}
- public void testCleanupPackage() {
+ public void CleanupPackage() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcut("s0_1"))));
@@ -4505,7 +4505,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mService.saveDirtyInfo();
}
- public void testCleanupPackage_republishManifests() {
+ public void CleanupPackage_republishManifests() {
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
R.xml.shortcut_2);
@@ -4573,7 +4573,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHandleGonePackage_crossProfile() {
+ public void HandleGonePackage_crossProfile() {
// Create some shortcuts.
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
@@ -4845,7 +4845,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertEquals(expected, spi.canRestoreTo(mService, pi, true));
}
- public void testCanRestoreTo() {
+ public void CanRestoreTo() {
addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sig1");
addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 10, "sig1", "sig2");
addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 10, "sig1");
@@ -4908,7 +4908,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkCanRestoreTo(DISABLED_REASON_BACKUP_NOT_SUPPORTED, spi3, true, 10, true, "sig1");
}
- public void testHandlePackageDelete() {
+ public void HandlePackageDelete() {
checkHandlePackageDeleteInner((userId, packageName) -> {
uninstallPackage(userId, packageName);
mService.mPackageMonitor.onReceive(getTestContext(),
@@ -4916,7 +4916,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHandlePackageDisable() {
+ public void HandlePackageDisable() {
checkHandlePackageDeleteInner((userId, packageName) -> {
disablePackage(userId, packageName);
mService.mPackageMonitor.onReceive(getTestContext(),
@@ -5048,7 +5048,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
/** Almost ame as testHandlePackageDelete, except it doesn't uninstall packages. */
- public void testHandlePackageClearData() {
+ public void HandlePackageClearData() {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
setCaller(CALLING_PACKAGE_1, USER_0);
@@ -5124,7 +5124,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
}
- public void testHandlePackageClearData_manifestRepublished() {
+ public void HandlePackageClearData_manifestRepublished() {
mRunningUsers.put(USER_10, true);
@@ -5166,7 +5166,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHandlePackageUpdate() throws Throwable {
+ public void HandlePackageUpdate() throws Throwable {
// Set up shortcuts and launchers.
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
@@ -5340,7 +5340,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Test the case where an updated app has resource IDs changed.
*/
- public void testHandlePackageUpdate_resIdChanged() throws Exception {
+ public void HandlePackageUpdate_resIdChanged() throws Exception {
final Icon icon1 = Icon.createWithResource(getTestContext(), /* res ID */ 1000);
final Icon icon2 = Icon.createWithResource(getTestContext(), /* res ID */ 1001);
@@ -5415,7 +5415,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHandlePackageUpdate_systemAppUpdate() {
+ public void HandlePackageUpdate_systemAppUpdate() {
// Package1 is a system app. Package 2 is not a system app, so it's not scanned
// in this test at all.
@@ -5521,7 +5521,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mService.getUserShortcutsLocked(USER_0).getLastAppScanOsFingerprint());
}
- public void testHandlePackageChanged() {
+ public void HandlePackageChanged() {
final ComponentName ACTIVITY1 = new ComponentName(CALLING_PACKAGE_1, "act1");
final ComponentName ACTIVITY2 = new ComponentName(CALLING_PACKAGE_1, "act2");
@@ -5651,7 +5651,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHandlePackageUpdate_activityNoLongerMain() throws Throwable {
+ public void HandlePackageUpdate_activityNoLongerMain() throws Throwable {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
makeShortcutWithActivity("s1a",
@@ -5737,7 +5737,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* - Unpinned dynamic shortcuts
* - Bitmaps
*/
- public void testBackupAndRestore() {
+ public void BackupAndRestore() {
assertFileNotExists("user-0/shortcut_dump/restore-0-start.txt");
assertFileNotExists("user-0/shortcut_dump/restore-1-payload.xml");
@@ -5758,7 +5758,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_success(/*firstRestore=*/ true);
}
- public void testBackupAndRestore_backupRestoreTwice() {
+ public void BackupAndRestore_backupRestoreTwice() {
prepareForBackupTest();
checkBackupAndRestore_success(/*firstRestore=*/ true);
@@ -5774,7 +5774,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_success(/*firstRestore=*/ false);
}
- public void testBackupAndRestore_restoreToNewVersion() {
+ public void BackupAndRestore_restoreToNewVersion() {
prepareForBackupTest();
addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 2);
@@ -5783,7 +5783,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_success(/*firstRestore=*/ true);
}
- public void testBackupAndRestore_restoreToSuperSetSignatures() {
+ public void BackupAndRestore_restoreToSuperSetSignatures() {
prepareForBackupTest();
// Change package signatures.
@@ -5980,7 +5980,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testBackupAndRestore_publisherWrongSignature() {
+ public void BackupAndRestore_publisherWrongSignature() {
prepareForBackupTest();
addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "sigx"); // different signature
@@ -5988,7 +5988,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_publisherNotRestored(ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH);
}
- public void testBackupAndRestore_publisherNoLongerBackupTarget() {
+ public void BackupAndRestore_publisherNoLongerBackupTarget() {
prepareForBackupTest();
updatePackageInfo(CALLING_PACKAGE_1,
@@ -6117,7 +6117,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testBackupAndRestore_launcherLowerVersion() {
+ public void BackupAndRestore_launcherLowerVersion() {
prepareForBackupTest();
addPackage(LAUNCHER_1, LAUNCHER_UID_1, 0); // Lower version
@@ -6126,7 +6126,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_success(/*firstRestore=*/ true);
}
- public void testBackupAndRestore_launcherWrongSignature() {
+ public void BackupAndRestore_launcherWrongSignature() {
prepareForBackupTest();
addPackage(LAUNCHER_1, LAUNCHER_UID_1, 10, "sigx"); // different signature
@@ -6134,7 +6134,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
checkBackupAndRestore_launcherNotRestored(true);
}
- public void testBackupAndRestore_launcherNoLongerBackupTarget() {
+ public void BackupAndRestore_launcherNoLongerBackupTarget() {
prepareForBackupTest();
updatePackageInfo(LAUNCHER_1,
@@ -6239,7 +6239,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testBackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
+ public void BackupAndRestore_launcherAndPackageNoLongerBackupTarget() {
prepareForBackupTest();
updatePackageInfo(CALLING_PACKAGE_1,
@@ -6337,7 +6337,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testBackupAndRestore_disabled() {
+ public void BackupAndRestore_disabled() {
prepareCrossProfileDataSet();
// Before doing backup & restore, disable s1.
@@ -6402,7 +6402,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
- public void testBackupAndRestore_manifestRePublished() {
+ public void BackupAndRestore_manifestRePublished() {
// Publish two manifest shortcuts.
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -6493,7 +6493,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
* logcat.
* - if it has allowBackup=false, we don't touch any of the existing shortcuts.
*/
- public void testBackupAndRestore_appAlreadyInstalledWhenRestored() {
+ public void BackupAndRestore_appAlreadyInstalledWhenRestored() {
// Pre-backup. Same as testBackupAndRestore_manifestRePublished().
// Publish two manifest shortcuts.
@@ -6618,7 +6618,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Test for restoring the pre-P backup format.
*/
- public void testBackupAndRestore_api27format() throws Exception {
+ public void BackupAndRestore_api27format() throws Exception {
final byte[] payload = readTestAsset("shortcut/shortcut_api27_backup.xml").getBytes();
addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 10, "22222");
@@ -6656,7 +6656,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
- public void testSaveAndLoad_crossProfile() {
+ public void SaveAndLoad_crossProfile() {
prepareCrossProfileDataSet();
dumpsysOnLogcat("Before save & load");
@@ -6859,7 +6859,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
.getPackageUserId());
}
- public void testOnApplicationActive_permission() {
+ public void OnApplicationActive_permission() {
assertExpectException(SecurityException.class, "Missing permission", () ->
mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0));
@@ -6868,7 +6868,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.onApplicationActive(CALLING_PACKAGE_1, USER_0);
}
- public void testGetShareTargets_permission() {
+ public void GetShareTargets_permission() {
addPackage(CHOOSER_ACTIVITY_PACKAGE, CHOOSER_ACTIVITY_UID, 10, "sig1");
mInjectedChooserActivity =
ComponentName.createRelative(CHOOSER_ACTIVITY_PACKAGE, ".ChooserActivity");
@@ -6887,7 +6887,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testHasShareTargets_permission() {
+ public void HasShareTargets_permission() {
assertExpectException(SecurityException.class, "Missing permission", () ->
mManager.hasShareTargets(CALLING_PACKAGE_1));
@@ -6896,7 +6896,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.hasShareTargets(CALLING_PACKAGE_1);
}
- public void testisSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
+ public void isSharingShortcut_permission() throws IntentFilter.MalformedMimeTypeException {
setCaller(LAUNCHER_1, USER_0);
IntentFilter filter_any = new IntentFilter();
@@ -6911,18 +6911,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
mManager.hasShareTargets(CALLING_PACKAGE_1);
}
- public void testDumpsys_crossProfile() {
+ public void Dumpsys_crossProfile() {
prepareCrossProfileDataSet();
dumpsysOnLogcat("test1", /* force= */ true);
}
- public void testDumpsys_withIcons() throws IOException {
- testIcons();
+ public void Dumpsys_withIcons() throws IOException {
+ Icons();
// Dump after having some icons.
dumpsysOnLogcat("test1", /* force= */ true);
}
- public void testManifestShortcut_publishOnUnlockUser() {
+ public void ManifestShortcut_publishOnUnlockUser() {
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
R.xml.shortcut_1);
@@ -7136,7 +7136,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertNull(mService.getPackageShortcutForTest(LAUNCHER_1, USER_0));
}
- public void testManifestShortcut_publishOnBroadcast() {
+ public void ManifestShortcut_publishOnBroadcast() {
// First, no packages are installed.
uninstallPackage(USER_0, CALLING_PACKAGE_1);
uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7392,7 +7392,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_missingMandatoryFields() {
+ public void ManifestShortcuts_missingMandatoryFields() {
// Start with no apps installed.
uninstallPackage(USER_0, CALLING_PACKAGE_1);
uninstallPackage(USER_0, CALLING_PACKAGE_2);
@@ -7461,7 +7461,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_intentDefinitions() {
+ public void ManifestShortcuts_intentDefinitions() {
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
R.xml.shortcut_error_4);
@@ -7603,7 +7603,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_checkAllFields() {
+ public void ManifestShortcuts_checkAllFields() {
mService.handleUnlockUser(USER_0);
// Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7708,7 +7708,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_localeChange() throws InterruptedException {
+ public void ManifestShortcuts_localeChange() throws InterruptedException {
mService.handleUnlockUser(USER_0);
// Package 1 updated, which has one valid manifest shortcut and one invalid.
@@ -7812,7 +7812,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_updateAndDisabled_notPinned() {
+ public void ManifestShortcuts_updateAndDisabled_notPinned() {
mService.handleUnlockUser(USER_0);
// First, just publish a manifest shortcut.
@@ -7852,7 +7852,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_updateAndDisabled_pinned() {
+ public void ManifestShortcuts_updateAndDisabled_pinned() {
mService.handleUnlockUser(USER_0);
// First, just publish a manifest shortcut.
@@ -7908,7 +7908,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_duplicateInSingleActivity() {
+ public void ManifestShortcuts_duplicateInSingleActivity() {
mService.handleUnlockUser(USER_0);
// The XML has two shortcuts with the same ID.
@@ -7933,7 +7933,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testManifestShortcuts_duplicateInTwoActivities() {
+ public void ManifestShortcuts_duplicateInTwoActivities() {
mService.handleUnlockUser(USER_0);
// ShortcutActivity has shortcut ms1
@@ -7985,7 +7985,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Manifest shortcuts cannot override shortcuts that were published via the APIs.
*/
- public void testManifestShortcuts_cannotOverrideNonManifest() {
+ public void ManifestShortcuts_cannotOverrideNonManifest() {
mService.handleUnlockUser(USER_0);
// Create a non-pinned dynamic shortcut and a non-dynamic pinned shortcut.
@@ -8058,7 +8058,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Make sure the APIs won't work on manifest shortcuts.
*/
- public void testManifestShortcuts_immutable() {
+ public void ManifestShortcuts_immutable() {
mService.handleUnlockUser(USER_0);
// Create a non-pinned manifest shortcut, a pinned shortcut that was originally
@@ -8151,7 +8151,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Make sure the APIs won't work on manifest shortcuts.
*/
- public void testManifestShortcuts_tooMany() {
+ public void ManifestShortcuts_tooMany() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
@@ -8170,7 +8170,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testMaxShortcutCount_set() {
+ public void MaxShortcutCount_set() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
@@ -8251,7 +8251,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testMaxShortcutCount_add() {
+ public void MaxShortcutCount_add() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
@@ -8378,7 +8378,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testMaxShortcutCount_update() {
+ public void MaxShortcutCount_update() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
@@ -8469,7 +8469,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testShortcutsPushedOutByManifest() {
+ public void ShortcutsPushedOutByManifest() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
@@ -8577,7 +8577,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testReturnedByServer() {
+ public void ReturnedByServer() {
// Package 1 updated, with manifest shortcuts.
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8623,7 +8623,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testIsForegroundDefaultLauncher_true() {
+ public void IsForegroundDefaultLauncher_true() {
final int uid = 1024;
setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8633,7 +8633,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
- public void testIsForegroundDefaultLauncher_defaultButNotForeground() {
+ public void IsForegroundDefaultLauncher_defaultButNotForeground() {
final int uid = 1024;
setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8642,7 +8642,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertFalse(mInternal.isForegroundDefaultLauncher("default", uid));
}
- public void testIsForegroundDefaultLauncher_foregroundButNotDefault() {
+ public void IsForegroundDefaultLauncher_foregroundButNotDefault() {
final int uid = 1024;
setDefaultLauncher(UserHandle.USER_SYSTEM, "default");
@@ -8651,7 +8651,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
assertFalse(mInternal.isForegroundDefaultLauncher("another", uid));
}
- public void testParseShareTargetsFromManifest() {
+ public void ParseShareTargetsFromManifest() {
// These values must exactly match the content of shortcuts_share_targets.xml resource
List<ShareTargetInfo> expectedValues = new ArrayList<>();
expectedValues.add(new ShareTargetInfo(
@@ -8703,7 +8703,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
}
- public void testShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
+ public void ShareTargetInfo_saveToXml() throws IOException, XmlPullParserException {
List<ShareTargetInfo> expectedValues = new ArrayList<>();
expectedValues.add(new ShareTargetInfo(
new ShareTargetInfo.TargetData[]{new ShareTargetInfo.TargetData(
@@ -8769,7 +8769,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
}
}
- public void testIsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
+ public void IsSharingShortcut() throws IntentFilter.MalformedMimeTypeException {
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
R.xml.shortcut_share_targets);
@@ -8819,7 +8819,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
filter_any));
}
- public void testIsSharingShortcut_PinnedAndCachedOnlyShortcuts()
+ public void IsSharingShortcut_PinnedAndCachedOnlyShortcuts()
throws IntentFilter.MalformedMimeTypeException {
addManifestShortcutResource(
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
@@ -8876,7 +8876,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
filter_any));
}
- public void testAddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+ public void AddingShortcuts_ExcludesHiddenFromLauncherShortcuts() {
final ShortcutInfo s1 = makeShortcutExcludedFromLauncher("s1");
final ShortcutInfo s2 = makeShortcutExcludedFromLauncher("s2");
final ShortcutInfo s3 = makeShortcutExcludedFromLauncher("s3");
@@ -8897,7 +8897,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testUpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
+ public void UpdateShortcuts_ExcludesHiddenFromLauncherShortcuts() {
final ShortcutInfo s1 = makeShortcut("s1");
final ShortcutInfo s2 = makeShortcut("s2");
final ShortcutInfo s3 = makeShortcut("s3");
@@ -8910,7 +8910,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
});
}
- public void testPinHiddenShortcuts_ThrowsException() {
+ public void PinHiddenShortcuts_ThrowsException() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertThrown(IllegalArgumentException.class, () -> {
mManager.requestPinShortcut(makeShortcutExcludedFromLauncher("s1"), null);
diff --git a/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
new file mode 100644
index 000000000000..a2df73b7d540
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/LazyJniRegistrarTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.utils;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+@SmallTest
+@Presubmit
+@RunWith(JUnit4.class)
+public class LazyJniRegistrarTest {
+
+ @Test
+ public void testNativeMethodsResolve() throws Exception {
+ // Basic test with a few explicit invocations to make sure methods resolve and don't throw.
+ LazyJniRegistrar.registerConsumerIrService();
+ LazyJniRegistrar.registerGameManagerService();
+ LazyJniRegistrar.registerVrManagerService();
+ }
+
+ @Test
+ public void testAllNativeRegisterMethodsResolve() throws Exception {
+ // Catch-all test to make sure public static register* methods resolve and don't throw.
+ for (Method method : LazyJniRegistrar.class.getDeclaredMethods()) {
+ if (Modifier.isPublic(method.getModifiers())
+ && Modifier.isStatic(method.getModifiers())
+ && method.getName().startsWith("register")) {
+ method.invoke(null);
+ }
+ }
+ }
+
+ // TODO(b/302724778): Remove manual JNI load
+ static {
+ System.loadLibrary("servicestestjni");
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
index f5b19a1c40ae..69b9fa23c040 100644
--- a/services/tests/servicestests/src/com/android/server/utils/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -1,5 +1,6 @@
per-file EventLoggerTest.java = file:/platform/frameworks/av:/media/janitors/media_solutions_OWNERS
per-file EventLoggerTest.java = jmtrivi@google.com
+per-file LazyJniRegistrarTest.java = file:/PERFORMANCE_OWNERS
# Bug component : 158088 = per-file AnrTimer*.java
per-file AnrTimer*.java = file:/PERFORMANCE_OWNERS
diff --git a/services/usb/OWNERS b/services/usb/OWNERS
index 2dff392d4e34..259261252032 100644
--- a/services/usb/OWNERS
+++ b/services/usb/OWNERS
@@ -1,9 +1,9 @@
-anothermark@google.com
+vmartensson@google.com
+nkapron@google.com
febinthattil@google.com
-aprasath@google.com
+shubhankarm@google.com
badhri@google.com
elaurent@google.com
albertccwang@google.com
jameswei@google.com
howardyen@google.com
-kumarashishg@google.com \ No newline at end of file
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 55a89239b864..86468b0cf821 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -200,7 +200,11 @@ public class UsbPortManager implements IBinder.DeathRecipient {
mHandler.sendEmptyMessage(MSG_SYSTEM_READY);
}
- private void updateContaminantNotification() {
+ private void updateContaminantNotificationLocked() {
+ if (mNotificationManager == null) {
+ return;
+ }
+
PortInfo currentPortInfo = null;
Resources r = mContext.getResources();
int contaminantStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED;
@@ -1171,7 +1175,7 @@ public class UsbPortManager implements IBinder.DeathRecipient {
private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) {
sendPortChangedBroadcastLocked(portInfo);
logToStatsd(portInfo, pw);
- updateContaminantNotification();
+ updateContaminantNotificationLocked();
}
private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
@@ -1433,6 +1437,9 @@ public class UsbPortManager implements IBinder.DeathRecipient {
case MSG_SYSTEM_READY: {
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ synchronized (mLock) {
+ updateContaminantNotificationLocked();
+ }
break;
}
}
diff --git a/startop/OWNERS b/startop/OWNERS
index 11d5ad0f000a..3414a7469ac2 100644
--- a/startop/OWNERS
+++ b/startop/OWNERS
@@ -1,2 +1 @@
include platform/art:/OWNERS
-keunyoung@google.com
diff --git a/telecomm/java/android/telecom/OWNERS b/telecomm/java/android/telecom/OWNERS
index 6656a01403b8..0854c5d45603 100644
--- a/telecomm/java/android/telecom/OWNERS
+++ b/telecomm/java/android/telecom/OWNERS
@@ -3,4 +3,3 @@
rgreenwalt@google.com
tgunn@google.com
breadley@google.com
-hallliu@google.com
diff --git a/tests/Codegen/OWNERS b/tests/Codegen/OWNERS
index da723b3b67da..e69de29bb2d1 100644
--- a/tests/Codegen/OWNERS
+++ b/tests/Codegen/OWNERS
@@ -1 +0,0 @@
-eugenesusla@google.com \ No newline at end of file
diff --git a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
index ce63fe89fe2e..02b639109931 100644
--- a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
+++ b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
@@ -45,7 +45,6 @@ android_test {
],
optimize: {
- proguard_compatibility: true,
proguard_flags_files: ["proguard.flags"],
},
}
diff --git a/tests/CompanionDeviceMultiDeviceTests/host/Android.bp b/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
index a0e047759dab..1fb18a6bb391 100644
--- a/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
+++ b/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
@@ -39,13 +39,4 @@ python_test_host {
device_common_data: [
":cdm_snippet_legacy",
],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
}
diff --git a/tests/EnforcePermission/OWNERS b/tests/EnforcePermission/OWNERS
index 39550a394f33..160849e5616f 100644
--- a/tests/EnforcePermission/OWNERS
+++ b/tests/EnforcePermission/OWNERS
@@ -1,3 +1,2 @@
# Bug component: 315013
tweek@google.com
-brufino@google.com
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 168141bf6e7d..1f0bd61b5c3f 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -19,9 +19,6 @@ android_test {
"src/**/*.kt",
],
asset_dirs: ["assets"],
- kotlincflags: [
- "-Werror",
- ],
platform_apis: true,
certificate: "platform",
static_libs: [
diff --git a/tests/InputScreenshotTest/robotests/Android.bp b/tests/InputScreenshotTest/robotests/Android.bp
index b2414a85c095..63a13849ee7f 100644
--- a/tests/InputScreenshotTest/robotests/Android.bp
+++ b/tests/InputScreenshotTest/robotests/Android.bp
@@ -66,7 +66,6 @@ android_robolectric_test {
"android.test.mock.stubs.system",
"truth",
],
- upstream: true,
java_resource_dirs: ["config"],
instrumentation_for: "InputRoboApp",
diff --git a/tests/SharedLibrary/lib/Android.bp b/tests/SharedLibrary/lib/Android.bp
index 0595cb1e116a..abfd0e869b45 100644
--- a/tests/SharedLibrary/lib/Android.bp
+++ b/tests/SharedLibrary/lib/Android.bp
@@ -15,6 +15,7 @@ android_app {
export_package_resources: true,
privileged: true,
optimize: {
+ keep_runtime_invisible_annotations: true,
proguard_flags_files: ["proguard.proguard"],
},
}
diff --git a/tests/SharedLibrary/lib/proguard.proguard b/tests/SharedLibrary/lib/proguard.proguard
index e5dfbe1c453d..699fbdaaadad 100644
--- a/tests/SharedLibrary/lib/proguard.proguard
+++ b/tests/SharedLibrary/lib/proguard.proguard
@@ -1,6 +1,8 @@
-keepparameternames
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
- SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
+ SourceFile,LineNumberTable,EnclosingMethod,
+ RuntimeVisibleAnnotations,RuntimeVisibleParameterAnnotations,
+ RuntimeVisibleTypeAnnotations,AnnotationDefault
-keep public class * {
public protected *;
diff --git a/tests/SoundTriggerTestApp/OWNERS b/tests/SoundTriggerTestApp/OWNERS
index a0fcfc52704d..1e41886fe716 100644
--- a/tests/SoundTriggerTestApp/OWNERS
+++ b/tests/SoundTriggerTestApp/OWNERS
@@ -1,2 +1 @@
include /media/java/android/media/soundtrigger/OWNERS
-mdooley@google.com
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index 51a300bff7ea..5ad1d1dce324 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -16,13 +16,20 @@ android_test {
name: "FrameworksVcnTests",
// For access hidden connectivity methods in tests
defaults: ["framework-connectivity-test-defaults"],
+
+ // Tethering module is released in R so this test needs to be installable
+ // on R
+ min_sdk_version: "30",
+
srcs: [
"java/**/*.java",
"java/**/*.kt",
],
platform_apis: true,
- test_suites: ["device-tests"],
- certificate: "platform",
+ test_suites: [
+ "general-tests",
+ "mts-tethering",
+ ],
static_libs: [
"android.net.vcn.flags-aconfig-java-export",
"androidx.test.rules",
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
index a8f657c89f76..6e8b4ac48816 100644
--- a/tests/vcn/AndroidManifest.xml
+++ b/tests/vcn/AndroidManifest.xml
@@ -16,8 +16,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.tests.vcn">
- <uses-sdk android:minSdkVersion="33"
- android:targetSdkVersion="33"/>
+ <!-- TODO: b/374174952 Use 36 after Android B finalization -->
+ <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="35" />
+
<application>
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
index dc521fd7bcd9..9c8362f36cb2 100644
--- a/tests/vcn/AndroidTest.xml
+++ b/tests/vcn/AndroidTest.xml
@@ -14,12 +14,20 @@
limitations under the License.
-->
<configuration description="Runs VCN Tests.">
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
<option name="test-file-name" value="FrameworksVcnTests.apk" />
</target_preparer>
<option name="test-suite-tag" value="apct" />
<option name="test-tag" value="FrameworksVcnTests" />
+
+ <!-- Run tests in MTS only if the Tethering Mainline module is installed. -->
+ <object type="module_controller"
+ class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+ <option name="mainline-module-package-name" value="com.google.android.tethering" />
+ </object>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.frameworks.tests.vcn" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
index 156961312323..0fa11ae1fe7d 100644
--- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
@@ -23,11 +23,24 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.HashSet;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
private static final Set<Integer> ALLOWED_CARRIER_IDS = new HashSet<>();
diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
index 73a0a6183cb6..fa97de0aff45 100644
--- a/tests/vcn/java/android/net/vcn/VcnConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
@@ -29,11 +29,14 @@ import static org.mockito.Mockito.mock;
import android.annotation.NonNull;
import android.content.Context;
+import android.os.Build;
import android.os.Parcel;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -42,7 +45,10 @@ import org.junit.runner.RunWith;
import java.util.Collections;
import java.util.Set;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnConfigTest {
private static final String TEST_PACKAGE_NAME = VcnConfigTest.class.getPackage().getName();
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 59dc68900100..990cc74caf6c 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -34,10 +34,13 @@ import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,7 +52,10 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConfigTest {
// Public for use in VcnGatewayConnectionTest
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 8461de6d877b..1739fbc0fa6d 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -38,16 +38,28 @@ import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager.VcnStatusCallback;
import android.net.vcn.VcnManager.VcnStatusCallbackBinder;
import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;
+import android.os.Build;
import android.os.ParcelUuid;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.net.UnknownHostException;
import java.util.UUID;
import java.util.concurrent.Executor;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnManagerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final String GATEWAY_CONNECTION_NAME = "gatewayConnectionName";
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 7bc9970629a6..52952eb3f2cc 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -30,12 +30,24 @@ import static org.junit.Assert.fail;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
+import android.os.Build;
import android.os.Parcel;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnTransportInfoTest {
private static final int SUB_ID = 1;
private static final int NETWORK_ID = 5;
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index a674425efea3..c82d2003dbf6 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -22,9 +22,21 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import android.net.NetworkCapabilities;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
+import org.junit.runner.RunWith;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnUnderlyingNetworkPolicyTest {
private static final VcnUnderlyingNetworkPolicy DEFAULT_NETWORK_POLICY =
new VcnUnderlyingNetworkPolicy(
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
index 2110d6ee7c86..22361cc71f12 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
@@ -22,14 +22,20 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.net.TelephonyNetworkSpecifier;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnUnderlyingNetworkSpecifierTest {
private static final int[] TEST_SUB_IDS = new int[] {1, 2, 3, 5};
diff --git a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
index 3ce6c8f9386d..fb040d8f9b91 100644
--- a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
@@ -30,13 +30,25 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.TelephonyNetworkSpecifier;
import android.net.wifi.WifiInfo;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Collections;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnUtilsTest {
private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
index 4063178e005d..2c072e1cbc88 100644
--- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
@@ -22,10 +22,23 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
private static final String SSID = "TestWifi";
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
index bc8e9d3200b6..01e9ac2ac3cf 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
@@ -21,11 +21,14 @@ import static android.telephony.TelephonyManager.APPTYPE_USIM;
import static org.junit.Assert.assertEquals;
import android.net.eap.EapSessionConfig;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +38,10 @@ import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class EapSessionConfigUtilsTest {
private static final byte[] EAP_ID = "test@android.net".getBytes(StandardCharsets.US_ASCII);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
index 4f3930f9b5af..821e5a6c94cb 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
@@ -25,10 +25,13 @@ import android.net.ipsec.ike.IkeIpv4AddrIdentification;
import android.net.ipsec.ike.IkeIpv6AddrIdentification;
import android.net.ipsec.ike.IkeKeyIdIdentification;
import android.net.ipsec.ike.IkeRfc822AddrIdentification;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,7 +42,10 @@ import java.net.InetAddress;
import javax.security.auth.x500.X500Principal;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeIdentificationUtilsTest {
private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeIdentification id) {
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index 9f7d2390938f..7200aee1c012 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -29,14 +29,16 @@ import android.net.InetAddresses;
import android.net.eap.EapSessionConfig;
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSessionParams;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,7 +54,10 @@ import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeSessionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
index 28cf38a2a583..957e785d70c0 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
@@ -20,17 +20,23 @@ import static org.junit.Assert.assertEquals;
import android.net.InetAddresses;
import android.net.ipsec.ike.IkeTrafficSelector;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.net.InetAddress;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class IkeTrafficSelectorUtilsTest {
private static final int START_PORT = 16;
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 664044a9e7d4..1e8f5ff2dc07 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -21,15 +21,21 @@ import static org.junit.Assert.assertEquals;
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeSaProposal;
import android.net.ipsec.ike.SaProposal;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class SaProposalUtilsTest {
/** Package private so that IkeSessionParamsUtilsTest can use it */
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
index f9dc9eb4d5ae..7d17724112ec 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
@@ -20,14 +20,20 @@ import static org.junit.Assert.assertEquals;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TunnelConnectionParamsUtilsTest {
// Public for use in VcnGatewayConnectionConfigTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
index e0b5f0ef0381..3d7348a79b8c 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
@@ -25,10 +25,13 @@ import android.net.InetAddresses;
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeTrafficSelector;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +40,10 @@ import java.net.Inet4Address;
import java.net.Inet6Address;
import java.util.concurrent.TimeUnit;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TunnelModeChildSessionParamsUtilsTest {
// Package private for use in EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
index 47638b002f37..99c7aa72146b 100644
--- a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
@@ -33,9 +33,12 @@ import static org.junit.Assert.assertTrue;
import static java.util.Collections.emptyList;
import android.net.ipsec.ike.ChildSaProposal;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -43,7 +46,10 @@ import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.List;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class MtuUtilsTest {
private void verifyUnderlyingMtuZero(boolean isIpv4) {
diff --git a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
index c84e60086b37..f7786af840ee 100644
--- a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
@@ -21,10 +21,13 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +38,10 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class PersistableBundleUtilsTest {
private static final String TEST_KEY = "testKey";
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 26a2a0636792..3cccbc419425 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -41,6 +41,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -79,6 +80,7 @@ import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkPolicy;
import android.net.vcn.util.PersistableBundleUtils;
import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
+import android.os.Build;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -93,7 +95,6 @@ import android.telephony.TelephonyManager;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.VcnManagementService.VcnStatusCallbackInfo;
@@ -101,6 +102,8 @@ import com.android.server.vcn.TelephonySubscriptionTracker;
import com.android.server.vcn.Vcn;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Rule;
@@ -117,8 +120,10 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
-/** Tests for {@link VcnManagementService}. */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnManagementServiceTest {
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -1084,6 +1089,10 @@ public class VcnManagementServiceTest {
@Test
public void testGetRestrictedTransportsFromCarrierConfig() {
+ assumeTrue(
+ "Configuring restricted transport types is only allowed on a debuggable build",
+ Build.isDebuggable());
+
final Set<Integer> restrictedTransports = new ArraySet<>();
restrictedTransports.add(TRANSPORT_CELLULAR);
restrictedTransports.add(TRANSPORT_WIFI);
@@ -1105,6 +1114,10 @@ public class VcnManagementServiceTest {
@Test
public void testGetRestrictedTransportsFromCarrierConfig_noRestrictPolicyConfigured() {
+ assumeTrue(
+ "Configuring restricted transport types is only allowed on a debuggable build",
+ Build.isDebuggable());
+
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
final PersistableBundleWrapper carrierConfig =
@@ -1119,6 +1132,10 @@ public class VcnManagementServiceTest {
@Test
public void testGetRestrictedTransportsFromCarrierConfig_noCarrierConfig() {
+ assumeTrue(
+ "Configuring restricted transport types is only allowed on a debuggable build",
+ Build.isDebuggable());
+
final Set<Integer> restrictedTransports = Collections.singleton(TRANSPORT_WIFI);
final TelephonySubscriptionSnapshot lastSnapshot =
@@ -1130,6 +1147,10 @@ public class VcnManagementServiceTest {
@Test
public void testGetRestrictedTransportsFromCarrierConfigAndVcnConfig() {
+ assumeTrue(
+ "Configuring restricted transport types is only allowed on a debuggable build",
+ Build.isDebuggable());
+
// Configure restricted transport in CarrierConfig
final Set<Integer> restrictedTransportInCarrierConfig =
Collections.singleton(TRANSPORT_WIFI);
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 77f82f0d8cf4..6276be27fbf5 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -54,6 +54,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.vcn.VcnManager;
+import android.os.Build;
import android.os.Handler;
import android.os.ParcelUuid;
import android.os.PersistableBundle;
@@ -69,9 +70,10 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.modules.utils.HandlerExecutor;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -87,8 +89,10 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class TelephonySubscriptionTrackerTest {
private static final String PACKAGE_NAME =
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 74db6a5211a0..6608dda95a4b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -70,16 +70,18 @@ import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager.VcnErrorCode;
import android.net.vcn.VcnTransportInfo;
import android.net.vcn.util.MtuUtils;
+import android.os.Build;
import android.os.PersistableBundle;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback;
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration;
import com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
import com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -94,8 +96,10 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
-/** Tests for VcnGatewayConnection.ConnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
private static final int PARALLEL_SA_COUNT = 4;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index 3c70759a2fa6..f6123d29f35a 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -26,17 +26,22 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.net.ipsec.ike.IkeSessionParams;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-/** Tests for VcnGatewayConnection.ConnectingState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectionTestBase {
private VcnIkeSession mIkeSession;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index f3eb82f46de7..7cfaf5be5111 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -30,16 +30,21 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.net.IpSecManager;
+import android.os.Build;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.DisconnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 78aefad9f8ff..9132d830c54e 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -23,15 +23,21 @@ import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.os.Build;
+
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.DisconnectedState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnectionTestBase {
@Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index 6568cdd44377..d5ef4e028709 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -27,15 +27,21 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import android.os.Build;
+
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-/** Tests for VcnGatewayConnection.RetryTimeoutState */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnectionTestBase {
private long mFirstRetryInterval;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index b9fe76a24d20..5283322682ee 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -61,15 +61,17 @@ import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.Process;
import android.telephony.SubscriptionInfo;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -87,8 +89,10 @@ import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
private static final int TEST_UID = Process.myUid() + 1;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index e9026e22b6b2..2b92428918db 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -29,12 +29,14 @@ import android.annotation.NonNull;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkRequest;
+import android.os.Build;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
@@ -44,8 +46,10 @@ import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
import java.util.List;
-/** Tests for TelephonySubscriptionTracker */
-@RunWith(AndroidJUnit4.class)
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
@SmallTest
public class VcnNetworkProviderTest {
private static final int TEST_SCORE_UNSATISFIED = 0;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index 6d269686e42f..bd4aeba761da 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -49,20 +49,26 @@ import android.net.Uri;
import android.net.vcn.VcnConfig;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
import com.android.server.VcnManagementService.VcnCallback;
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.ArrayList;
@@ -73,6 +79,11 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class VcnTest {
private static final String PKG_NAME = VcnTest.class.getPackage().getName();
private static final ParcelUuid TEST_SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
index 5db02e376f3d..53a36d3e4d6a 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
@@ -44,16 +44,22 @@ import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.net.IpSecTransformState;
+import android.os.Build;
import android.os.OutcomeReceiver;
import android.os.PowerManager;
+import androidx.test.filters.SmallTest;
+
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult;
import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@@ -63,6 +69,11 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.concurrent.TimeUnit;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
private static final String TAG = IpSecPacketLossDetectorTest.class.getSimpleName();
@@ -284,8 +295,11 @@ public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
// Stop the monitor
mIpSecPacketLossDetector.close();
+ mIpSecPacketLossDetector.close();
verifyStopped();
- verify(mIpSecTransform).close();
+
+ verify(mIpSecTransform, never()).close();
+ verify(mContext).unregisterReceiver(any());
}
@Test
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index 4f34f9f8f74c..a9c637f7c943 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -42,16 +42,28 @@ import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnManager;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.PersistableBundle;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class NetworkPriorityClassifierTest extends NetworkEvaluationTestBase {
private UnderlyingNetworkRecord mWifiNetworkRecord;
private UnderlyingNetworkRecord mCellNetworkRecord;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
index e540932d0e1f..99c508c139ec 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
@@ -58,6 +58,7 @@ import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
import android.net.vcn.VcnCellUnderlyingNetworkTemplateTest;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.net.vcn.VcnUnderlyingNetworkTemplate;
+import android.os.Build;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.telephony.CarrierConfigManager;
@@ -65,6 +66,8 @@ import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
+import androidx.test.filters.SmallTest;
+
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
import com.android.server.vcn.VcnContext;
import com.android.server.vcn.VcnNetworkProvider;
@@ -73,9 +76,12 @@ import com.android.server.vcn.routeselection.UnderlyingNetworkController.Network
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkControllerCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkListener;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@@ -89,6 +95,11 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class UnderlyingNetworkControllerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final int INITIAL_SUB_ID_1 = 1;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
index a315b0690ec5..27c1bc105bde 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
@@ -38,19 +38,30 @@ import static org.mockito.Mockito.when;
import android.net.IpSecTransform;
import android.net.vcn.VcnGatewayConnectionConfig;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.Dependencies;
import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import java.util.concurrent.TimeUnit;
+// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
+// Android B/B+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@SmallTest
public class UnderlyingNetworkEvaluatorTest extends NetworkEvaluationTestBase {
private static final int PENALTY_TIMEOUT_MIN = 10;
private static final long PENALTY_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(PENALTY_TIMEOUT_MIN);
diff --git a/tools/aosp/upload_aosp.sh b/tools/aosp/upload_aosp.sh
new file mode 100755
index 000000000000..c36057b302cb
--- /dev/null
+++ b/tools/aosp/upload_aosp.sh
@@ -0,0 +1,116 @@
+#!/bin/bash
+
+set -eu
+
+DRYRUN=false
+VERBOSE=false
+DEST_BRANCH_NAME="main"
+AOSP_URL=""
+
+function log_info() {
+ echo -e "\033[32m$1\033[m"
+}
+
+function log_warn() {
+ echo -e "\033[33m$1\033[m"
+}
+
+function log_fatal() {
+ echo -e "\033[31mERROR: $1\033[m" > /dev/stderr
+ exit 1
+}
+
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ -b|--branch)
+ DEST_BRANCH_NAME=$2
+ shift
+ shift
+ ;;
+ -v|--verbose)
+ set -x
+ VERBOSE=true
+ shift
+ ;;
+ -n|--dryrun)
+ DRYRUN=true
+ shift
+ ;;
+ -u|--url)
+ AOSP_URL=$2
+ shift
+ shift
+ ;;
+ --help)
+ echo "$0 <options>"
+ echo
+ echo "Options:"
+ echo " -b, --branch <branch> : destination AOSP branch, default is $DEST_BRANCH_NAME"
+ echo " -n, --dryrun : do not upload CL"
+ echo " -u, --url : AOSP repo URL. Default is to use existing 'aosp' remote or guess the URL."
+ echo " -v, --verbose : show verbose output"
+ echo
+ exit 0
+ ;;
+ -*|--*)
+ echo "Unknown option $i"
+ exit 1
+ ;;
+ *)
+ ;;
+ esac
+done
+
+if $VERBOSE; then
+ log_info "DRYRUN=$DRYRUN"
+ log_info "DEST_BRANCH_NAME=$DEST_BRANCH_NAME"
+fi
+
+current_branch=$(git branch --no-color --show-current)
+if [ -z "$current_branch" ]; then
+ log_fatal "use 'repo start' first"
+fi
+
+tmp_branch="aosp_$current_branch"
+
+if [ -z "$AOSP_URL" ]; then
+ AOSP_URL=$(git config --get remote.goog.url | sed 's/googleplex-//')
+fi
+
+if $VERBOSE; then
+ log_info "AOSP_URL=$AOSP_URL"
+ log_info "current_branch=$current_branch"
+ log_info "tmp_branch=$tmp_branch"
+fi
+
+log_info "Running repo hooks..."
+repo upload -c . -n -y
+
+log_info "Setting up AOSP repo..."
+existing_aosp_url=$(git config --get remote.aosp.url 2>/dev/null || true)
+if [ -z "$existing_aosp_url" ]; then
+ git remote add aosp $AOSP_URL
+elif [ "$existing_aosp_url" != "$AOSP_URL"]; then
+ log_warn "Remote 'aosp' uses $existing_aosp_url. Expected $AOSP_URL"
+fi
+
+log_info "Fetching '$DEST_BRANCH_NAME'"
+git fetch aosp $DEST_BRANCH_NAME
+
+log_info "Creating $tmp_branch and cherry-picking..."
+git branch -D $tmp_branch 2>/dev/null || true
+git checkout -b $tmp_branch
+git branch --set-upstream-to aosp/$DEST_BRANCH_NAME
+git reset --hard aosp/$DEST_BRANCH_NAME
+git cherry-pick goog/$DEST_BRANCH_NAME..$current_branch
+
+if $DRYRUN; then
+ log_info "Dryrun specified, skipping CL upload"
+else
+ log_info "Pushing to AOSP..."
+ git push aosp HEAD:refs/for/$DEST_BRANCH_NAME
+fi
+
+log_info "Cleaning up..."
+git checkout $current_branch
+git branch -D $tmp_branch \ No newline at end of file
diff --git a/tools/codegen/OWNERS b/tools/codegen/OWNERS
index c9bd260ca7ae..e69de29bb2d1 100644
--- a/tools/codegen/OWNERS
+++ b/tools/codegen/OWNERS
@@ -1 +0,0 @@
-chiuwinson@google.com
diff --git a/tools/hiddenapi/OWNERS b/tools/hiddenapi/OWNERS
index dc82aac9d41c..d1e36b953e7f 100644
--- a/tools/hiddenapi/OWNERS
+++ b/tools/hiddenapi/OWNERS
@@ -1,6 +1,5 @@
# compat-team@ for changes to hiddenapi files
mathewi@google.com
-satayev@google.com
# soong-team@ as the files these tools protect are tightly coupled with Soong
file:platform/build/soong:/OWNERS
diff --git a/tools/lint/OWNERS b/tools/lint/OWNERS
index 8e4569ee2a30..4035e19158c6 100644
--- a/tools/lint/OWNERS
+++ b/tools/lint/OWNERS
@@ -1,6 +1,5 @@
mattgilbride@google.com
azharaa@google.com
-jsharkey@google.com
per-file *CallingSettingsNonUserGetterMethods* = file:/packages/SettingsProvider/OWNERS
per-file *RegisterReceiverFlagDetector* = jacobhobbie@google.com
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index af753e5963a3..b62843ca3ff4 100644
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -19,6 +19,7 @@ package com.google.android.lint
import com.android.tools.lint.client.api.IssueRegistry
import com.android.tools.lint.client.api.Vendor
import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.multiuser.PendingIntentGetActivityDetector
import com.google.android.lint.parcel.SaferParcelChecker
import com.google.auto.service.AutoService
@@ -40,6 +41,7 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() {
PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE,
PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD,
FeatureAutomotiveDetector.ISSUE,
+ PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY,
)
override val api: Int
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt
new file mode 100644
index 000000000000..b9f22ebfa8ec
--- /dev/null
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetector.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint.multiuser
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+
+/**
+ * Detector for flagging potential multiuser issues in `PendingIntent.getActivity()` calls.
+ *
+ * This detector checks for calls to `PendingIntent#getActivity()` and
+ * reports a warning if such a call is found, suggesting that the
+ * default user 0 context might not be the right one.
+ */
+class PendingIntentGetActivityDetector : Detector(), SourceCodeScanner {
+
+ companion object {
+
+ val description = """Flags potential multiuser issue in PendingIntent.getActivity() calls."""
+
+ val EXPLANATION =
+ """
+ **Problem:**
+
+ Calling `PendingIntent.getActivity()` in the `system_server` often accidentally uses the user 0 context. Moreover, since there's no explicit user parameter in the `getActivity` method, it can be hard to tell which user the `PendingIntent` activity is associated with, making the code error-prone and less readable.
+
+ **Solution:**
+
+ Always use the user aware methods to refer the correct user context. You can achieve this by:
+
+ * **Using `PendingIntent.getActivityAsUser(...)`:** This API allows you to explicitly specify the user for the activity.
+
+ ```java
+ PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null,
+ UserHandle.of(mUserId));
+ ```
+
+ **When to Ignore this Warning:**
+
+ You can safely ignore this warning if you are certain that:
+
+ * You've confirmed that the `PendingIntent` activity you're targeting is the correct one and is **rightly** associated with the context parameter passed into the `PendingIntent.getActivity` method.
+
+ **Note:** If you are unsure about the user context, it's best to err on the side of caution and explicitly specify the user using the method specified above.
+
+ **For any further questions, please reach out to go/multiuser-help.**
+ """.trimIndent()
+
+ val ISSUE_PENDING_INTENT_GET_ACTIVITY: Issue =
+ Issue.create(
+ id = "PendingIntent#getActivity",
+ briefDescription = description,
+ explanation = EXPLANATION,
+ category = Category.SECURITY,
+ priority = 8,
+ severity = Severity.WARNING,
+ implementation =
+ Implementation(
+ PendingIntentGetActivityDetector::class.java,
+ EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES),
+ ),
+ )
+ }
+
+ override fun getApplicableMethodNames() = listOf("getActivity")
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ // Check if the method call is PendingIntent.getActivity
+ if (
+ context.evaluator.isMemberInClass(method, "android.app.PendingIntent") &&
+ method.name == "getActivity"
+ ) {
+ context.report(
+ ISSUE_PENDING_INTENT_GET_ACTIVITY,
+ node,
+ context.getLocation(node),
+ "Using `PendingIntent.getActivity(...)` might not be multiuser-aware. " +
+ "Consider using the user aware method `PendingIntent.getActivityAsUser(...)`.",
+ )
+ }
+ }
+}
diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt
new file mode 100644
index 000000000000..401055055232
--- /dev/null
+++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/multiuser/PendingIntentGetActivityDetectorTest.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.lint.multiuser
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class PendingIntentGetActivityDetectorTest : LintDetectorTest() {
+
+ override fun getDetector(): Detector = PendingIntentGetActivityDetector()
+
+ override fun getIssues(): List<Issue> =
+ listOf(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+
+ override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+ fun testPendingIntentGetActivity() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+
+ import android.app.PendingIntent;
+ import android.content.Context;
+ import android.content.Intent;
+
+ public class TestClass {
+ private Context mContext;
+
+ public void testMethod(Intent intent) {
+ PendingIntent.getActivity(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null
+ );
+ }
+ }
+ """
+ )
+ .indented(),
+ *stubs,
+ )
+ .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:11: Warning: Using PendingIntent.getActivity(...) might not be multiuser-aware. Consider using the user aware method PendingIntent.getActivityAsUser(...). [PendingIntent#getActivity]
+ PendingIntent.getActivity(
+ ^
+ 0 errors, 1 warnings
+ """
+ )
+ }
+
+ fun testPendingIntentGetActivityAsUser() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+
+ import android.app.PendingIntent;
+ import android.content.Context;
+ import android.content.Intent;
+ import android.os.UserHandle;
+
+ public class TestClass {
+ private Context mContext;
+
+ public void testMethod(Intent intent) {
+ PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ 0, /*options=*/null,
+ UserHandle.CURRENT
+ );
+ }
+ }
+ """
+ )
+ .indented(),
+ *stubs,
+ )
+ .issues(PendingIntentGetActivityDetector.ISSUE_PENDING_INTENT_GET_ACTIVITY)
+ .run()
+ .expectClean()
+ }
+
+ private val pendingIntentStub: TestFile =
+ java(
+ """
+ package android.app;
+
+ import android.content.Context;
+ import android.content.Intent;
+ import android.os.UserHandle;
+
+ public class PendingIntent {
+ public static boolean getActivity(Context context, int requestCode, Intent intent, int flags) {
+ return true;
+ }
+
+ public static boolean getActivityAsUser(
+ Context context,
+ int requestCode,
+ Intent intent,
+ int flags,
+ UserHandle userHandle
+ ) {
+ return true;
+ }
+ }
+ """
+ )
+
+ private val contxtStub: TestFile =
+ java(
+ """
+ package android.content;
+
+ import android.os.UserHandle;
+
+ public class Context {
+
+ public Context createContextAsUser(UserHandle userHandle, int flags) {
+ return this;
+ }
+ }
+
+ """
+ )
+
+ private val userHandleStub: TestFile =
+ java(
+ """
+ package android.os;
+
+ public class UserHandle {
+
+ }
+
+ """
+ )
+
+ private val intentStub: TestFile =
+ java(
+ """
+ package android.content;
+
+ public class Intent {
+
+ }
+ """
+ )
+
+ private val stubs = arrayOf(pendingIntentStub, contxtStub, userHandleStub, intentStub)
+}
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
index 8f67fa87adb5..899cd7f9ce5e 100755
--- a/tools/localedata/extract_icu_data.py
+++ b/tools/localedata/extract_icu_data.py
@@ -121,7 +121,7 @@ def pack_to_uint32(locale):
def dump_script_codes(all_scripts):
"""Dump the SCRIPT_CODES table."""
- print('const char SCRIPT_CODES[][4] = {')
+ print('constexpr const char SCRIPT_CODES[][4] = {')
for index, script in enumerate(all_scripts):
print(" /* %-2d */ {'%c', '%c', '%c', '%c'}," % (
index, script[0], script[1], script[2], script[3]))
@@ -132,15 +132,33 @@ def dump_script_codes(all_scripts):
def dump_script_data(likely_script_dict, all_scripts):
"""Dump the script data."""
print()
- print('const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({')
+ print('const char* lookupLikelyScript(uint32_t packed_lang_region) {')
+ print(' switch(packed_lang_region) {')
+
+ # partition the mapping by the script code
+ parts = {}
for locale in sorted(likely_script_dict.keys()):
script = likely_script_dict[locale]
- print(' {0x%08Xu, %2du}, // %s -> %s' % (
- pack_to_uint32(locale),
- all_scripts.index(script),
- locale.replace('_', '-'),
- script))
- print('});')
+ if script in parts:
+ l = parts[script]
+ else:
+ l = []
+ parts[script] = l
+ l.append(locale)
+
+ for script in sorted(parts.keys()):
+ locales = parts[script]
+ for locale in locales:
+ print(' case 0x%08Xu: // %s -> %s' % (
+ pack_to_uint32(locale),
+ locale.replace('_', '-'),
+ script))
+ print(' return SCRIPT_CODES[%2du];' %
+ all_scripts.index(script))
+ print(' default:')
+ print(' return nullptr;')
+ print(' }')
+ print('}')
def pack_to_uint64(locale):
@@ -152,16 +170,39 @@ def pack_to_uint64(locale):
(ord(script[2]) << 8) |
ord(script[3]))
+def pack_script_to_uint32(script):
+ """Pack a 4-letter script code into a 32-bit unsigned integer."""
+ return ((ord(script[0]) << 24) |
+ (ord(script[1]) << 16) |
+ (ord(script[2]) << 8) |
+ ord(script[3]))
+
def dump_representative_locales(representative_locales):
"""Dump the set of representative locales."""
- print()
- print('std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({')
+ print('''
+/*
+ * TODO: Consider turning the below switch statement into binary search
+ * to save the disk space when the table is larger in the future.
+ * Disassembled code shows that the jump table emitted by clang can be
+ * 4x larger than the data in disk size, but it depends on the optimization option.
+ * However, a switch statement will benefit from the future of compiler improvement.
+ */''')
+ print('bool isLocaleRepresentative(uint32_t language_and_region, const char* script) {')
+ print(' const uint64_t packed_locale =')
+ print(' ((static_cast<uint64_t>(language_and_region)) << 32u) |')
+ print(' (static_cast<uint64_t>(packScript(script)));')
+ print(' switch(packed_locale) {')
for locale in sorted(representative_locales):
- print(' 0x%08XLLU, // %s' % (
+ print(' case 0x%08XLLU: // %s' % (
pack_to_uint64(locale),
locale))
- print('});')
+
+ print(' return true;')
+ print(' default:')
+ print(' return false;')
+ print(' }')
+ print('}')
def read_and_dump_likely_data(cldr_source_dir):
@@ -182,7 +223,7 @@ def read_and_dump_likely_data(cldr_source_dir):
def escape_script_variable_name(script):
"""Escape characters, e.g. '~', in a C++ variable name"""
- return script.replace("~", "_")
+ return script.replace("~", "0")
def read_parent_data(icu_data_dir):
"""Read locale parent data from ICU data files."""
@@ -225,29 +266,52 @@ def dump_parent_data(script_organized_dict):
"""Dump information for parents of locales."""
sorted_scripts = sorted(script_organized_dict.keys())
print()
+
for script in sorted_scripts:
parent_dict = script_organized_dict[script]
- print ('const std::unordered_map<uint32_t, uint32_t> %s_PARENTS({'
- % escape_script_variable_name(script.upper()))
+
+ # partition the mapping by the parent's value
+ parts = {}
for locale in sorted(parent_dict.keys()):
parent = parent_dict[locale]
- print(' {0x%08Xu, 0x%08Xu}, // %s -> %s' % (
- pack_to_uint32(locale),
- pack_to_uint32(parent),
- locale.replace('_', '-'),
- parent.replace('_', '-')))
- print('});')
+ if parent in parts:
+ l = parts[parent]
+ else:
+ l = []
+ parts[parent] = l
+ l.append(locale)
+
+ print('static uint32_t find%sParent(uint32_t packed_lang_region) {' % escape_script_variable_name(script))
+ print(' switch(packed_lang_region) {')
+ for parent in sorted(parts.keys()):
+ locales = parts[parent]
+ for locale in locales:
+ print(' case 0x%08Xu: // %s -> %s' % (
+ pack_to_uint32(locale),
+ locale.replace('_', '-'),
+ parent.replace('_', '-')))
+
+ print(' return 0x%08Xu;' % pack_to_uint32(parent))
+
+ print(' default:')
+ print(' return 0;')
+ print(' }')
+ print('}')
print()
- print('const struct {')
- print(' const char script[4];')
- print(' const std::unordered_map<uint32_t, uint32_t>* map;')
- print('} SCRIPT_PARENTS[] = {')
+ print('uint32_t findParentLocalePackedKey(const char* script, uint32_t packed_lang_region) {')
+ print(' uint32_t packedScript = packScript(script);')
+ print(' switch (packedScript) {')
+
for script in sorted_scripts:
- print(" {{'%c', '%c', '%c', '%c'}, &%s_PARENTS}," % (
- script[0], script[1], script[2], script[3],
- escape_script_variable_name(script.upper())))
- print('};')
+ print(' case 0x%08Xu: // %s' % (pack_script_to_uint32(script), script))
+ print(' return find%sParent(packed_lang_region);' %
+ escape_script_variable_name(script))
+
+ print(' default:')
+ print(' return 0;')
+ print(' }')
+ print('}')
def dump_parent_tree_depth(parent_dict):
@@ -261,7 +325,9 @@ def dump_parent_tree_depth(parent_dict):
max_depth = max(max_depth, depth)
assert max_depth < 5 # Our algorithms assume small max_depth
print()
- print('const size_t MAX_PARENT_DEPTH = %d;' % max_depth)
+ print('uint32_t getMaxAncestorTreeDepth() {')
+ print(' return %d;' % max_depth)
+ print('}')
def read_and_dump_parent_data(icu_data_dir, likely_script_dict):
@@ -286,10 +352,33 @@ def main():
'external', 'icu', 'icu4c', 'source', 'data')
cldr_source_dir = os.path.join(source_root, 'external', 'cldr')
+ print('''/*
+ * Copyright (C) 2025 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.
+ */
+
+''')
print('// Auto-generated by %s' % sys.argv[0])
- print()
+ print('''
+#include <androidfw/LocaleDataLookup.h>
+
+namespace android {
+''')
likely_script_dict = read_and_dump_likely_data(cldr_source_dir)
read_and_dump_parent_data(icu_data_dir, likely_script_dict)
+ print()
+ print('} // namespace android')
if __name__ == '__main__':
diff --git a/tools/processors/view_inspector/OWNERS b/tools/processors/view_inspector/OWNERS
index 0473f54e57ca..38d21e141f43 100644
--- a/tools/processors/view_inspector/OWNERS
+++ b/tools/processors/view_inspector/OWNERS
@@ -1,3 +1,2 @@
alanv@google.com
-ashleyrose@google.com
-aurimas@google.com \ No newline at end of file
+aurimas@google.com
diff --git a/tools/systemfeatures/Android.bp b/tools/systemfeatures/Android.bp
index 2ebede39504e..87ea5db57db4 100644
--- a/tools/systemfeatures/Android.bp
+++ b/tools/systemfeatures/Android.bp
@@ -100,3 +100,72 @@ sh_test_host {
unit_test: true,
},
}
+
+java_library_host {
+ name: "systemfeatures-errorprone-lib",
+ srcs: [
+ ":systemfeatures-gen-metadata-srcs",
+ "errorprone/java/**/*.java",
+ ],
+ static_libs: [
+ "//external/error_prone:error_prone_core",
+ "guava",
+ "jsr305",
+ ],
+ libs: [
+ "//external/auto:auto_service_annotations",
+ ],
+ javacflags: [
+ // These exports are needed because this errorprone plugin access some private classes
+ // of the java compiler.
+ "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+ ],
+ plugins: [
+ "//external/auto:auto_service_plugin",
+ ],
+}
+
+java_plugin {
+ name: "systemfeatures-errorprone",
+ static_libs: ["systemfeatures-errorprone-lib"],
+}
+
+java_test_host {
+ name: "systemfeatures-errorprone-tests",
+ srcs: [
+ "errorprone/tests/java/**/*.java",
+ ],
+ java_resource_dirs: ["tests/src"],
+ java_resources: [
+ ":systemfeatures-errorprone-tests-data",
+ ],
+ static_libs: [
+ "compile-testing-prebuilt",
+ "error_prone_test_helpers",
+ "framework-annotations-lib",
+ "hamcrest",
+ "hamcrest-library",
+ "junit",
+ "systemfeatures-errorprone-lib",
+ "truth",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+}
+
+java_system_features_srcs {
+ name: "systemfeatures-gen-metadata-srcs",
+ full_class_name: "com.android.systemfeatures.RoSystemFeaturesMetadata",
+ metadata_only: true,
+ visibility: ["//visibility:private"],
+}
+
+filegroup {
+ name: "systemfeatures-errorprone-tests-data",
+ path: "tests/src",
+ srcs: ["tests/src/android/**/*.java"],
+ visibility: ["//visibility:private"],
+}
diff --git a/tools/systemfeatures/README.md b/tools/systemfeatures/README.md
index 5836f81e5fd3..b1fec1a34723 100644
--- a/tools/systemfeatures/README.md
+++ b/tools/systemfeatures/README.md
@@ -4,8 +4,110 @@
System features exposed from `PackageManager` are defined and aggregated as
`<feature>` xml attributes across various partitions, and are currently queried
-at runtime through the framework. This directory contains tooling that will
-support *build-time* queries of select system features, enabling optimizations
+at runtime through the framework. This directory contains tooling that supports
+*build-time* queries of select system features, enabling optimizations
like code stripping and conditionally dependencies when so configured.
-### TODO(b/203143243): Expand readme after landing codegen.
+### System Feature Codegen
+
+As not all system features can be fully specified or defined at build time (e.g.
+updatable partitisions and apex modules can change/remove such features), we
+use a conditional, build flag approach that allows a given device to customize
+the subset of build-time defined system features that are immutable and cannot
+be updated.
+
+#### Build Flags
+
+System features that can be fixed at build-time are declared in a common
+location, `build/release/flag_declarations/`. These have the form
+`RELEASE_SYSTEM_FEATURE_${X}`, where `${X}` corresponds to a feature defined in
+`PackageManager`, e.g., `TELEVISION` or `WATCH`.
+
+Build flag values can then be defined per device (or form factor), where such
+values either indicate the existence/version of the system feature, or that the
+feature is unavailable, e.g., for TV, we could define these build flag values:
+```
+name: "RELEASE_SYSTEM_FEATURE_TELEVISION"
+value: {
+ string_value: "0" # Feature version = 0
+}
+```
+```
+name: "RELEASE_SYSTEM_FEATURE_WATCH"
+value: {
+ string_value: "UNAVAILABLE"
+}
+```
+
+See also [SystemFeaturesGenerator](src/com/android/systemfeatures/SystemFeaturesGenerator.kt)
+for more details.
+
+#### Runtime Queries
+
+Each declared build flag system feature is routed into codegen, generating a
+getter API in the internal class, `com.android.internal.pm.RoSystemFeatures`:
+```
+class RoSystemFeatures {
+ ...
+ public static boolean hasFeatureX(Context context);
+ ...
+}
+```
+By default, these queries simply fall back to the usual
+`PackageManager.hasSystemFeature(...)` runtime queries. However, if a device
+defines these features via build flags, the generated code will add annotations
+indicating fixed value for this query, and adjust the generated code to return
+the value directly. This in turn enables build-time stripping and optimization.
+
+> **_NOTE:_** Any build-time defined system features will also be implicitly
+used to accelerate calls to `PackageManager.hasSystemFeature(...)` for the
+feature, avoiding binder calls when possible.
+
+#### Lint
+
+A new `ErrorProne` rule is introduced to assist with migration and maintenance
+of codegen APIs for build-time defined system features. This is defined in the
+`systemfeatures-errorprone` build rule, which can be added to any Java target's
+`plugins` list.
+
+// TODO(b/203143243): Add plugin to key system targets after initial migration.
+
+1) Add the plugin dependency to a given `${TARGET}`:
+```
+java_library {
+ name: "${TARGET}",
+ plugins: ["systemfeatures-errorprone"],
+}
+```
+2) Run locally:
+```
+RUN_ERROR_PRONE=true m ${TARGET}
+```
+3) (Optional) Update the target rule to generate in-place patch files:
+```
+java_library {
+ name: "${TARGET}",
+ plugins: ["systemfeatures-errorprone"],
+ // DO NOT SUBMIT: GENERATE IN-PLACE PATCH FILES
+ errorprone: {
+ javacflags: [
+ "-XepPatchChecks:RoSystemFeaturesChecker",
+ "-XepPatchLocation:IN_PLACE",
+ ],
+ }
+ ...
+}
+```
+```
+RUN_ERROR_PRONE=true m ${TARGET}
+```
+
+See also [RoSystemFeaturesChecker](errorprone/java/com/android/systemfeatures/errorprone/RoSystemFeaturesChecker.java)
+for more details.
+
+> **_NOTE:_** Not all system feature queries or targets need or should be
+migrated. Only system features that are explicitly declared with build flags,
+and only targets that are built with the platform (i.e., not updatable), are
+candidates for this linting and migration, e.g., SystemUI, System Server, etc...
+
+// TODO(b/203143243): Wrap the in-place lint updates with a simple script for convenience.
diff --git a/tools/systemfeatures/errorprone/java/com/android/systemfeatures/errorprone/RoSystemFeaturesChecker.java b/tools/systemfeatures/errorprone/java/com/android/systemfeatures/errorprone/RoSystemFeaturesChecker.java
new file mode 100644
index 000000000000..78123774205a
--- /dev/null
+++ b/tools/systemfeatures/errorprone/java/com/android/systemfeatures/errorprone/RoSystemFeaturesChecker.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemfeatures.errorprone;
+
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+
+import com.android.systemfeatures.RoSystemFeaturesMetadata;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.fixes.SuggestedFix;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.matchers.Matcher;
+import com.google.errorprone.matchers.Matchers;
+import com.google.errorprone.util.ASTHelpers;
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodInvocationTree;
+import com.sun.tools.javac.code.Symbol;
+
+@AutoService(BugChecker.class)
+@BugPattern(
+ name = "RoSystemFeaturesChecker",
+ summary = "Use RoSystemFeature instead of PackageManager.hasSystemFeature",
+ explanation =
+ "Directly invoking `PackageManager.hasSystemFeature` is less efficient than using"
+ + " the `RoSystemFeatures` helper class. This check flags invocations like"
+ + " `context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FOO)`"
+ + " and suggests replacing them with"
+ + " `com.android.internal.pm.RoSystemFeatures.hasFeatureFoo(context)`.",
+ severity = WARNING)
+public class RoSystemFeaturesChecker extends BugChecker
+ implements BugChecker.MethodInvocationTreeMatcher {
+
+ private static final String PACKAGE_MANAGER_CLASS = "android.content.pm.PackageManager";
+ private static final String CONTEXT_CLASS = "android.content.Context";
+ private static final String RO_SYSTEM_FEATURE_SIMPLE_CLASS = "RoSystemFeatures";
+ private static final String RO_SYSTEM_FEATURE_CLASS =
+ "com.android.internal.pm." + RO_SYSTEM_FEATURE_SIMPLE_CLASS;
+ private static final String GET_PACKAGE_MANAGER_METHOD = "getPackageManager";
+ private static final String HAS_SYSTEM_FEATURE_METHOD = "hasSystemFeature";
+ private static final String FEATURE_PREFIX = "FEATURE_";
+
+ private static final Matcher<ExpressionTree> HAS_SYSTEM_FEATURE_MATCHER =
+ Matchers.instanceMethod()
+ .onDescendantOf(PACKAGE_MANAGER_CLASS)
+ .named(HAS_SYSTEM_FEATURE_METHOD)
+ .withParameters(String.class.getName());
+
+ private static final Matcher<ExpressionTree> GET_PACKAGE_MANAGER_MATCHER =
+ Matchers.instanceMethod()
+ .onDescendantOf(CONTEXT_CLASS)
+ .named(GET_PACKAGE_MANAGER_METHOD);
+
+ @Override
+ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
+ if (!HAS_SYSTEM_FEATURE_MATCHER.matches(tree, state)) {
+ return Description.NO_MATCH;
+ }
+
+ // Check if the PackageManager was obtained from a Context instance.
+ ExpressionTree packageManager = ASTHelpers.getReceiver(tree);
+ if (!GET_PACKAGE_MANAGER_MATCHER.matches(packageManager, state)) {
+ return Description.NO_MATCH;
+ }
+
+ // Get the feature argument and check if it's a PackageManager.FEATURE_X constant.
+ ExpressionTree feature = tree.getArguments().isEmpty() ? null : tree.getArguments().get(0);
+ Symbol featureSymbol = ASTHelpers.getSymbol(feature);
+ if (featureSymbol == null
+ || !featureSymbol.isStatic()
+ || !featureSymbol.getSimpleName().toString().startsWith(FEATURE_PREFIX)
+ || ASTHelpers.enclosingClass(featureSymbol) == null
+ || !ASTHelpers.enclosingClass(featureSymbol)
+ .getQualifiedName()
+ .contentEquals(PACKAGE_MANAGER_CLASS)) {
+ return Description.NO_MATCH;
+ }
+
+ // Check if the feature argument is part of the RoSystemFeatures API surface.
+ String featureName = featureSymbol.getSimpleName().toString();
+ String methodName = RoSystemFeaturesMetadata.getMethodNameForFeatureName(featureName);
+ if (methodName == null) {
+ return Description.NO_MATCH;
+ }
+
+ // Generate the appropriate fix.
+ String replacement =
+ String.format(
+ "%s.%s(%s)",
+ RO_SYSTEM_FEATURE_SIMPLE_CLASS,
+ methodName,
+ state.getSourceForNode(ASTHelpers.getReceiver(packageManager)));
+ // Note that ErrorProne doesn't offer a seamless way of removing the `PackageManager` import
+ // if unused after fix application, so for now we only offer best effort import suggestions.
+ SuggestedFix fix =
+ SuggestedFix.builder()
+ .replace(tree, replacement)
+ .addImport(RO_SYSTEM_FEATURE_CLASS)
+ .removeStaticImport(PACKAGE_MANAGER_CLASS + "." + featureName)
+ .build();
+ return describeMatch(tree, fix);
+ }
+}
diff --git a/tools/systemfeatures/errorprone/tests/java/com/android/systemfeatures/errorprone/RoSystemFeaturesCheckerTest.java b/tools/systemfeatures/errorprone/tests/java/com/android/systemfeatures/errorprone/RoSystemFeaturesCheckerTest.java
new file mode 100644
index 000000000000..c517b2495ee4
--- /dev/null
+++ b/tools/systemfeatures/errorprone/tests/java/com/android/systemfeatures/errorprone/RoSystemFeaturesCheckerTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemfeatures.errorprone;
+
+import com.google.errorprone.BugCheckerRefactoringTestHelper;
+import com.google.errorprone.CompilationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RoSystemFeaturesCheckerTest {
+ private BugCheckerRefactoringTestHelper mRefactoringHelper;
+ private CompilationTestHelper mCompilationHelper;
+
+ @Before
+ public void setUp() {
+ mCompilationHelper =
+ CompilationTestHelper.newInstance(RoSystemFeaturesChecker.class, getClass());
+ mRefactoringHelper =
+ BugCheckerRefactoringTestHelper.newInstance(
+ RoSystemFeaturesChecker.class, getClass());
+ }
+
+ @Test
+ public void testNoDiagnostic() {
+ mCompilationHelper
+ .addSourceFile("/android/content/Context.java")
+ .addSourceFile("/android/content/pm/PackageManager.java")
+ .addSourceLines("Example.java",
+ """
+ import android.content.Context;
+ import android.content.pm.PackageManager;
+ public class Example {
+ void test(Context context) {
+ boolean hasCustomFeature = context.getPackageManager()
+ .hasSystemFeature("my.custom.feature");
+ boolean hasNonAnnotatedFeature = context.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_NOT_ANNOTATED);
+ boolean hasNonRoApiFeature = context.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_NOT_IN_RO_FEATURE_API);
+ }
+ }
+ """)
+ .doTest();
+ }
+
+ @Test
+ public void testDiagnostic() {
+ mCompilationHelper
+ .addSourceFile("/android/content/Context.java")
+ .addSourceFile("/android/content/pm/PackageManager.java")
+ .addSourceLines("Example.java",
+ """
+ import android.content.Context;
+ import android.content.pm.PackageManager;
+ public class Example {
+ void test(Context context) {
+ boolean hasFeature = context.getPackageManager()
+ // BUG: Diagnostic contains:
+ .hasSystemFeature(PackageManager.FEATURE_PC);
+ }
+ }
+ """)
+ .doTest();
+ }
+
+ @Test
+ public void testFix() {
+ mRefactoringHelper
+ .addInputLines("Example.java",
+ """
+ import static android.content.pm.PackageManager.FEATURE_WATCH;
+
+ import android.content.Context;
+ import android.content.pm.PackageManager;
+ public class Example {
+ static class CustomContext extends Context {};
+ private CustomContext mContext;
+ void test(Context context) {
+ boolean hasPc = mContext.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_PC);
+ boolean hasWatch = context.getPackageManager()
+ .hasSystemFeature(FEATURE_WATCH);
+ }
+ }
+ """)
+ .addOutputLines("Example.java",
+ """
+ import android.content.Context;
+ import android.content.pm.PackageManager;
+ import com.android.internal.pm.RoSystemFeatures;
+ public class Example {
+ static class CustomContext extends Context {};
+ private CustomContext mContext;
+ void test(Context context) {
+ boolean hasPc = RoSystemFeatures.hasFeaturePc(mContext);
+ boolean hasWatch = RoSystemFeatures.hasFeatureWatch(context);
+ }
+ }
+ """)
+ // Don't try compiling the output, as it requires pulling in the full set of code
+ // dependencies.
+ .allowBreakingChanges()
+ .doTest();
+ }
+}
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
index f260e2733843..22d364ec3212 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
@@ -53,11 +53,20 @@ import javax.lang.model.element.Modifier
* public static ArrayMap<String, FeatureInfo> getReadOnlySystemEnabledFeatures();
* }
* </pre>
+ *
+ * <p> If `--metadata-only=true` is set, the resulting class would simply be:
+ * <pre>
+ * package com.foo;
+ * public final class RoSystemFeatures {
+ * public static String getMethodNameForFeatureName(String featureName);
+ * }
+ * </pre>
*/
object SystemFeaturesGenerator {
private const val FEATURE_ARG = "--feature="
private const val FEATURE_APIS_ARG = "--feature-apis="
private const val READONLY_ARG = "--readonly="
+ private const val METADATA_ONLY_ARG = "--metadata-only="
private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
private val CONTEXT_CLASS = ClassName.get("android.content", "Context")
private val FEATUREINFO_CLASS = ClassName.get("android.content.pm", "FeatureInfo")
@@ -84,6 +93,8 @@ object SystemFeaturesGenerator {
println(" runtime passthrough API will be generated, regardless")
println(" of the `--readonly` flag. This allows decoupling the")
println(" API surface from variations in device feature sets.")
+ println(" --metadata-only=true|false Whether to simply output metadata about the")
+ println(" generated API surface.")
}
/** Main entrypoint for build-time system feature codegen. */
@@ -106,6 +117,7 @@ object SystemFeaturesGenerator {
}
var readonly = false
+ var metadataOnly = false
var outputClassName: ClassName? = null
val featureArgs = mutableListOf<FeatureInfo>()
// We could just as easily hardcode this list, as the static API surface should change
@@ -115,6 +127,8 @@ object SystemFeaturesGenerator {
when {
arg.startsWith(READONLY_ARG) ->
readonly = arg.substring(READONLY_ARG.length).toBoolean()
+ arg.startsWith(METADATA_ONLY_ARG) ->
+ metadataOnly = arg.substring(METADATA_ONLY_ARG.length).toBoolean()
arg.startsWith(FEATURE_ARG) -> {
featureArgs.add(parseFeatureArg(arg))
}
@@ -155,9 +169,13 @@ object SystemFeaturesGenerator {
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addJavadoc("@hide")
- addFeatureMethodsToClass(classBuilder, features.values)
- addMaybeFeatureMethodToClass(classBuilder, features.values)
- addGetFeaturesMethodToClass(classBuilder, features.values)
+ if (metadataOnly) {
+ addMetadataMethodToClass(classBuilder, features.values)
+ } else {
+ addFeatureMethodsToClass(classBuilder, features.values)
+ addMaybeFeatureMethodToClass(classBuilder, features.values)
+ addGetFeaturesMethodToClass(classBuilder, features.values)
+ }
// TODO(b/203143243): Add validation of build vs runtime values to ensure consistency.
JavaFile.builder(outputClassName.packageName(), classBuilder.build())
@@ -214,11 +232,8 @@ object SystemFeaturesGenerator {
features: Collection<FeatureInfo>,
) {
for (feature in features) {
- // Turn "FEATURE_FOO" into "hasFeatureFoo".
- val methodName =
- "has" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, feature.name)
val methodBuilder =
- MethodSpec.methodBuilder(methodName)
+ MethodSpec.methodBuilder(feature.methodName)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc("Check for ${feature.name}.\n\n@hide")
.returns(Boolean::class.java)
@@ -248,7 +263,7 @@ object SystemFeaturesGenerator {
.returns(Boolean::class.java)
.addParameter(CONTEXT_CLASS, "context")
.addParameter(String::class.java, "featureName")
- .addStatement("return context.getPackageManager().hasSystemFeature(featureName, 0)")
+ .addStatement("return context.getPackageManager().hasSystemFeature(featureName)")
.build()
)
}
@@ -341,5 +356,32 @@ object SystemFeaturesGenerator {
builder.addMethod(methodBuilder.build())
}
- private data class FeatureInfo(val name: String, val version: Int?, val readonly: Boolean)
+ /*
+ * Adds a metadata helper method that maps FEATURE_FOO names to their generated hasFeatureFoo()
+ * API counterpart, if defined.
+ */
+ private fun addMetadataMethodToClass(
+ builder: TypeSpec.Builder,
+ features: Collection<FeatureInfo>,
+ ) {
+ val methodBuilder =
+ MethodSpec.methodBuilder("getMethodNameForFeatureName")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addJavadoc("@return \"hasFeatureFoo\" if FEATURE_FOO is in the API, else null")
+ .returns(String::class.java)
+ .addParameter(String::class.java, "featureVarName")
+
+ methodBuilder.beginControlFlow("switch (featureVarName)")
+ for (feature in features) {
+ methodBuilder.addStatement("case \$S: return \$S", feature.name, feature.methodName)
+ }
+ methodBuilder.addStatement("default: return null").endControlFlow()
+
+ builder.addMethod(methodBuilder.build())
+ }
+
+ private data class FeatureInfo(val name: String, val version: Int?, val readonly: Boolean) {
+ // Turn "FEATURE_FOO" into "hasFeatureFoo".
+ val methodName get() = "has" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name)
+ }
}
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
index 4a6d4b1f49ef..c51c6d661314 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesMetadataProcessor.kt
@@ -18,9 +18,11 @@ package com.android.systemfeatures
import android.annotation.SdkConstant
import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.CodeBlock
import com.squareup.javapoet.FieldSpec
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.ParameterizedTypeName
import com.squareup.javapoet.TypeSpec
import java.io.IOException
import javax.annotation.processing.AbstractProcessor
@@ -101,8 +103,8 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
TypeSpec.classBuilder("SystemFeaturesMetadata")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addJavadoc("@hide")
- .addField(buildFeatureCount(featureVarNames))
- .addMethod(buildFeatureIndexLookup(featureVarNames))
+ .addFeatureCount(featureVarNames)
+ .addFeatureIndexLookup(featureVarNames)
.build()
try {
@@ -120,19 +122,55 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
return true
}
- private fun buildFeatureCount(featureVarNames: Collection<String>): FieldSpec {
- return FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
- .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
- .addJavadoc(
- "# of {@link android.annotation.SdkConstant}` features defined in PackageManager."
- )
- .addJavadoc("\n\n@hide")
- .initializer("\$L", featureVarNames.size)
- .build()
+ private fun TypeSpec.Builder.addFeatureCount(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ return addField(
+ FieldSpec.builder(Int::class.java, "SDK_FEATURE_COUNT")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
+ .addJavadoc(
+ "# of {@link android.annotation.SdkConstant}` features in PackageManager."
+ )
+ .addJavadoc("\n\n@hide")
+ .initializer("\$L", featureVarNames.size)
+ .build()
+ )
}
- private fun buildFeatureIndexLookup(featureVarNames: Collection<String>): MethodSpec {
- val methodBuilder =
+ private fun TypeSpec.Builder.addFeatureIndexLookup(
+ featureVarNames: Collection<String>
+ ): TypeSpec.Builder {
+ // NOTE: This was initially implemented in terms of a single, long switch() statement.
+ // However, this resulted in:
+ // 1) relatively large compiled code size for the lookup method (~20KB)
+ // 2) worse runtime lookup performance than a simple ArraySet
+ // The ArraySet approach adds just ~1KB to the code/image and is 2x faster at runtime.
+
+ // Provide the initial capacity of the ArraySet for efficiency.
+ addField(
+ FieldSpec.builder(
+ ParameterizedTypeName.get(ARRAYSET_CLASS, ClassName.get(String::class.java)),
+ "sFeatures",
+ )
+ .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
+ .initializer("new ArraySet<>(\$L)", featureVarNames.size)
+ .build()
+ )
+
+ // Use a temp array + Collections.addAll() to minimizes the generated code size.
+ addStaticBlock(
+ CodeBlock.builder()
+ .add("final \$T[] features = {\n", String::class.java)
+ .indent()
+ .apply { featureVarNames.forEach { add("\$T.\$N,\n", PACKAGEMANAGER_CLASS, it) } }
+ .unindent()
+ .addStatement("}")
+ .addStatement("\$T.addAll(sFeatures, features)", COLLECTIONS_CLASS)
+ .build()
+ )
+
+ // Use ArraySet.indexOf to provide the implicit feature index mapping.
+ return addMethod(
MethodSpec.methodBuilder("maybeGetSdkFeatureIndex")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addJavadoc("@return an index in [0, SDK_FEATURE_COUNT) for features defined ")
@@ -140,21 +178,15 @@ class SystemFeaturesMetadataProcessor : AbstractProcessor() {
.addJavadoc("\n\n@hide")
.returns(Int::class.java)
.addParameter(String::class.java, "featureName")
- methodBuilder.beginControlFlow("switch (featureName)")
- featureVarNames.forEachIndexed { index, featureVarName ->
- methodBuilder
- .addCode("case \$T.\$N: ", PACKAGEMANAGER_CLASS, featureVarName)
- .addStatement("return \$L", index)
- }
- methodBuilder
- .addCode("default: ")
- .addStatement("return -1")
- .endControlFlow()
- return methodBuilder.build()
+ .addStatement("return sFeatures.indexOf(featureName)")
+ .build()
+ )
}
companion object {
private val SDK_CONSTANT_ANNOTATION_NAME = SdkConstant::class.qualifiedName
private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
+ private val ARRAYSET_CLASS = ClassName.get("android.util", "ArraySet")
+ private val COLLECTIONS_CLASS = ClassName.get("java.util", "Collections")
}
}
diff --git a/tools/systemfeatures/tests/golden/RoFeatures.java.gen b/tools/systemfeatures/tests/golden/RoFeatures.java.gen
index ee97b26159de..730dacbbf995 100644
--- a/tools/systemfeatures/tests/golden/RoFeatures.java.gen
+++ b/tools/systemfeatures/tests/golden/RoFeatures.java.gen
@@ -70,7 +70,7 @@ public final class RoFeatures {
}
private static boolean hasFeatureFallback(Context context, String featureName) {
- return context.getPackageManager().hasSystemFeature(featureName, 0);
+ return context.getPackageManager().hasSystemFeature(featureName);
}
/**
diff --git a/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen b/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen
index 40c7db7ff1df..fe268c70708e 100644
--- a/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen
+++ b/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen
@@ -25,7 +25,7 @@ public final class RoNoFeatures {
}
private static boolean hasFeatureFallback(Context context, String featureName) {
- return context.getPackageManager().hasSystemFeature(featureName, 0);
+ return context.getPackageManager().hasSystemFeature(featureName);
}
/**
diff --git a/tools/systemfeatures/tests/golden/RwFeatures.java.gen b/tools/systemfeatures/tests/golden/RwFeatures.java.gen
index 7bf89614b92d..bcf978de3c1f 100644
--- a/tools/systemfeatures/tests/golden/RwFeatures.java.gen
+++ b/tools/systemfeatures/tests/golden/RwFeatures.java.gen
@@ -55,7 +55,7 @@ public final class RwFeatures {
}
private static boolean hasFeatureFallback(Context context, String featureName) {
- return context.getPackageManager().hasSystemFeature(featureName, 0);
+ return context.getPackageManager().hasSystemFeature(featureName);
}
/**
diff --git a/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen b/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen
index eb7ec63f1d7d..7bad5a2bae2a 100644
--- a/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen
+++ b/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen
@@ -14,7 +14,7 @@ import android.util.ArrayMap;
*/
public final class RwNoFeatures {
private static boolean hasFeatureFallback(Context context, String featureName) {
- return context.getPackageManager().hasSystemFeature(featureName, 0);
+ return context.getPackageManager().hasSystemFeature(featureName);
}
/**
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java
index ed3f5c94ba79..491b55e7992c 100644
--- a/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java
+++ b/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java
@@ -76,28 +76,28 @@ public class SystemFeaturesGeneratorTest {
// Also ensure we fall back to the PackageManager for feature APIs without an accompanying
// versioned feature definition.
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(true);
assertThat(RwFeatures.hasFeatureWatch(mContext)).isTrue();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(false);
assertThat(RwFeatures.hasFeatureWatch(mContext)).isFalse();
}
@Test
public void testReadonlyDisabledWithDefinedFeatures() {
// Always fall back to the PackageManager for defined, explicit features queries.
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(true);
assertThat(RwFeatures.hasFeatureWatch(mContext)).isTrue();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)).thenReturn(false);
assertThat(RwFeatures.hasFeatureWatch(mContext)).isFalse();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI, 0)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
assertThat(RwFeatures.hasFeatureWifi(mContext)).isTrue();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN)).thenReturn(false);
assertThat(RwFeatures.hasFeatureVulkan(mContext)).isFalse();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO)).thenReturn(false);
assertThat(RwFeatures.hasFeatureAuto(mContext)).isFalse();
// For defined and undefined features, conditional queries should report null (unknown).
@@ -139,9 +139,9 @@ public class SystemFeaturesGeneratorTest {
assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 100)).isFalse();
// VERSION=
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO)).thenReturn(false);
assertThat(RoFeatures.hasFeatureAuto(mContext)).isFalse();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO, 0)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO)).thenReturn(true);
assertThat(RoFeatures.hasFeatureAuto(mContext)).isTrue();
assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, -1)).isNull();
assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 0)).isNull();
@@ -149,9 +149,9 @@ public class SystemFeaturesGeneratorTest {
// For feature APIs without an associated feature definition, conditional queries should
// report null, and explicit queries should report runtime-defined versions.
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC, 0)).thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC)).thenReturn(true);
assertThat(RoFeatures.hasFeaturePc(mContext)).isTrue();
- when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC, 0)).thenReturn(false);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_PC)).thenReturn(false);
assertThat(RoFeatures.hasFeaturePc(mContext)).isFalse();
assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_PC, -1)).isNull();
assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_PC, 0)).isNull();
diff --git a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
index 74ce6daaffc4..560454b65b7e 100644
--- a/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
+++ b/tools/systemfeatures/tests/src/SystemFeaturesMetadataProcessorTest.java
@@ -36,8 +36,8 @@ public class SystemFeaturesMetadataProcessorTest {
@Test
public void testSdkFeatureCount() {
// See the fake PackageManager definition in this directory.
- // It defines 5 annotated features, and any/all other constants should be ignored.
- assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(5);
+ // It defines 6 annotated features, and any/all other constants should be ignored.
+ assertThat(SystemFeaturesMetadata.SDK_FEATURE_COUNT).isEqualTo(6);
}
@Test
diff --git a/tools/systemfeatures/tests/src/Context.java b/tools/systemfeatures/tests/src/android/content/Context.java
index 630bc0771a01..630bc0771a01 100644
--- a/tools/systemfeatures/tests/src/Context.java
+++ b/tools/systemfeatures/tests/src/android/content/Context.java
diff --git a/tools/systemfeatures/tests/src/FeatureInfo.java b/tools/systemfeatures/tests/src/android/content/pm/FeatureInfo.java
index 9d57edc64ca5..9d57edc64ca5 100644
--- a/tools/systemfeatures/tests/src/FeatureInfo.java
+++ b/tools/systemfeatures/tests/src/android/content/pm/FeatureInfo.java
diff --git a/tools/systemfeatures/tests/src/PackageManager.java b/tools/systemfeatures/tests/src/android/content/pm/PackageManager.java
index 839a9377476d..4a9edd61b55b 100644
--- a/tools/systemfeatures/tests/src/PackageManager.java
+++ b/tools/systemfeatures/tests/src/android/content/pm/PackageManager.java
@@ -36,6 +36,9 @@ public class PackageManager {
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_WIFI = "wifi";
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_NOT_IN_RO_FEATURE_API = "not_in_ro_feature_api";
+
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String FEATURE_INTENT_CATEGORY = "intent_category_with_feature_name_prefix";
@@ -47,4 +50,9 @@ public class PackageManager {
public boolean hasSystemFeature(String featureName, int version) {
return false;
}
+
+ /** @hide */
+ public boolean hasSystemFeature(String featureName) {
+ return hasSystemFeature(featureName, 0);
+ }
}
diff --git a/tools/systemfeatures/tests/src/ArrayMap.java b/tools/systemfeatures/tests/src/android/util/ArrayMap.java
index a5ed9b088896..a5ed9b088896 100644
--- a/tools/systemfeatures/tests/src/ArrayMap.java
+++ b/tools/systemfeatures/tests/src/android/util/ArrayMap.java
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/tools/systemfeatures/tests/src/android/util/ArraySet.java
index f72f74e8b3b9..0eb8f298bd89 100644
--- a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
+++ b/tools/systemfeatures/tests/src/android/util/ArraySet.java
@@ -14,7 +14,21 @@
* limitations under the License.
*/
-package android.nfc;
+package android.util;
-parcelable T4tNdefNfceeCcFileInfo;
+import java.util.ArrayList;
+/** Stub for testing, we extend ArrayList to get indexOf() for free. */
+public final class ArraySet<K> extends ArrayList<K> {
+ public ArraySet(int capacity) {
+ super(capacity);
+ }
+
+ @Override
+ public boolean add(K k) {
+ if (!contains(k)) {
+ return super.add(k);
+ }
+ return false;
+ }
+}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS b/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
index 2a4acc111257..abb9aa4c05a2 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/OWNERS
@@ -1,4 +1,3 @@
# Bug component: 1216021
asapperstein@google.com
-etancohen@google.com