aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 07:16:58 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 07:16:58 +0000
commit92ffffdace4c216616a8d7338996e1d4406fd8fd (patch)
tree3d838dc163ed48dadb670aa912e7bb8d85c3f8a0
parente56041544737f689a3f700577e88e532a19027e4 (diff)
parentbdecd4ef6264998d9ebf8c7aaabbf05f0438c28e (diff)
downloadlayoutlib-92ffffdace4c216616a8d7338996e1d4406fd8fd.tar.gz
Snap for 10453938 from bdecd4ef6264998d9ebf8c7aaabbf05f0438c28e to mainline-odp-releaseaml_odp_341610000
Change-Id: I44ebcaa359e5eaf919beaa7bb8025c415fb192ba
-rw-r--r--.gitignore1
-rw-r--r--.idea/libraries/jsoup.xml9
-rw-r--r--.idea/libraries/kotlin_stdlib.xml9
-rw-r--r--.idea/libraries/kxml.xml11
-rw-r--r--.idea/libraries/libprotobuf_java_lite.xml11
-rw-r--r--.idea/libraries/ninepatch_prebuilt.xml11
-rw-r--r--.idea/libraries/sdk_common.xml11
-rw-r--r--.idea/libraries/tools_common_prebuilt.xml14
-rw-r--r--.idea/libraries/trove4j.xml9
-rw-r--r--.idea/misc.xml2
-rw-r--r--.idea/modules.xml7
-rw-r--r--.idea/runConfigurations/All_in_bridge.xml5
-rw-r--r--.idea/runConfigurations/All_in_create.xml2
-rw-r--r--.idea/runConfigurations/Bridge_quick.xml5
-rw-r--r--.idea/runConfigurations/Create.xml2
-rw-r--r--Android.bp14
-rw-r--r--bridge/Android.bp33
-rw-r--r--bridge/bridge.iml84
-rw-r--r--bridge/bridge_client/Android.bp51
-rw-r--r--bridge/bridge_client/bridge_client.iml (renamed from remote/common/remote common.iml)22
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/FrameworkResources.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdResourceParser.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/IdResourceParser.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFile.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFolder.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceItem.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceItem.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceRepository.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ScanningContext.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ScanningContext.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java)0
-rw-r--r--bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java (renamed from bridge/tests/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/BridgeClient.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java)386
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/RenderResult.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutlibBridgeClientCallback.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java)45
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java)0
-rw-r--r--bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java (renamed from bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java)0
-rw-r--r--bridge/src/android/app/ActivityManager_Delegate.java61
-rw-r--r--bridge/src/android/app/Application_Delegate.java (renamed from remote/common/src/com/android/layout/remote/util/SerializableImage.java)19
-rw-r--r--bridge/src/android/content/res/BridgeTypedArray.java2
-rw-r--r--bridge/src/android/content/res/Resources_Delegate.java23
-rw-r--r--bridge/src/android/graphics/ImageDecoder_Delegate.java7
-rw-r--r--bridge/src/android/graphics/Typeface_Builder_Delegate.java42
-rw-r--r--bridge/src/android/graphics/Typeface_Delegate.java6
-rw-r--r--bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java59
-rw-r--r--bridge/src/android/graphics/fonts/Font_Builder_Delegate.java5
-rw-r--r--bridge/src/android/graphics/fonts/SystemFonts_Delegate.java (renamed from delegates/src/android/graphics/fonts/SystemFonts_Delegate.java)0
-rw-r--r--bridge/src/android/hardware/display/DisplayManagerGlobal.java3
-rw-r--r--bridge/src/android/media/ImageReader_Delegate.java (renamed from delegates/src/android/media/ImageReader_Delegate.java)0
-rw-r--r--bridge/src/android/os/SystemProperties_Delegate.java (renamed from remote/common/src/com/android/layout/remote/api/RemoteParserFactory.java)21
-rw-r--r--bridge/src/android/permission/PermissionManager_Delegate.java (renamed from bridge/src/android/view/TextureView_Delegate.java)16
-rw-r--r--bridge/src/android/provider/DeviceConfig_Delegate.java5
-rw-r--r--bridge/src/android/view/AttachInfo_Accessor.java42
-rw-r--r--bridge/src/android/view/BridgeInflater.java119
-rw-r--r--bridge/src/android/view/Choreographer_Delegate.java9
-rw-r--r--bridge/src/android/view/DisplayEventReceiver_Delegate.java48
-rw-r--r--bridge/src/android/view/VelocityTracker_Delegate.java41
-rw-r--r--bridge/src/android/view/ViewRootImpl_Accessor.java9
-rw-r--r--bridge/src/android/view/ViewRootImpl_Delegate.java5
-rw-r--r--bridge/src/android/view/WindowManagerImpl.java51
-rw-r--r--bridge/src/android/view/accessibility/AccessibilityManager.java371
-rw-r--r--bridge/src/android/view/accessibility/AccessibilityNodeIdManager.java61
-rw-r--r--bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java40
-rw-r--r--bridge/src/android/widget/AbsListView_Delegate.java24
-rw-r--r--bridge/src/android/widget/Magnifier_Delegate.java34
-rw-r--r--bridge/src/com/android/layoutlib/bridge/Bridge.java114
-rw-r--r--bridge/src/com/android/layoutlib/bridge/BridgeConstants.java3
-rw-r--r--bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java6
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/ApplicationContext.java1323
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java31
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java51
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java75
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java60
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/DynamicRenderResources.java207
-rw-r--r--bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java22
-rw-r--r--bridge/src/com/android/layoutlib/bridge/bars/Config.java7
-rw-r--r--bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java8
-rw-r--r--bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java2
-rw-r--r--bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java223
-rw-r--r--bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java16
-rw-r--r--bridge/src/com/android/layoutlib/bridge/util/ChoreographerCallbacks.java33
-rw-r--r--bridge/src/com/android/layoutlib/bridge/util/HandlerMessageQueue.java58
-rw-r--r--bridge/src/com/android/layoutlib/bridge/util/KeyEventHandling.java395
-rw-r--r--bridge/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java (renamed from delegates/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java)0
-rw-r--r--bridge/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java (renamed from delegates/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java)0
-rw-r--r--bridge/src/dalvik/system/VMRuntimeCommonHelper.java (renamed from delegates/src/dalvik/system/VMRuntimeCommonHelper.java)0
-rw-r--r--bridge/tests/Android.bp17
-rw-r--r--bridge/tests/bridge_tests.iml29
-rw-r--r--bridge/tests/res/com/android/layoutlib/testdata/wallpaper1.webpbin0 -> 175870 bytes
-rw-r--r--bridge/tests/res/com/android/layoutlib/testdata/wallpaper2.webpbin0 -> 486114 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/a11y_test1.pngbin12184 -> 15680 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/activity.pngbin89971 -> 89998 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.pngbin23469 -> 23893 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_circle.pngbin26151 -> 26576 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_green.pngbin0 -> 25586 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_orange.pngbin0 -> 25703 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_rounded_corners.pngbin24229 -> 24654 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_squircle.pngbin26816 -> 27241 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/allwidgets.pngbin161678 -> 161814 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.pngbin62949 -> 62790 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/animated_vector.pngbin42362 -> 42570 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.pngbin37224 -> 37425 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/array_check.pngbin57970 -> 57972 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/asset.pngbin415049 -> 415465 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/auto-scale-image.pngbin2020 -> 1462 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/bitmap_decoder.pngbin0 -> 1567 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/button_resize.pngbin2506 -> 2389 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/button_resize2.pngbin3055 -> 3348 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/canvas.pngbin23021 -> 23097 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/color_interpolation.pngbin39748 -> 39773 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/context_theme_wrapper.pngbin19874 -> 20275 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/dialog.pngbin33533 -> 29191 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.pngbin9636 -> 9922 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.pngbin16866 -> 17097 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/font_test.pngbin76885 -> 76799 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/four_corners.pngbin50376 -> 50506 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.pngbin49252 -> 49213 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.pngbin55566 -> 55487 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/gradient_colors.pngbin35356 -> 35467 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/html.pngbin0 -> 18951 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/justified_inter_word.pngbin258544 -> 259667 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/justified_none.pngbin254039 -> 255270 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/large_shadows_test.pngbin65364 -> 22118 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/many_line_breaks.pngbin85776 -> 85139 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/ninepatch_background.pngbin32383 -> 32322 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/ninepatch_drawable.pngbin43986 -> 34963 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/ondraw_crash.pngbin22251 -> 22662 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/onmeasure_crash.pngbin20098 -> 20498 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/remote_component_load.pngbin15967 -> 0 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/remote_component_load_fail.pngbin8568 -> 0 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/render_effect.pngbin98036 -> 90956 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/rtl_ltr.pngbin51076 -> 50572 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/shadow_scrollview_test.pngbin94874 -> 33933 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/shadow_sizes_test.pngbin151331 -> 43315 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/shadows_test.pngbin124440 -> 27970 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/shadows_test_rounded_edge.pngbin177804 -> 38459 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.pngbin28761 -> 29213 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/simple_activity.pngbin26935 -> 27254 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.pngbin26769 -> 27185 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/textclock.pngbin15383 -> 15338 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/translate_test.pngbin13779 -> 13303 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/transparent_drawable.pngbin11683 -> 12403 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/typed_arrays.pngbin54684 -> 54698 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable.pngbin38997 -> 44874 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.pngbin34923 -> 35615 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable_gradient.pngbin37498 -> 37923 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable_radial_gradient.pngbin61757 -> 62205 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_in_image_view.pngbin82791 -> 82624 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_itself.pngbin43991 -> 43863 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/view_boundaries.pngbin23079 -> 23743 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/view_stub.pngbin41024 -> 40926 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/golden/window_background.pngbin15591 -> 15607 bytes
-rw-r--r--bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml1
-rwxr-xr-xbridge/tests/run_tests.sh87
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/android/AccessibilityTest.java74
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/android/BitmapTest.java70
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/android/BridgeContextTest.java60
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/android/DynamicRenderResourcesTest.java61
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/android/RenderTestBase.java83
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java6
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/LayoutLibTestCallback.java (renamed from delegates/src/com/android/tools/layoutlib/java/text/DateFormat_Delegate.java)21
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java5
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java1
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java393
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/intensive/ShadowsRenderTests.java2
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/test/widgets/HtmlTextView.java (renamed from remote/tests/src/CustomComponent.java)36
-rw-r--r--bridge/tests/src/com/android/layoutlib/bridge/util/ChoreographerCallbacksTest.java34
-rw-r--r--bridge/tests/src/com/android/tools/idea/validator/AccessibilityValidatorTests.java41
-rw-r--r--bridge/tests/src/com/android/tools/idea/validator/LayoutValidatorTests.java11
-rw-r--r--common/src/com/android/tools/layoutlib/create/NativeConfig.java29
-rw-r--r--create/Android.bp7
-rw-r--r--create/create.iml21
-rw-r--r--create/src/com/android/tools/layoutlib/create/CreateInfo.java129
-rw-r--r--create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java72
-rw-r--r--create/src/com/android/tools/layoutlib/create/Main.java66
-rw-r--r--create/tests/Android.bp2
-rwxr-xr-xcreate/tests/run_tests.sh2
-rw-r--r--create/tests/src/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java21
-rw-r--r--delegates/Android.bp31
-rw-r--r--delegates/README1
-rw-r--r--delegates/delegates.iml14
-rw-r--r--delegates/src/com/android/tools/layoutlib/java/util/LocaleAdjustLanguageCodeReplacement.java43
-rw-r--r--delegates/src/com/android/tools/layoutlib/java/util/zip/ZipEntry_Delegate.java49
-rw-r--r--remote/client/remote client.iml25
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java123
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteActionBarCallbackAdapter.java71
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteAssetRepositoryAdapter.java52
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteDrawableParamsAdapter.java48
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteILayoutPullParserAdapter.java48
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java64
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutlibCallbackAdapter.java154
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderParamsAdapter.java157
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderResourcesAdapter.java116
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderSessionAdapter.java111
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteSessionParamsAdapter.java80
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteXmlPullParserAdapter.java234
-rw-r--r--remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/package-info.java5
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteActionBarCallback.java44
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteAssetRepository.java36
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteBridge.java104
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteDrawableParams.java31
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteHardwareConfig.java71
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteILayoutPullParser.java31
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java84
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteLayoutlibCallback.java64
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteNamespaceResolver.java50
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteRenderParams.java64
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteRenderResources.java61
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteRenderSession.java48
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteResourceValue.java117
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteSessionParams.java45
-rw-r--r--remote/common/src/com/android/layout/remote/api/RemoteXmlPullParser.java109
-rw-r--r--remote/common/src/com/android/layout/remote/api/package-info.java6
-rw-r--r--remote/common/src/com/android/layout/remote/util/RemoteInputStream.java42
-rw-r--r--remote/common/src/com/android/layout/remote/util/RemoteInputStreamAdapter.java82
-rw-r--r--remote/common/src/com/android/layout/remote/util/RemoteResolverAdapter.java51
-rw-r--r--remote/common/src/com/android/layout/remote/util/SerializableImageImpl.java55
-rw-r--r--remote/common/src/com/android/layout/remote/util/StreamUtil.java96
-rw-r--r--remote/server/remote server.iml26
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/RemoteBridgeImpl.java149
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/ServerMain.java213
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteActionBarCallbackAdapter.java87
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteAssetRepositoryAdapter.java50
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteILayoutPullParserAdapter.java49
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java78
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutlibCallbackAdapter.java286
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java149
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderSessionAdapter.java78
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteXmlPullParserAdapter.java353
-rw-r--r--remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/package-info.java5
-rw-r--r--remote/tests/remote tests.iml79
-rw-r--r--remote/tests/src/RemoteBridgeTest.java146
-rw-r--r--validator/Android.bp2
-rw-r--r--validator/resources/strings.properties71
-rw-r--r--validator/src/com/android/tools/idea/validator/LayoutValidator.java2
-rw-r--r--validator/src/com/android/tools/idea/validator/ValidatorUtil.java9
-rw-r--r--validator/validator.iml35
249 files changed, 4347 insertions, 6119 deletions
diff --git a/.gitignore b/.gitignore
index d886ce191e..7f426b5cda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
bin
/out
/bridge/out
+/bridge/tests/out
/.idea/kotlinc.xml
/.idea/shelf
/.idea/workspace.xml
diff --git a/.idea/libraries/jsoup.xml b/.idea/libraries/jsoup.xml
new file mode 100644
index 0000000000..e11698c0d5
--- /dev/null
+++ b/.idea/libraries/jsoup.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="jsoup">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/tools/common/m2/repository/org/jsoup/jsoup/1.6.3/jsoup-1.6.3.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/kotlin_stdlib.xml b/.idea/libraries/kotlin_stdlib.xml
new file mode 100644
index 0000000000..9673da8948
--- /dev/null
+++ b/.idea/libraries/kotlin_stdlib.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="kotlin-stdlib">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../external/kotlinc/lib/kotlin-stdlib.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/kxml.xml b/.idea/libraries/kxml.xml
new file mode 100644
index 0000000000..62b9adb6ba
--- /dev/null
+++ b/.idea/libraries/kxml.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="kxml">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$PROJECT_DIR$/../../libcore/xml/src/main/java" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/libprotobuf_java_lite.xml b/.idea/libraries/libprotobuf_java_lite.xml
new file mode 100644
index 0000000000..18c6702200
--- /dev/null
+++ b/.idea/libraries/libprotobuf_java_lite.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="libprotobuf-java-lite">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../out/soong/.intermediates/external/protobuf/libprotobuf-java-lite/linux_glibc_common/javac/libprotobuf-java-lite.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$PROJECT_DIR$/../../external/protobuf/java/core/src/main/java" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/ninepatch_prebuilt.xml b/.idea/libraries/ninepatch_prebuilt.xml
new file mode 100644
index 0000000000..2ee7a532e1
--- /dev/null
+++ b/.idea/libraries/ninepatch_prebuilt.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="ninepatch-prebuilt">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt-sources.jar!/" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/sdk_common.xml b/.idea/libraries/sdk_common.xml
new file mode 100644
index 0000000000..5198492f98
--- /dev/null
+++ b/.idea/libraries/sdk_common.xml
@@ -0,0 +1,11 @@
+<component name="libraryTable">
+ <library name="sdk-common">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/tools_common_prebuilt.xml b/.idea/libraries/tools_common_prebuilt.xml
new file mode 100644
index 0000000000..5ace0c32da
--- /dev/null
+++ b/.idea/libraries/tools_common_prebuilt.xml
@@ -0,0 +1,14 @@
+<component name="libraryTable">
+ <library name="tools-common-prebuilt">
+ <ANNOTATIONS>
+ <root url="file://$PROJECT_DIR$" />
+ </ANNOTATIONS>
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
+ </SOURCES>
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/trove4j.xml b/.idea/libraries/trove4j.xml
new file mode 100644
index 0000000000..c5968a7889
--- /dev/null
+++ b/.idea/libraries/trove4j.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="trove4j">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/../../prebuilts/tools/common/m2/repository/net/sf/trove4j/trove4j/1.1/trove4j-1.1.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 943a663b39..0a1e4e0324 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -53,7 +53,7 @@
</value>
</option>
</component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 5b018bb9ec..5359d3cbad 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,13 +3,10 @@
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/bridge/bridge.iml" filepath="$PROJECT_DIR$/bridge/bridge.iml" />
+ <module fileurl="file://$PROJECT_DIR$/bridge/bridge_client/bridge_client.iml" filepath="$PROJECT_DIR$/bridge/bridge_client/bridge_client.iml" />
+ <module fileurl="file://$PROJECT_DIR$/bridge/tests/bridge_tests.iml" filepath="$PROJECT_DIR$/bridge/tests/bridge_tests.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common.iml" filepath="$PROJECT_DIR$/common/common.iml" />
<module fileurl="file://$PROJECT_DIR$/create/create.iml" filepath="$PROJECT_DIR$/create/create.iml" />
- <module fileurl="file://$PROJECT_DIR$/delegates/delegates.iml" filepath="$PROJECT_DIR$/delegates/delegates.iml" />
- <module fileurl="file://$PROJECT_DIR$/remote/client/remote client.iml" filepath="$PROJECT_DIR$/remote/client/remote client.iml" group="remote" />
- <module fileurl="file://$PROJECT_DIR$/remote/common/remote common.iml" filepath="$PROJECT_DIR$/remote/common/remote common.iml" group="remote" />
- <module fileurl="file://$PROJECT_DIR$/remote/server/remote server.iml" filepath="$PROJECT_DIR$/remote/server/remote server.iml" group="remote" />
- <module fileurl="file://$PROJECT_DIR$/remote/tests/remote tests.iml" filepath="$PROJECT_DIR$/remote/tests/remote tests.iml" group="remote" />
<module fileurl="file://$PROJECT_DIR$/validator/validator.iml" filepath="$PROJECT_DIR$/validator/validator.iml" />
</modules>
</component>
diff --git a/.idea/runConfigurations/All_in_bridge.xml b/.idea/runConfigurations/All_in_bridge.xml
index e89deb32e0..5353408242 100644
--- a/.idea/runConfigurations/All_in_bridge.xml
+++ b/.idea/runConfigurations/All_in_bridge.xml
@@ -1,7 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All in bridge" type="JUnit" factoryName="JUnit" singleton="true">
- <module name="bridge" />
- <option name="ALTERNATIVE_JRE_PATH" value="11" />
+ <module name="bridge_tests" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+ <option name="ALTERNATIVE_JRE_PATH" value="jbr-17" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
diff --git a/.idea/runConfigurations/All_in_create.xml b/.idea/runConfigurations/All_in_create.xml
index 08ae5b5df0..ac2401627d 100644
--- a/.idea/runConfigurations/All_in_create.xml
+++ b/.idea/runConfigurations/All_in_create.xml
@@ -1,6 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All in create" type="JUnit" factoryName="JUnit" singleton="false" nameIsGenerated="true">
<module name="create" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+ <option name="ALTERNATIVE_JRE_PATH" value="jbr-17" />
<option name="PACKAGE_NAME" value="" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
diff --git a/.idea/runConfigurations/Bridge_quick.xml b/.idea/runConfigurations/Bridge_quick.xml
index 9ed99d1039..3a598ab60d 100644
--- a/.idea/runConfigurations/Bridge_quick.xml
+++ b/.idea/runConfigurations/Bridge_quick.xml
@@ -1,7 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Bridge quick" type="JUnit" factoryName="JUnit">
- <module name="bridge" />
- <option name="ALTERNATIVE_JRE_PATH" value="11" />
+ <module name="bridge_tests" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+ <option name="ALTERNATIVE_JRE_PATH" value="jbr-17" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="pattern" />
diff --git a/.idea/runConfigurations/Create.xml b/.idea/runConfigurations/Create.xml
index 11a2ae4296..68f4a033f8 100644
--- a/.idea/runConfigurations/Create.xml
+++ b/.idea/runConfigurations/Create.xml
@@ -3,7 +3,7 @@
<option name="ALTERNATIVE_JRE_PATH" value="$PROJECT_DIR$/../../prebuilts/jdk/jdk9/linux-x86" />
<option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
<module name="create" />
- <option name="PROGRAM_PARAMETERS" value="--create-stub out/soong/.temp/temp_layoutlib.jar out/soong/.intermediates/prebuilts/misc/common/atf/atf-prebuilt-jars-371374941/linux_glibc_common/combined/atf-prebuilt-jars-371374941.jar out/soong/.intermediates/external/icu/android_icu4j/core-icu4j-for-host/android_common/withres/core-icu4j-for-host.jar out/soong/.intermediates/libcore/core-libart/android_common/javac/core-libart.jar out/soong/.intermediates/frameworks/base/framework-all/android_common/combined/framework-all.jar out/soong/.intermediates/frameworks/base/ext/android_common/withres/ext.jar out/soong/.intermediates/external/icu/icu4j/icu4j-icudata-jarjar/linux_glibc_common/jarjar/icu4j-icudata-jarjar.jar out/soong/.intermediates/external/icu/icu4j/icu4j-icutzdata-jarjar/linux_glibc_common/jarjar/icu4j-icutzdata-jarjar.jar" />
+ <option name="PROGRAM_PARAMETERS" value="--create-stub out/soong/.temp/temp_layoutlib.jar out/soong/.intermediates/prebuilts/misc/common/atf/atf-prebuilt-jars-502584086/linux_glibc_common/combined/atf-prebuilt-jars-502584086.jar out/soong/.intermediates/external/icu/android_icu4j/core-icu4j-for-host/android_common/withres/core-icu4j-for-host.jar out/soong/.intermediates/libcore/core-libart/android_common/javac/core-libart.jar out/soong/.intermediates/frameworks/base/framework-all/android_common/combined/framework-all.jar out/soong/.intermediates/frameworks/base/ext/android_common/withres/ext.jar out/soong/.intermediates/external/icu/icu4j/icu4j-icudata-jarjar/linux_glibc_common/jarjar/icu4j-icudata-jarjar.jar out/soong/.intermediates/external/icu/icu4j/icu4j-icutzdata-jarjar/linux_glibc_common/jarjar/icu4j-icutzdata-jarjar.jar out/soong/.intermediates/frameworks/base/packages/SystemUI/monet/monet/android_common/combined/monet.jar" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../.." />
<RunnerSettings RunnerId="Debug">
diff --git a/Android.bp b/Android.bp
index 0be4cccad8..76bc916b23 100644
--- a/Android.bp
+++ b/Android.bp
@@ -30,27 +30,18 @@ java_genrule_host {
tools: ["layoutlib_create"],
out: ["temp_layoutlib.jar"],
srcs: [
- ":atf-prebuilt-371374941{.jar}",
+ ":atf-prebuilt-502584086{.jar}",
":core-icu4j-for-host{.jar}",
":core-libart-for-host{.jar}",
":framework-all{.jar}",
":ext{.jar}",
":icu4j-icudata-jarjar{.jar}", // HOST
":icu4j-icutzdata-jarjar{.jar}", // HOST
+ ":monet{.jar}",
],
cmd: "rm -f $(out) && $(location layoutlib_create) --create-stub $(out) $(in)",
}
-java_genrule_host {
- name: "layoutlib-native-delegates",
- tools: ["layoutlib_create"],
- out: ["layoutlib-native-delegates.jar"],
- srcs: [
- ":framework{.jar}",
- ],
- cmd: "rm -f $(out) && $(location layoutlib_create) --create-native-only-delegates $(out) $(in)",
-}
-
java_device_for_host {
name: "layoutlib_create-classpath",
libs: [
@@ -61,5 +52,6 @@ java_device_for_host {
"framework-all",
"icu4j-icudata-jarjar",
"icu4j-icutzdata-jarjar",
+ "monet",
],
}
diff --git a/bridge/Android.bp b/bridge/Android.bp
index 5eefce25e0..a48f0d009a 100644
--- a/bridge/Android.bp
+++ b/bridge/Android.bp
@@ -35,7 +35,6 @@ java_library_host {
static_libs: [
"temp_layoutlib",
"layoutlib-common",
- "layoutlib-common-delegates",
"layoutlib-validator",
],
@@ -44,34 +43,4 @@ java_library_host {
dist: {
targets: ["layoutlib"],
},
-}
-
-java_library_host {
- name: "layoutlib-no-framework",
-
- srcs: ["src/**/*.java"],
- java_resource_dirs: ["resources"],
-
- libs: [
- "kxml2-2.3.0",
- "temp_layoutlib",
- "guava",
- "ninepatch-prebuilt",
- "sdk-common",
- ],
-
- static_libs: [
- "layoutlib_create",
- "layoutlib_api-prebuilt",
- "layoutlib-common",
- "layoutlib-common-delegates",
- "layoutlib-native-delegates",
- "layoutlib-validator",
- ],
-
- jarjar_rules: "jarjar-rules.txt",
-
- dist: {
- targets: ["layoutlib"],
- },
-}
+} \ No newline at end of file
diff --git a/bridge/bridge.iml b/bridge/bridge.iml
index 870615d38c..913590c286 100644
--- a/bridge/bridge.iml
+++ b/bridge/bridge.iml
@@ -5,94 +5,20 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/tests/res" type="java-test-resource" />
- <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
- <sourceFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.settings" />
<excludeFolder url="file://$MODULE_DIR$/bin" />
<excludeFolder url="file://$MODULE_DIR$/out" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.gradle" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/.idea" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/generated" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/assets" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/dependency-cache" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/incremental" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/libs" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/manifests" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/res" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/rs" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/build/intermediates/symbols" />
- <excludeFolder url="file://$MODULE_DIR$/tests/res/testApp/MyApplication/gradle" />
+ <excludeFolder url="file://$MODULE_DIR$/tests/res" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="kxml" level="project" />
<orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="module-library" scope="TEST">
- <library name="tools-common-prebuilt">
- <ANNOTATIONS>
- <root url="file://$MODULE_DIR$/.." />
- </ANNOTATIONS>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="library" name="framework.jar" level="project" />
<orderEntry type="library" name="guava" level="project" />
- <orderEntry type="module-library">
- <library name="sdk-common">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="library" scope="TEST" name="junit" level="project" />
- <orderEntry type="library" scope="TEST" name="mockito" level="project" />
- <orderEntry type="library" scope="TEST" name="objenesis" level="project" />
+ <orderEntry type="library" name="ninepatch-prebuilt" level="project" />
+ <orderEntry type="library" name="sdk-common" level="project" />
+ <orderEntry type="library" name="framework.jar" level="project" />
<orderEntry type="module" module-name="common" />
- <orderEntry type="module-library">
- <library name="kxml2-2.3.0">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$MODULE_DIR$/../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
- <orderEntry type="module" module-name="delegates" />
- <orderEntry type="module-library">
- <library name="ninepatch-prebuilt">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module-library" scope="TEST">
- <library name="trove4j">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/net/sf/trove4j/trove4j/1.1/trove4j-1.1.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/net/sf/trove4j/trove4j/1.1/trove4j-1.1-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
<orderEntry type="module" module-name="validator" />
</component>
</module> \ No newline at end of file
diff --git a/bridge/bridge_client/Android.bp b/bridge/bridge_client/Android.bp
new file mode 100644
index 0000000000..02bd07f037
--- /dev/null
+++ b/bridge/bridge_client/Android.bp
@@ -0,0 +1,51 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library_host {
+ name: "layoutlib-bridge-client",
+
+ // Only compile source java files in this lib.
+ srcs: [
+ "**/*.java",
+ ],
+
+ static_libs: [
+ "tools-common-prebuilt",
+ "sdk-common",
+ "kxml2-2.3.0",
+ "layoutlib_api-prebuilt",
+ "trove-prebuilt",
+ "junit",
+ "guava",
+ "layoutlib",
+ ],
+
+ // Copy the jar to DIST_DIR for sdk builds
+ dist: {
+ targets: [
+ "sdk",
+ "win_sdk",
+ ],
+ },
+}
+
+java_host_for_device {
+ name: "layoutlib-bridge-client-target",
+ libs: ["layoutlib-bridge-client"],
+ visibility: ["//visibility:public"],
+}
diff --git a/remote/common/remote common.iml b/bridge/bridge_client/bridge_client.iml
index 1562b6d21c..618c727706 100644
--- a/remote/common/remote common.iml
+++ b/bridge/bridge_client/bridge_client.iml
@@ -3,23 +3,19 @@
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$MODULE_DIR$/../../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
- </orderEntry>
+ <orderEntry type="library" name="tools-common-prebuilt" level="project" />
+ <orderEntry type="library" name="sdk-common" level="project" />
+ <orderEntry type="library" name="kxml" level="project" />
<orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="module" module-name="common" />
+ <orderEntry type="library" name="trove4j" level="project" />
+ <orderEntry type="library" name="junit" level="project" />
+ <orderEntry type="library" name="guava" level="project" />
<orderEntry type="library" name="framework.jar" level="project" />
+ <orderEntry type="module" module-name="bridge" />
+ <orderEntry type="module" module-name="common" />
</component>
</module> \ No newline at end of file
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
index 2624df0e1b..2624df0e1b 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
index 5434cadfb1..5434cadfb1 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdResourceParser.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdResourceParser.java
index 090217ab54..090217ab54 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdResourceParser.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/IdResourceParser.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
index 016c6b4088..016c6b4088 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java
index 67c48f3940..67c48f3940 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceDeltaKind.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFile.java
index 30fbd0b153..30fbd0b153 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFile.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
index 5fc2c195ec..5fc2c195ec 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceItem.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceItem.java
index 8aaefde789..8aaefde789 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceItem.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceItem.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
index fca0862922..fca0862922 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ScanningContext.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ScanningContext.java
index dadf18d42d..dadf18d42d 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ScanningContext.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ScanningContext.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
index 38d975dab4..38d975dab4 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java
index f1f3f1743a..f1f3f1743a 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java
index f945d3c650..f945d3c650 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java
index 58af88d9d6..58af88d9d6 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValidatingResourceParser.java
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java
index 53bb5c0fcc..53bb5c0fcc 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java
+++ b/bridge/bridge_client/src/com/android/ide/common/resources/deprecated/ValueResourceParser.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/BridgeClient.java
index 7054f2b49c..cff0e9ea49 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/BridgeClient.java
@@ -29,8 +29,8 @@ import com.android.internal.lang.System_Delegate;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
+import com.android.layoutlib.bridge.intensive.setup.LayoutlibBridgeClientCallback;
import com.android.layoutlib.bridge.intensive.util.ImageUtils;
import com.android.layoutlib.bridge.intensive.util.ModuleClassLoader;
import com.android.layoutlib.bridge.intensive.util.SessionParamsBuilder;
@@ -52,10 +52,8 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Locale;
import java.util.concurrent.TimeUnit;
import com.google.android.collect.Lists;
@@ -84,40 +82,27 @@ import static org.junit.Assert.fail;
* 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
* falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
* <p>
- * The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
+ * The app resources are obtained using getAppResources() getAppTestAsset() getAppClassesLocation()
*/
-public class RenderTestBase {
-
- /**
- * Listener for render process.
- */
- public interface RenderSessionListener {
-
- /**
- * Called before session is disposed after rendering.
- */
- void beforeDisposed(RenderSession session);
- }
+public abstract class BridgeClient {
+ protected static final String PLATFORM_DIR;
+ private static final String ANDROID_HOST_OUT_DIR_PROPERTY = "android_host_out.dir";
private static final String NATIVE_LIB_PATH_PROPERTY = "native.lib.path";
private static final String FONT_DIR_PROPERTY = "font.dir";
private static final String ICU_DATA_PATH_PROPERTY = "icu.data.path";
+ private static final String KEYBOARD_DIR_PROPERTY = "keyboard.dir";
private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
- private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
private static final String NATIVE_LIB_DIR_PATH;
private static final String FONT_DIR;
private static final String ICU_DATA_PATH;
- protected static final String PLATFORM_DIR;
- private static final String TEST_RES_DIR;
- /** Location of the app to test inside {@link #TEST_RES_DIR} */
- protected static final String APP_TEST_DIR = "testApp/MyApplication";
- /** Location of the app's res dir inside {@link #TEST_RES_DIR} */
- private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
- /** Location of the app's asset dir inside {@link #TEST_RES_DIR} */
- private static final String APP_TEST_ASSET = APP_TEST_DIR + "/src/main/assets/";
- private static final String APP_CLASSES_LOCATION =
- APP_TEST_DIR + "/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/";
+ private static final String KEYBOARD_DIR;
+ private static final String EMPTY_FRAME =
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?> <FrameLayout "
+ + "xmlns:android=\"http://schemas.android.com/apk/res/android\" "
+ + "android:layout_width=\"match_parent\" "
+ + "android:layout_height=\"match_parent\"> </FrameLayout>";
protected static Bridge sBridge;
/** List of log messages generated by a render call. It can be used to find specific errors */
protected static ArrayList<String> sRenderMessages = Lists.newArrayList();
@@ -137,12 +122,7 @@ public class RenderTestBase {
NATIVE_LIB_DIR_PATH = getNativeLibDirPath();
FONT_DIR = getFontDir();
ICU_DATA_PATH = getIcuDataPath();
-
- TEST_RES_DIR = getTestResDir();
- if (TEST_RES_DIR == null) {
- fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
- RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
- }
+ KEYBOARD_DIR = getKeyboardDir();
}
@Rule
@@ -156,7 +136,6 @@ public class RenderTestBase {
}
}
};
-
@Rule
public TestWatcher sMemoryLeakChecker = new TestWatcher() {
@Override
@@ -168,8 +147,17 @@ public class RenderTestBase {
}
}
};
-
protected ClassLoader mDefaultClassLoader;
+ private String mPackageName;
+ private String mThemeName;
+
+ public BridgeClient(String themeName) {
+ init(themeName);
+ }
+
+ public BridgeClient() {
+ init("AppTheme");
+ }
private static String getNativeLibDirPath() {
String nativeLibDirPath = System.getProperty(NATIVE_LIB_PATH_PROPERTY);
@@ -191,7 +179,7 @@ public class RenderTestBase {
String fontDir = System.getProperty(FONT_DIR_PROPERTY);
if (fontDir == null) {
// The fonts are built into out/host/common/obj/PACKAGING/fonts_intermediates
- // as specified in build/make/core/layoutlib_fonts.mk, and PLATFORM_DIR is
+ // as specified in build/make/core/layoutlib_data.mk, and PLATFORM_DIR is
// out/host/[arch]/sdk/sdk*/android-sdk*/platforms/android*
fontDir = PLATFORM_DIR +
"/../../../../../../common/obj/PACKAGING/fonts_intermediates";
@@ -202,18 +190,47 @@ public class RenderTestBase {
private static String getIcuDataPath() {
String icuDataPath = System.getProperty(ICU_DATA_PATH_PROPERTY);
if (icuDataPath == null) {
- icuDataPath = PLATFORM_DIR + "/../../../../../com.android.i18n/etc/icu/icudt70l.dat";
+ icuDataPath = PLATFORM_DIR + "/../../../../../com.android.i18n/etc/icu/icudt72l.dat";
}
return icuDataPath;
}
+ private static String getKeyboardDir() {
+ String keyboardDir = System.getProperty(KEYBOARD_DIR_PROPERTY);
+ if (keyboardDir == null) {
+ // The keyboard files are built into
+ // out/host/common/obj/PACKAGING/keyboards_intermediates
+ // as specified in build/make/core/layoutlib_data.mk, and PLATFORM_DIR is
+ // out/host/[arch]/sdk/sdk*/android-sdk*/platforms/android*
+ keyboardDir = PLATFORM_DIR +
+ "/../../../../../../common/obj/PACKAGING/keyboards_intermediates";
+ }
+ return keyboardDir;
+ }
+
+ private static String getAndroidHostOutDir() {
+ String androidHostOutDir = System.getProperty(ANDROID_HOST_OUT_DIR_PROPERTY);
+ if (androidHostOutDir != null && !androidHostOutDir.isEmpty()
+ && new File(androidHostOutDir).isDirectory()) {
+ return androidHostOutDir;
+ }
+
+ androidHostOutDir = System.getenv("ANDROID_HOST_OUT");
+ if (androidHostOutDir != null && !androidHostOutDir.isEmpty()
+ && new File(androidHostOutDir).isDirectory()) {
+ return androidHostOutDir;
+ }
+
+ return null;
+ }
+
private static String getPlatformDir() {
String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
return platformDir;
}
// System Property not set. Try to find the directory in the build directory.
- String androidHostOut = System.getenv("ANDROID_HOST_OUT");
+ String androidHostOut = getAndroidHostOutDir();
if (androidHostOut != null) {
platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
if (platformDir != null) {
@@ -339,21 +356,6 @@ public class RenderTestBase {
return null;
}
- private static String getTestResDir() {
- String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
- if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
- return resourceDir;
- }
- // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
- try {
- URL location = RenderTestBase.class.getProtectionDomain().getCodeSource().getLocation();
- return new File(location.getPath()).exists() ? location.getPath() : null;
- } catch (NullPointerException e) {
- // Prevent a lot of null checks by just catching the exception.
- return null;
- }
- }
-
/**
* Initialize the bridge and the resource maps.
*/
@@ -365,23 +367,13 @@ public class RenderTestBase {
sFrameworkRepo.loadResources();
sFrameworkRepo.loadPublicResources(getLogger());
- sProjectResources =
- new ResourceRepository(new TestFolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
- false) {
- @NonNull
- @Override
- protected ResourceItem createResourceItem(@NonNull String name) {
- return new ResourceItem(name);
- }
- };
- sProjectResources.loadResources();
-
File fontLocation = new File(FONT_DIR);
File buildProp = new File(PLATFORM_DIR, "build.prop");
File attrs = new File(res, "values" + File.separator + "attrs.xml");
+ String[] keyboardPaths = new String[0];
sBridge = new Bridge();
sBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation, NATIVE_LIB_DIR_PATH,
- ICU_DATA_PATH, ConfigGenerator.getEnumMap(attrs), getLayoutLog());
+ ICU_DATA_PATH, keyboardPaths, ConfigGenerator.getEnumMap(attrs), getLayoutLog());
Bridge.getLock().lock();
try {
Bridge.setLog(getLayoutLog());
@@ -399,104 +391,14 @@ public class RenderTestBase {
sBridge = null;
}
- @NonNull
- protected static RenderResult render(com.android.ide.common.rendering.api.Bridge bridge,
- SessionParams params,
- long frameTimeNanos) {
- return render(bridge, params, frameTimeNanos, null);
- }
-
- @NonNull
- protected static RenderResult render(com.android.ide.common.rendering.api.Bridge bridge,
- SessionParams params,
- long frameTimeNanos,
- @Nullable RenderSessionListener listener) {
- // TODO: Set up action bar handler properly to test menu rendering.
- // Create session params.
- System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
- System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
- RenderSession session = bridge.createSession(params);
-
- try {
- if (frameTimeNanos != -1) {
- session.setElapsedFrameTimeNanos(frameTimeNanos);
- }
-
- if (!session.getResult().isSuccess()) {
- getLogger().error(session.getResult().getException(),
- session.getResult().getErrorMessage());
- }
- else {
- // Render the session with a timeout of 50s.
- Result renderResult = session.render(50000);
- if (!renderResult.isSuccess()) {
- getLogger().error(session.getResult().getException(),
- session.getResult().getErrorMessage());
- }
- }
- if (listener != null) {
- listener.beforeDisposed(session);
- }
-
- return RenderResult.getFromSession(session);
- } finally {
- session.dispose();
- }
- }
-
- /**
- * Compares the golden image with the passed image
- */
- protected static void verify(@NonNull String goldenImageName, @NonNull BufferedImage image) {
- try {
- boolean isMac = System.getProperty("os.name").toLowerCase(Locale.US).contains("mac");
- String goldenImagePath = APP_TEST_DIR;
- if (isMac) {
- goldenImagePath += "/golden-mac/";
- } else {
- goldenImagePath += "/golden/";
- }
- goldenImagePath += goldenImageName;
- ImageUtils.requireSimilar(goldenImagePath, image);
- } catch (IOException e) {
- getLogger().error(e, e.getMessage());
- }
- }
-
- /**
- * Create a new rendering session and test that rendering the given layout doesn't throw any
- * exceptions and matches the provided image.
- * <p>
- * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
- * how far in the future is.
- */
- @Nullable
- protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName,
- long frameTimeNanos) throws ClassNotFoundException {
- RenderResult result = RenderTestBase.render(sBridge, params, frameTimeNanos);
- assertNotNull(result.getImage());
- verify(goldenFileName, result.getImage());
-
- return result;
- }
-
- /**
- * Create a new rendering session and test that rendering the given layout doesn't throw any
- * exceptions and matches the provided image.
- */
- @Nullable
- protected static RenderResult renderAndVerify(SessionParams params, String goldenFileName)
- throws ClassNotFoundException {
- return RenderTestBase.renderAndVerify(params, goldenFileName, TimeUnit.SECONDS.toNanos(2));
- }
-
protected static ILayoutLog getLayoutLog() {
if (sLayoutLibLog == null) {
sLayoutLibLog = new ILayoutLog() {
@Override
- public void warning(@Nullable String tag, @NonNull String message, @Nullable Object viewCookie,
+ public void warning(@Nullable String tag, @NonNull String message,
+ @Nullable Object viewCookie,
@Nullable Object data) {
- System.out.println("Warning " + tag + ": " + message);
+ System.out.println("BridgeClient: LayoutLog: Warning " + tag + ": " + message);
failWithMsg(message);
}
@@ -512,14 +414,16 @@ public class RenderTestBase {
}
@Override
- public void error(@Nullable String tag, @NonNull String message, @Nullable Object viewCookie,
+ public void error(@Nullable String tag, @NonNull String message,
+ @Nullable Object viewCookie,
@Nullable Object data) {
System.out.println("Error " + tag + ": " + message);
failWithMsg(message);
}
@Override
- public void error(@Nullable String tag, @NonNull String message, @Nullable Throwable throwable,
+ public void error(@Nullable String tag, @NonNull String message,
+ @Nullable Throwable throwable,
@Nullable Object viewCookie, @Nullable Object data) {
System.out.println("Error " + tag + ": " + message);
if (throwable != null) {
@@ -538,7 +442,8 @@ public class RenderTestBase {
}
protected static void ignoreAllLogging() {
- sLayoutLibLog = new ILayoutLog() {};
+ sLayoutLibLog = new ILayoutLog() {
+ };
sLogger = new ILogger() {
@Override
public void error(Throwable t, String msgFormat, Object... args) {
@@ -592,17 +497,144 @@ public class RenderTestBase {
sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args));
}
+ public abstract String getAppTestDir();
+
+ public abstract String getAppTestRes();
+
+ public abstract String getAppResources();
+
+ public abstract String getAppGoldenDir();
+
+ public abstract String getAppTestAsset();
+
+ public abstract String getAppClassesLocation();
+
+ protected void init(String themeName) {
+ mPackageName = "NOT_INITIALIZED";
+ mThemeName = themeName;
+ initProjectResources();
+ }
+
+ public void setPackageName(String packageName) {
+ mPackageName = packageName;
+ }
+
+ public void initProjectResources() {
+ String TEST_RESOURCE_FOLDER = getAppTestRes();
+ sProjectResources =
+ new ResourceRepository(new TestFolderWrapper(TEST_RESOURCE_FOLDER), false) {
+ @NonNull
+ @Override
+ protected ResourceItem createResourceItem(@NonNull String name) {
+ return new ResourceItem(name);
+ }
+ };
+ sProjectResources.loadResources();
+
+ }
+
+ @NonNull
+ protected RenderResult render(com.android.ide.common.rendering.api.Bridge bridge,
+ SessionParams params,
+ long frameTimeNanos) {
+ return render(bridge, params, frameTimeNanos, null);
+ }
+
+ @NonNull
+ protected RenderResult render(com.android.ide.common.rendering.api.Bridge bridge,
+ SessionParams params,
+ long frameTimeNanos,
+ @Nullable RenderSessionListener listener) {
+ // TODO: Set up action bar handler properly to test menu rendering.
+ // Create session params.
+ System_Delegate.setBootTimeNanos(TimeUnit.MILLISECONDS.toNanos(871732800000L));
+ System_Delegate.setNanosTime(TimeUnit.MILLISECONDS.toNanos(871732800000L));
+
+ RenderSession session = bridge.createSession(params);
+
+ try {
+ if (frameTimeNanos != -1) {
+ session.setElapsedFrameTimeNanos(frameTimeNanos);
+ }
+
+ if (!session.getResult().isSuccess()) {
+ getLogger().error(session.getResult().getException(),
+ session.getResult().getErrorMessage());
+ } else {
+ // Render the session with a timeout of 50s.
+ Result renderResult = session.render(50000);
+ if (!renderResult.isSuccess()) {
+ getLogger().error(session.getResult().getException(),
+ session.getResult().getErrorMessage());
+ }
+ }
+ if (listener != null) {
+ listener.beforeDisposed(session);
+ }
+
+ return RenderResult.getFromSession(session);
+ } finally {
+ session.dispose();
+ }
+ }
+
+ /**
+ * Compares the golden image with the passed image
+ */
+ protected void verify(@NonNull String goldenImageName, @NonNull BufferedImage image) {
+ try {
+ String goldenImagePath = getAppGoldenDir() + goldenImageName;
+ ImageUtils.requireSimilar(goldenImagePath, image);
+ } catch (IOException e) {
+ getLogger().error(e, e.getMessage());
+ }
+ }
+
+ /**
+ * Create a new rendering session and test that rendering the given layout doesn't throw any
+ * exceptions and matches the provided image.
+ * <p>
+ * If frameTimeNanos is >= 0 a frame will be executed during the rendering. The time indicates
+ * how far in the future is.
+ */
+ @Nullable
+ protected RenderResult renderAndVerify(SessionParams params, String goldenFileName,
+ long frameTimeNanos) throws ClassNotFoundException {
+ RenderResult result = render(sBridge, params, frameTimeNanos);
+ assertNotNull(result.getImage());
+ verify(goldenFileName, result.getImage());
+
+ return result;
+ }
+
+ /**
+ * Create a new rendering session and test that rendering the given layout doesn't throw any
+ * exceptions and matches the provided image.
+ */
+ @Nullable
+ protected RenderResult renderAndVerify(SessionParams params, String goldenFileName)
+ throws ClassNotFoundException {
+ return renderAndVerify(params, goldenFileName, TimeUnit.SECONDS.toNanos(2));
+ }
+
@Before
public void beforeTestCase() {
// Default class loader with access to the app classes
- mDefaultClassLoader = new ModuleClassLoader(APP_CLASSES_LOCATION, getClass().getClassLoader());
+ mDefaultClassLoader = new ModuleClassLoader(getAppClassesLocation(),
+ getClass().getClassLoader());
sRenderMessages.clear();
}
@NonNull
protected LayoutPullParser createParserFromPath(String layoutPath)
throws FileNotFoundException {
- return LayoutPullParser.createFromPath(APP_TEST_RES + "/layout/" + layoutPath);
+ return LayoutPullParser.createFromPath(getAppResources() + "/layout/" + layoutPath);
+ }
+
+ @NonNull
+ protected LayoutPullParser createParserFromString(String layoutStr)
+ throws FileNotFoundException {
+ return LayoutPullParser.createFromString(layoutStr);
}
/**
@@ -634,10 +666,17 @@ public class RenderTestBase {
protected SessionParams createSessionParams(String layoutFileName, ConfigGenerator deviceConfig)
throws ClassNotFoundException, FileNotFoundException {
// Create the layout pull parser.
- LayoutPullParser parser = createParserFromPath(layoutFileName);
+
+ LayoutPullParser parser = null;
+ if (layoutFileName != null) {
+ parser = createParserFromPath(layoutFileName);
+ } else {
+ parser = createParserFromString(EMPTY_FRAME);
+
+ }
// Create LayoutLibCallback.
- LayoutLibTestCallback layoutLibCallback =
- new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ LayoutlibBridgeClientCallback layoutLibCallback =
+ new LayoutlibBridgeClientCallback(getLogger(), mDefaultClassLoader, mPackageName);
layoutLibCallback.initResources();
// TODO: Set up action bar handler properly to test menu rendering.
// Create session params.
@@ -645,6 +684,7 @@ public class RenderTestBase {
.setParser(parser)
.setConfigGenerator(deviceConfig)
.setCallback(layoutLibCallback)
+ .setTheme(mThemeName, true)
.build();
}
@@ -663,6 +703,18 @@ public class RenderTestBase {
.setRenderingMode(RenderingMode.NORMAL)
.setTargetSdk(28)
.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true)
- .setAssetRepository(new TestAssetRepository(TEST_RES_DIR + "/" + APP_TEST_ASSET));
+ .setAssetRepository(
+ new TestAssetRepository(getAppTestAsset()));
+ }
+
+ /**
+ * Listener for render process.
+ */
+ public interface RenderSessionListener {
+
+ /**
+ * Called before session is disposed after rendering.
+ */
+ void beforeDisposed(RenderSession session);
}
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/RenderResult.java
index 989d146bc1..989d146bc1 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderResult.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/RenderResult.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
index 684cf12c4e..684cf12c4e 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
index af0c9e5209..af0c9e5209 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutPullParser.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutlibBridgeClientCallback.java
index 8dd7ec7a61..b6663a170c 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/setup/LayoutlibBridgeClientCallback.java
@@ -22,8 +22,6 @@ import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.resources.ResourceType;
import com.android.utils.ILogger;
@@ -50,23 +48,24 @@ import com.google.common.io.ByteStreams;
import static com.android.ide.common.rendering.api.ResourceNamespace.RES_AUTO;
-public class LayoutLibTestCallback extends LayoutlibCallback {
- private static final String PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
-
+public class LayoutlibBridgeClientCallback extends LayoutlibCallback {
private final Map<Integer, ResourceReference> mProjectResources = new HashMap<>();
private final Map<ResourceReference, Integer> mResources = new HashMap<>();
private final ILogger mLog;
private final ActionBarCallback mActionBarCallback = new ActionBarCallback();
private final ClassLoader mModuleClassLoader;
private String mAdaptiveIconMaskPath;
+ private String mPackageName;
- public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
+ public LayoutlibBridgeClientCallback(ILogger logger, ClassLoader classLoader,
+ String packageName) {
mLog = logger;
mModuleClassLoader = classLoader;
+ mPackageName = packageName;
}
public void initResources() throws ClassNotFoundException {
- Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
+ Class<?> rClass = mModuleClassLoader.loadClass(mPackageName + ".R");
Class<?>[] nestedClasses = rClass.getDeclaredClasses();
for (Class<?> resClass : nestedClasses) {
final ResourceType resType = ResourceType.fromClassName(resClass.getSimpleName());
@@ -78,16 +77,16 @@ public class LayoutLibTestCallback extends LayoutlibCallback {
final Class<?> type = field.getType();
try {
if (type == int.class) {
- final Integer value = (Integer) field.get(null);
+ final Integer val = (Integer) field.get(null);
ResourceReference reference =
new ResourceReference(RES_AUTO, resType, field.getName());
- mProjectResources.put(value, reference);
- mResources.put(reference, value);
+ mProjectResources.put(val, reference);
+ mResources.put(reference, val);
} else if (!(type.isArray() && type.getComponentType() == int.class)) {
mLog.error(null, "Unknown field type in R class: %1$s", type);
}
} catch (IllegalAccessException e) {
- mLog.error(e, "Malformed R class: %1$s", PACKAGE_NAME + ".R");
+ mLog.error(e, "Malformed R class: %1$s", mPackageName + ".R");
}
}
}
@@ -95,9 +94,9 @@ public class LayoutLibTestCallback extends LayoutlibCallback {
}
}
-
@Override
- public Object loadView(@NonNull String name, @NonNull Class[] constructorSignature, Object[] constructorArgs)
+ public Object loadView(@NonNull String name, @NonNull Class[] constructorSignature,
+ Object[] constructorArgs)
throws Exception {
Class<?> viewClass = mModuleClassLoader.loadClass(name);
Constructor<?> viewConstructor = viewClass.getConstructor(constructorSignature);
@@ -134,8 +133,7 @@ public class LayoutLibTestCallback extends LayoutlibCallback {
}
@Override
- public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
- Object viewObject) {
+ public AdapterBinding getAdapterBinding(Object viewObject, Map<String, String> attributes) {
return null;
}
@@ -173,28 +171,17 @@ public class LayoutLibTestCallback extends LayoutlibCallback {
}
@Override
- @SuppressWarnings("unchecked") // The Key<T> API is based on unchecked casts.
- public <T> T getFlag(Key<T> key) {
- if (key.equals(RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE)) {
- return (T) PACKAGE_NAME;
- }
- if (key.equals(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH)) {
- return (T) mAdaptiveIconMaskPath;
- }
- return null;
+ public String getApplicationId() {
+ return mPackageName;
}
@Override
public String getResourcePackage() {
- return PACKAGE_NAME;
+ return mPackageName;
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return mModuleClassLoader.loadClass(name);
}
-
- public void setAdaptiveIconMaskPath(String adaptiveIconMaskPath) {
- mAdaptiveIconMaskPath = adaptiveIconMaskPath;
- }
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
index a8adf95d1a..a8adf95d1a 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ImageUtils.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
index d52fdcf9d4..d52fdcf9d4 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/ModuleClassLoader.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
index 35ade3454c..35ade3454c 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
index 54af92d6f5..54af92d6f5 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestAssetRepository.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
index 1df8e7978b..1df8e7978b 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/TestUtils.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
index ee98b4ba3b..ee98b4ba3b 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/LongStatsCollector.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
index 7225a10dbe..7225a10dbe 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/PerformanceRunner.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
index 77a2b0e509..77a2b0e509 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatement.java
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
index 59f90d2954..59f90d2954 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
+++ b/bridge/bridge_client/src/com/android/layoutlib/bridge/intensive/util/perf/TimedStatementResult.java
diff --git a/bridge/src/android/app/ActivityManager_Delegate.java b/bridge/src/android/app/ActivityManager_Delegate.java
new file mode 100644
index 0000000000..72004a2b95
--- /dev/null
+++ b/bridge/src/android/app/ActivityManager_Delegate.java
@@ -0,0 +1,61 @@
+/*
+ * 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.app;
+
+import com.android.internal.os.IResultReceiver;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.app.ActivityManager.MemoryInfo;
+import android.app.ActivityManager.PendingIntentInfo;
+import android.app.ActivityManager.ProcessErrorStateInfo;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.content.ComponentName;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.LocusId;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.IProgressListener;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.StrictMode.ViolationInfo;
+import android.os.WorkSource;
+
+import java.util.List;
+
+public class ActivityManager_Delegate {
+ private static final IActivityManager sStubManager = new IActivityManager.Default();
+
+ @LayoutlibDelegate
+ public static IActivityManager getService() {
+ return sStubManager;
+ }
+}
diff --git a/remote/common/src/com/android/layout/remote/util/SerializableImage.java b/bridge/src/android/app/Application_Delegate.java
index 999aae4ad9..1f1d90adde 100644
--- a/remote/common/src/com/android/layout/remote/util/SerializableImage.java
+++ b/bridge/src/android/app/Application_Delegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,17 +14,12 @@
* limitations under the License.
*/
-package com.android.layout.remote.util;
+package android.app;
-import com.android.tools.layoutlib.annotations.NotNull;
+import android.content.res.Resources;
-import java.awt.image.BufferedImage;
-import java.io.Serializable;
-
-/**
- * Serializable BufferedImage that can be sent across VMs
- */
-public interface SerializableImage extends Serializable {
- @NotNull
- BufferedImage getBufferedImage();
+public class Application_Delegate {
+ public static Resources getResources(Application app) {
+ return Resources.getSystem();
+ }
}
diff --git a/bridge/src/android/content/res/BridgeTypedArray.java b/bridge/src/android/content/res/BridgeTypedArray.java
index 2935c15db1..da59fb79a6 100644
--- a/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/bridge/src/android/content/res/BridgeTypedArray.java
@@ -211,7 +211,7 @@ public final class BridgeTypedArray extends TypedArray {
if (resourceValue instanceof TextResourceValue) {
String rawValue =
ValueXmlHelper.unescapeResourceString(resourceValue.getRawXmlValue(),
- true, false);
+ true, true);
if (rawValue != null && !rawValue.equals(value)) {
return ResourceHelper.parseHtml(rawValue);
}
diff --git a/bridge/src/android/content/res/Resources_Delegate.java b/bridge/src/android/content/res/Resources_Delegate.java
index f453aecce2..7aa02f9464 100644
--- a/bridge/src/android/content/res/Resources_Delegate.java
+++ b/bridge/src/android/content/res/Resources_Delegate.java
@@ -220,26 +220,19 @@ public class Resources_Delegate {
try {
return ResourceHelper.getColor(resourceValue.getValue());
} catch (NumberFormatException e) {
- // Check if the value passed is a file. If it is, mostly likely, user is referencing
- // a color state list from a place where they should reference only a pure color.
- AssetRepository repository = getAssetRepository(resources);
- String message;
- if (repository.isFileResource(resourceValue.getValue())) {
- String resource = (resourceValue.isFramework() ? "@android:" : "@") + "color/"
- + resourceValue.getName();
- message = "Hexadecimal color expected, found Color State List for " + resource;
- } else {
- message = e.getMessage();
+ ColorStateList stateList = ResourceHelper.getColorStateList(resourceValue,
+ getContext(resources), theme);
+ if (stateList != null) {
+ return stateList.getDefaultColor();
}
- Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, message, e, null, null);
+ Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, resourceValue.getName() +
+ " is neither a color value nor a color state list", null, null);
return 0;
}
}
- // Suppress possible NPE. getColorStateList will never return null, it will instead
- // throw an exception, but intelliJ can't figure that out
- //noinspection ConstantConditions
- return getColorStateList(resources, id, theme).getDefaultColor();
+ throwException(resources, id);
+ return 0;
}
@LayoutlibDelegate
diff --git a/bridge/src/android/graphics/ImageDecoder_Delegate.java b/bridge/src/android/graphics/ImageDecoder_Delegate.java
index 4eebc9d41d..b97803bf60 100644
--- a/bridge/src/android/graphics/ImageDecoder_Delegate.java
+++ b/bridge/src/android/graphics/ImageDecoder_Delegate.java
@@ -25,6 +25,7 @@ import android.annotation.NonNull;
import android.graphics.Bitmap.Config;
import android.graphics.ImageDecoder.InputStreamSource;
import android.graphics.ImageDecoder.OnHeaderDecodedListener;
+import android.graphics.ImageDecoder.ResourceSource;
import android.graphics.ImageDecoder.Source;
import java.awt.image.BufferedImage;
@@ -37,6 +38,12 @@ public class ImageDecoder_Delegate {
@LayoutlibDelegate
/*package*/ static Bitmap decodeBitmapImpl(@NonNull Source src,
@NonNull OnHeaderDecodedListener listener) throws IOException {
+ if (src instanceof ResourceSource) {
+ // Bypass ImageDecoder for ResourceSource as it goes through the native AssetManager
+ // which is not supported in layoutlib.
+ ResourceSource source = (ResourceSource) src;
+ return BitmapFactory.decodeResource(source.mResources, source.mResId);
+ }
InputStream stream = src instanceof InputStreamSource ?
((InputStreamSource) src).mInputStream : null;
Bitmap bm = ImageDecoder.decodeBitmapImpl_Original(src, listener);
diff --git a/bridge/src/android/graphics/Typeface_Builder_Delegate.java b/bridge/src/android/graphics/Typeface_Builder_Delegate.java
deleted file mode 100644
index 9d9d8448a4..0000000000
--- a/bridge/src/android/graphics/Typeface_Builder_Delegate.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-package android.graphics;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import android.annotation.Nullable;
-import android.content.res.AssetManager;
-import android.graphics.Typeface.Builder;
-import android.graphics.fonts.FontVariationAxis;
-
-public class Typeface_Builder_Delegate {
-
- /**
- * Creates a unique id for a given AssetManager and asset path.
- *
- * @param mgr AssetManager instance
- * @param path The path for the asset.
- * @param ttcIndex The TTC index for the font.
- * @param axes The font variation settings.
- * @return Unique id for a given AssetManager and asset path.
- */
- @LayoutlibDelegate
- public static String createAssetUid(final AssetManager mgr, String path, int ttcIndex,
- @Nullable FontVariationAxis[] axes, int weight, int italic, String fallback) {
- return Builder.createAssetUid_Original(mgr, path, ttcIndex, axes, weight, italic, fallback);
- }
-}
diff --git a/bridge/src/android/graphics/Typeface_Delegate.java b/bridge/src/android/graphics/Typeface_Delegate.java
index d9d38ad4c3..4568876d1d 100644
--- a/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/bridge/src/android/graphics/Typeface_Delegate.java
@@ -62,6 +62,10 @@ public final class Typeface_Delegate {
return typeface;
}
+ if (path.isBlank()) {
+ return null;
+ }
+
String lowerCaseValue = path.toLowerCase();
if (lowerCaseValue.endsWith(AndroidConstants.DOT_XML)) {
// create a block parser for the file
@@ -114,4 +118,4 @@ public final class Typeface_Delegate {
/*package*/ static Typeface create(Typeface family, int style, boolean isItalic) {
return Typeface.create_Original(family, style, isItalic);
}
-} \ No newline at end of file
+}
diff --git a/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java b/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java
index ca6bc85ff4..3c090e0e5a 100644
--- a/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java
+++ b/bridge/src/android/graphics/drawable/AdaptiveIconDrawable_Delegate.java
@@ -16,22 +16,65 @@
package android.graphics.drawable;
+import com.android.internal.R;
+import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import android.content.res.Resources;
import android.content.res.Resources_Delegate;
-import android.util.PathParser;
-
-import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH;
+import android.graphics.Canvas;
public class AdaptiveIconDrawable_Delegate {
+ public static String sPath;
+
+ /**
+ * Delegate that replaces a call to Resources.getString in
+ * the constructor of AdaptiveIconDrawable.
+ * This allows to pass a non-default value for the mask for adaptive icons.
+ */
+ @SuppressWarnings("unused")
+ public static String getResourceString(Resources res, int resId) {
+ if (resId == R.string.config_icon_mask) {
+ return sPath;
+ }
+ return res.getString(resId);
+ }
@LayoutlibDelegate
- /*package*/ static void constructor_after(AdaptiveIconDrawable icon) {
- String pathString = Resources_Delegate.getLayoutlibCallback(Resources.getSystem()).getFlag(
- FLAG_KEY_ADAPTIVE_ICON_MASK_PATH);
- if (pathString != null) {
- AdaptiveIconDrawable.sMask = PathParser.createPathFromPathData(pathString);
+ public static void draw(AdaptiveIconDrawable thisDrawable, Canvas canvas) {
+ Resources res = Resources.getSystem();
+ BridgeContext context = Resources_Delegate.getContext(res);
+ if (context.useThemedIcon() && thisDrawable.getMonochrome() != null) {
+ AdaptiveIconDrawable themedIcon =
+ createThemedVersionFromMonochrome(thisDrawable.getMonochrome(), res);
+ themedIcon.onBoundsChange(thisDrawable.getBounds());
+ themedIcon.draw_Original(canvas);
+ } else {
+ thisDrawable.draw_Original(canvas);
+ }
+ }
+
+ /**
+ * This builds the themed version of {@link AdaptiveIconDrawable}, copying what the
+ * framework does in {@link com.android.launcher3.Utilities#getFullDrawable}
+ */
+ private static AdaptiveIconDrawable createThemedVersionFromMonochrome(Drawable mono,
+ Resources resources) {
+ mono = mono.mutate();
+ int[] colors = getColors(resources);
+ mono.setTint(colors[1]);
+ return new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
+ }
+
+ private static int[] getColors(Resources resources) {
+ int[] colors = new int[2];
+ if (resources.getConfiguration().isNightModeActive()) {
+ colors[0] = resources.getColor(android.R.color.system_neutral1_800, null);
+ colors[1] = resources.getColor(android.R.color.system_accent1_100, null);
+ } else {
+ colors[0] = resources.getColor(android.R.color.system_accent1_100, null);
+ colors[1] = resources.getColor(android.R.color.system_neutral2_700, null);
}
+ return colors;
}
}
diff --git a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
index 490659bb60..c21a4f1722 100644
--- a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
+++ b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
@@ -46,6 +46,11 @@ public class Font_Builder_Delegate {
@LayoutlibDelegate
/*package*/ static ByteBuffer createBuffer(@NonNull AssetManager am, @NonNull String path,
boolean isAsset, int cookie) throws IOException {
+
+ if (path.isBlank()) {
+ return null;
+ }
+
try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER)
: am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) {
diff --git a/delegates/src/android/graphics/fonts/SystemFonts_Delegate.java b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java
index ff2d64c708..ff2d64c708 100644
--- a/delegates/src/android/graphics/fonts/SystemFonts_Delegate.java
+++ b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java
diff --git a/bridge/src/android/hardware/display/DisplayManagerGlobal.java b/bridge/src/android/hardware/display/DisplayManagerGlobal.java
index f58467f51b..e30009083f 100644
--- a/bridge/src/android/hardware/display/DisplayManagerGlobal.java
+++ b/bridge/src/android/hardware/display/DisplayManagerGlobal.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.ColorSpace;
import android.graphics.Point;
+import android.hardware.OverlayProperties;
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.projection.MediaProjection;
import android.os.Handler;
@@ -150,6 +151,8 @@ public final class DisplayManagerGlobal {
return null;
}
+ public OverlayProperties getOverlaySupport() { return null; }
+
public void setBrightnessConfigurationForUser(BrightnessConfiguration c, int userId,
String packageName) {}
diff --git a/delegates/src/android/media/ImageReader_Delegate.java b/bridge/src/android/media/ImageReader_Delegate.java
index 0ff1ce7303..0ff1ce7303 100644
--- a/delegates/src/android/media/ImageReader_Delegate.java
+++ b/bridge/src/android/media/ImageReader_Delegate.java
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteParserFactory.java b/bridge/src/android/os/SystemProperties_Delegate.java
index 4f187d1132..caf3a09a03 100644
--- a/remote/common/src/com/android/layout/remote/api/RemoteParserFactory.java
+++ b/bridge/src/android/os/SystemProperties_Delegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,16 +14,17 @@
* limitations under the License.
*/
-package com.android.layout.remote.api;
+package android.os;
-import com.android.tools.layoutlib.annotations.Nullable;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
+import android.os.SystemProperties.Handle;
-/**
- * Remote version of the {@link ParserFactory} class
- */
-public interface RemoteParserFactory extends Remote {
- RemoteXmlPullParser createParser(@Nullable String debugName) throws RemoteException;
+public class SystemProperties_Delegate {
+ @LayoutlibDelegate
+ public static Handle find(String name) {
+ // The native method called by the original version of SystemProperties.find
+ // throws a fatal exception for non-bionic devices.
+ return null;
+ }
}
diff --git a/bridge/src/android/view/TextureView_Delegate.java b/bridge/src/android/permission/PermissionManager_Delegate.java
index 0a2abe10cb..1aad83062d 100644
--- a/bridge/src/android/view/TextureView_Delegate.java
+++ b/bridge/src/android/permission/PermissionManager_Delegate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * 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.
@@ -14,18 +14,16 @@
* limitations under the License.
*/
-package android.view;
+package android.permission;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import android.graphics.TextureLayer;
+import android.content.pm.PackageManager;
+
+public class PermissionManager_Delegate {
-public class TextureView_Delegate {
@LayoutlibDelegate
- static TextureLayer getTextureLayer(TextureView thisTextureView) {
- /*
- * Currently layoutlib does not support TextureLayers (no OpenGL)
- */
- return null;
+ public static int checkPermission(String permission, int pid, int uid) {
+ return PackageManager.PERMISSION_GRANTED;
}
}
diff --git a/bridge/src/android/provider/DeviceConfig_Delegate.java b/bridge/src/android/provider/DeviceConfig_Delegate.java
index daf86dc6fa..236bf245f5 100644
--- a/bridge/src/android/provider/DeviceConfig_Delegate.java
+++ b/bridge/src/android/provider/DeviceConfig_Delegate.java
@@ -50,4 +50,9 @@ public class DeviceConfig_Delegate {
public static float getFloat(String namespace, String name, float defaultValue) {
return defaultValue;
}
+
+ @LayoutlibDelegate
+ public static String getProperty(String namespace, String name) {
+ return null;
+ }
}
diff --git a/bridge/src/android/view/AttachInfo_Accessor.java b/bridge/src/android/view/AttachInfo_Accessor.java
index 5f7588ee7d..cd35899c43 100644
--- a/bridge/src/android/view/AttachInfo_Accessor.java
+++ b/bridge/src/android/view/AttachInfo_Accessor.java
@@ -17,44 +17,26 @@
package android.view;
import android.content.Context;
-import android.graphics.HardwareRenderer;
-import android.graphics.RenderNode;
-import android.os.Handler;
import android.view.View.AttachInfo;
-import com.android.layoutlib.common.util.ReflectionUtils;
-
/**
* Class allowing access to package-protected methods/fields.
*/
public class AttachInfo_Accessor {
- public static void setAttachInfo(ViewGroup view, HardwareRenderer renderer) {
+ public static void setAttachInfo(ViewGroup view) {
Context context = view.getContext();
WindowManagerImpl wm = (WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE);
wm.setBaseRootView(view);
Display display = wm.getDefaultDisplay();
- ViewRootImpl root = new ViewRootImpl(context, display);
- root.mAttachInfo.mThreadedRenderer = new ThreadedRenderer(context, false,
- "delegate-renderer") {
- @Override
- public void registerAnimatingRenderNode(RenderNode animator) {
- if (renderer != null) {
- renderer.registerAnimatingRenderNode(animator);
- } else {
- super.registerAnimatingRenderNode(animator);
- }
- }
- };
- AttachInfo info = new AttachInfo(ReflectionUtils.createProxy(IWindowSession.class),
- ReflectionUtils.createProxy(IWindow.class), display, root, new Handler(), null,
- context);
+ ViewRootImpl root = new ViewRootImpl(context, display, new IWindowSession.Default(),
+ new WindowLayout());
+ AttachInfo info = root.mAttachInfo;
info.mHasWindowFocus = true;
info.mWindowVisibility = View.VISIBLE;
info.mInTouchMode = false; // this is so that we can display selections.
- info.mHardwareAccelerated = true;
- // We do not use this one at all, it is only needed to satisfy null checks in View
- info.mThreadedRenderer = new ThreadedRenderer(context, false, "layoutlib-renderer");
+ info.mHardwareAccelerated = false;
+ info.mApplicationScale = 1.0f;
view.dispatchAttachedToWindow(info, 0);
}
@@ -64,19 +46,7 @@ public class AttachInfo_Accessor {
public static void detachFromWindow(final View view) {
if (view != null) {
- final View.AttachInfo attachInfo = view.mAttachInfo;
view.dispatchDetachedFromWindow();
- if (attachInfo != null) {
- final ThreadedRenderer threadedRenderer = attachInfo.mThreadedRenderer;
- if(threadedRenderer != null) {
- threadedRenderer.destroy();
- }
- ThreadedRenderer rootRenderer =
- attachInfo.mViewRootImpl.mAttachInfo.mThreadedRenderer;
- if (rootRenderer != null) {
- rootRenderer.destroy();
- }
- }
}
}
diff --git a/bridge/src/android/view/BridgeInflater.java b/bridge/src/android/view/BridgeInflater.java
index 842badeb6a..ec8476dfb5 100644
--- a/bridge/src/android/view/BridgeInflater.java
+++ b/bridge/src/android/view/BridgeInflater.java
@@ -16,6 +16,7 @@
package android.view;
+import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.AndroidConstants;
import com.android.ide.common.rendering.api.ILayoutLog;
import com.android.ide.common.rendering.api.LayoutlibCallback;
@@ -31,6 +32,8 @@ import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
import com.android.layoutlib.bridge.impl.ParserFactory;
+import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
+import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
import com.android.layoutlib.common.util.ReflectionUtils;
import com.android.tools.layoutlib.annotations.NotNull;
import com.android.tools.layoutlib.annotations.Nullable;
@@ -43,9 +46,15 @@ import android.content.res.TypedArray;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.util.Pair;
import android.util.ResolvingAttributeSet;
import android.view.View.OnAttachStateChangeListener;
+import android.widget.AbsListView;
+import android.widget.AbsSpinner;
+import android.widget.AdapterView;
+import android.widget.ExpandableListView;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.NumberPicker;
import java.lang.reflect.Constructor;
@@ -514,7 +523,117 @@ public final class BridgeInflater extends LayoutInflater {
});
}
}
+ else if (view instanceof AdapterView<?>) {
+ // We do not need data binding support for Glance ListView, the assigned adapter should
+ // handle everything itself.
+ if (isGlanceView(view)) {
+ return;
+ }
+
+ int id = view.getId();
+ ResourceReference listRef = bc.resolveId(id);
+
+ if (listRef != null) {
+ Map<String, String> bindingAttributes = new HashMap<>(4);
+ String header = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
+ BridgeConstants.ATTR_LIST_HEADER);
+ String footer = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
+ BridgeConstants.ATTR_LIST_FOOTER);
+ String layout = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
+ BridgeConstants.ATTR_LIST_ITEM);
+ String columns = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES,
+ BridgeConstants.ATTR_NUM_COLUMNS);
+ if (header != null) {
+ bindingAttributes.put(BridgeConstants.ATTR_LIST_HEADER, header);
+ }
+ if (footer != null) {
+ bindingAttributes.put(BridgeConstants.ATTR_LIST_FOOTER, footer);
+ }
+ if (layout != null) {
+ bindingAttributes.put(BridgeConstants.ATTR_LIST_ITEM, layout);
+ }
+ if (columns != null) {
+ bindingAttributes.put(BridgeConstants.ATTR_NUM_COLUMNS, columns);
+ }
+
+ AdapterBinding binding =
+ mLayoutlibCallback.getAdapterBinding(view, bindingAttributes);
+ if (binding != null) {
+ setAdapterBinding(view, bc, listRef, binding);
+ }
+ }
+ }
+ }
+
+ private void setAdapterBinding(View view, BridgeContext bc, ResourceReference listRef,
+ AdapterBinding binding) {
+ if (view instanceof AbsListView) {
+ if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
+ view instanceof ListView) {
+ ListView list = (ListView) view;
+
+ boolean skipCallbackParser = false;
+
+ int count = binding.getHeaderCount();
+ for (int i = 0; i < count; i++) {
+ Pair<View, Boolean> pair =
+ bc.inflateView(binding.getHeaderAt(i), list, false,
+ skipCallbackParser);
+ if (pair.first != null) {
+ list.addHeaderView(pair.first);
+ }
+
+ skipCallbackParser |= pair.second;
+ }
+
+ count = binding.getFooterCount();
+ for (int i = 0; i < count; i++) {
+ Pair<View, Boolean> pair =
+ bc.inflateView(binding.getFooterAt(i), list, false,
+ skipCallbackParser);
+ if (pair.first != null) {
+ list.addFooterView(pair.first);
+ }
+
+ skipCallbackParser |= pair.second;
+ }
+ }
+
+ if (view instanceof ExpandableListView) {
+ ((ExpandableListView) view).setAdapter(
+ new FakeExpandableAdapter(listRef, binding, mLayoutlibCallback));
+ } else {
+ ((AbsListView) view).setAdapter(
+ new FakeAdapter(listRef, binding, mLayoutlibCallback));
+ }
+ } else if (view instanceof AbsSpinner) {
+ ((AbsSpinner) view).setAdapter(
+ new FakeAdapter(listRef, binding, mLayoutlibCallback));
+ }
+ }
+
+ private static boolean isGlanceAdapter(Class<?> clazz) {
+ return clazz
+ .getName()
+ .equals("androidx.glance.appwidget.preview.GlanceAppWidgetViewAdapter");
+ }
+ /**
+ * Return true if the View belongs to the Glance generated hierarchy (when one of the view's
+ * parents is GlanceAppWidgetViewAdapter).
+ */
+ private static boolean isGlanceView(View view) {
+ if (isGlanceAdapter(view.getClass())) {
+ return true;
+ }
+ ViewParent parent = view.getParent();
+ while (parent != null) {
+ if (isGlanceAdapter(parent.getClass())) {
+ return true;
+ }
+ parent = parent.getParent();
+ }
+ return false;
}
public void setIsInMerge(boolean isInMerge) {
diff --git a/bridge/src/android/view/Choreographer_Delegate.java b/bridge/src/android/view/Choreographer_Delegate.java
index 0b6a9e1e89..d6f3936a72 100644
--- a/bridge/src/android/view/Choreographer_Delegate.java
+++ b/bridge/src/android/view/Choreographer_Delegate.java
@@ -66,7 +66,8 @@ public class Choreographer_Delegate {
Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
"Callback with null action", (Object) null, null);
}
- context.getSessionInteractiveData().getChoreographerCallbacks().add(action, delayMillis);
+ context.getSessionInteractiveData().getChoreographerCallbacks().add(action,
+ token, delayMillis);
}
@LayoutlibDelegate
@@ -80,11 +81,7 @@ public class Choreographer_Delegate {
// Ignore non-animation callbacks
return;
}
- if (action == null) {
- Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
- "Callback with null action", (Object) null, null);
- }
- context.getSessionInteractiveData().getChoreographerCallbacks().remove(action);
+ context.getSessionInteractiveData().getChoreographerCallbacks().remove(action, token);
}
@LayoutlibDelegate
diff --git a/bridge/src/android/view/DisplayEventReceiver_Delegate.java b/bridge/src/android/view/DisplayEventReceiver_Delegate.java
new file mode 100644
index 0000000000..f1d4e65725
--- /dev/null
+++ b/bridge/src/android/view/DisplayEventReceiver_Delegate.java
@@ -0,0 +1,48 @@
+/*
+ * 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.view;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.os.MessageQueue;
+
+import java.lang.ref.WeakReference;
+
+import libcore.util.NativeAllocationRegistry_Delegate;
+
+public class DisplayEventReceiver_Delegate {
+ private static final DelegateManager<DisplayEventReceiver_Delegate> sManager =
+ new DelegateManager<>(DisplayEventReceiver_Delegate.class);
+ private static long sFinalizer = -1;
+
+ @LayoutlibDelegate
+ /*package*/ static long nativeInit(WeakReference<DisplayEventReceiver> receiver,
+ MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle) {
+ return sManager.addNewDelegate(new DisplayEventReceiver_Delegate());
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static long nativeGetDisplayEventReceiverFinalizer() {
+ synchronized (DisplayEventReceiver_Delegate.class) {
+ if (sFinalizer == -1) {
+ sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
+ }
+ }
+ return sFinalizer;
+ }
+}
diff --git a/bridge/src/android/view/VelocityTracker_Delegate.java b/bridge/src/android/view/VelocityTracker_Delegate.java
new file mode 100644
index 0000000000..aad3158d18
--- /dev/null
+++ b/bridge/src/android/view/VelocityTracker_Delegate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import static android.view.VelocityTracker.VELOCITY_TRACKER_STRATEGY_IMPULSE;
+
+public class VelocityTracker_Delegate {
+
+ @LayoutlibDelegate
+ public static VelocityTracker obtain() {
+ // Default VelocityTracker tries to use ApplicationThread which is not supported
+ // by layoutlib. Specify a strategy to work around this issue.
+ return VelocityTracker.obtain(VELOCITY_TRACKER_STRATEGY_IMPULSE);
+ }
+
+ @LayoutlibDelegate
+ public static VelocityTracker obtain(String strategy) {
+ return VelocityTracker.obtain_Original(strategy);
+ }
+
+ @LayoutlibDelegate
+ public static VelocityTracker obtain(int strategy) {
+ return VelocityTracker.obtain_Original(strategy);
+ }
+}
diff --git a/bridge/src/android/view/ViewRootImpl_Accessor.java b/bridge/src/android/view/ViewRootImpl_Accessor.java
index 0e15b97243..81ffe2e324 100644
--- a/bridge/src/android/view/ViewRootImpl_Accessor.java
+++ b/bridge/src/android/view/ViewRootImpl_Accessor.java
@@ -17,10 +17,17 @@
package android.view;
/**
- * Accessor to allow layoutlib to call {@link ViewRootImpl#dispatchApplyInsets} directly.
+ * Accessor to allow layoutlib to call {@link ViewRootImpl} methods directly.
*/
public class ViewRootImpl_Accessor {
public static void dispatchApplyInsets(ViewRootImpl viewRoot, View host) {
viewRoot.dispatchApplyInsets(host);
}
+
+ public static void setChild(ViewRootImpl viewRoot, View child) {
+ viewRoot.mView = child;
+ child.assignParent(viewRoot);
+ viewRoot.mWidth = child.getWidth();
+ viewRoot.mHeight = child.getHeight();
+ }
}
diff --git a/bridge/src/android/view/ViewRootImpl_Delegate.java b/bridge/src/android/view/ViewRootImpl_Delegate.java
index 14b84ef5b2..660ce47057 100644
--- a/bridge/src/android/view/ViewRootImpl_Delegate.java
+++ b/bridge/src/android/view/ViewRootImpl_Delegate.java
@@ -28,7 +28,8 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
public class ViewRootImpl_Delegate {
@LayoutlibDelegate
- /*package*/ static boolean isInTouchMode() {
- return false; // this allows displaying selection.
+ /*package*/ static boolean performHapticFeedback(ViewRootImpl thisViewRoot, int effectId,
+ boolean always) {
+ return false;
}
}
diff --git a/bridge/src/android/view/WindowManagerImpl.java b/bridge/src/android/view/WindowManagerImpl.java
index dabeda3584..e8b9fcf802 100644
--- a/bridge/src/android/view/WindowManagerImpl.java
+++ b/bridge/src/android/view/WindowManagerImpl.java
@@ -16,6 +16,7 @@
package android.view;
import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -27,6 +28,8 @@ import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
@@ -35,6 +38,7 @@ import android.widget.FrameLayout;
import com.android.ide.common.rendering.api.ILayoutLog;
import com.android.internal.R;
+import com.android.internal.policy.DecorView;
import com.android.layoutlib.bridge.Bridge;
public class WindowManagerImpl implements WindowManager {
@@ -103,10 +107,14 @@ public class WindowManagerImpl implements WindowManager {
FrameLayout layout = new FrameLayout(mContext) {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
+ float offsetX = - getX();
+ float offsetY = - getY();
View baseRootParent = (View)mBaseRootView.getParent();
if (baseRootParent != null) {
- ev.offsetLocation(-baseRootParent.getX(), -baseRootParent.getY());
+ offsetX -= baseRootParent.getX();
+ offsetY -= baseRootParent.getY();
}
+ ev.offsetLocation(offsetX, offsetY);
return super.dispatchTouchEvent(ev);
}
@@ -143,8 +151,12 @@ public class WindowManagerImpl implements WindowManager {
event.offsetLocation(-arg0.getX(), -arg0.getY());
return arg0.dispatchTouchEvent(event);
});
- mBaseRootView.addView(layout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
+ int layoutMode = WRAP_CONTENT;
+ if (arg0 instanceof DecorView) {
+ // DecorView background should cover the entire screen
+ layoutMode = MATCH_PARENT;
+ }
+ mBaseRootView.addView(layout, new FrameLayout.LayoutParams(layoutMode, layoutMode));
mCurrentRootView = layout;
}
@@ -154,6 +166,16 @@ public class WindowManagerImpl implements WindowManager {
frameLayoutParams.gravity = params.gravity;
if ((params.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
mCurrentRootView.setBackgroundColor(Color.argb(params.dimAmount, 0, 0, 0));
+ } else {
+ int backgroundColor = Color.WHITE;
+ Drawable background = mBaseRootView.getBackground();
+ if (background == null) {
+ background = mBaseRootView.getRootView().getBackground();
+ }
+ if (background instanceof ColorDrawable) {
+ backgroundColor = ((ColorDrawable) background).getColor();
+ }
+ mCurrentRootView.setBackgroundColor(backgroundColor);
}
}
mCurrentRootView.addView(arg0, frameLayoutParams);
@@ -171,8 +193,25 @@ public class WindowManagerImpl implements WindowManager {
}
@Override
- public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
- // pass
+ public void updateViewLayout(View view, android.view.ViewGroup.LayoutParams params) {
+ if (view == null) {
+ throw new IllegalArgumentException("view must not be null");
+ }
+ if (!(params instanceof WindowManager.LayoutParams)) {
+ throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+ }
+
+ WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
+ FrameLayout.LayoutParams lparams = new FrameLayout.LayoutParams(params);
+ lparams.gravity = wparams.gravity;
+ view.setLayoutParams(lparams);
+ if (mCurrentRootView != null) {
+ Rect bounds = new Rect();
+ mBaseRootView.getBoundsOnScreen(bounds);
+ mCurrentRootView.setX(wparams.x - bounds.left);
+ mCurrentRootView.setY(wparams.y - bounds.top);
+ mCurrentRootView.setElevation(view.getElevation());
+ }
}
@@ -235,7 +274,7 @@ public class WindowManagerImpl implements WindowManager {
final InsetsState insetsState = new InsetsState();
final boolean alwaysConsumeSystemBars =
WindowManagerGlobal.getWindowManagerService().getWindowInsets(
- new WindowManager.LayoutParams(), mContext.getDisplayId(), insetsState);
+ mContext.getDisplayId(), null /* token */, insetsState);
final Configuration config = mContext.getResources().getConfiguration();
final boolean isScreenRound = config.isScreenRound();
final int windowingMode = config.windowConfiguration.getWindowingMode();
diff --git a/bridge/src/android/view/accessibility/AccessibilityManager.java b/bridge/src/android/view/accessibility/AccessibilityManager.java
deleted file mode 100644
index 4454f29e07..0000000000
--- a/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2009 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.view.accessibility;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.accessibilityservice.AccessibilityServiceInfo.FeedbackType;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.os.Handler;
-import android.view.IWindow;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent.EventType;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * System level service that serves as an event dispatch for {@link AccessibilityEvent}s.
- * Such events are generated when something notable happens in the user interface,
- * for example an {@link android.app.Activity} starts, the focus or selection of a
- * {@link android.view.View} changes etc. Parties interested in handling accessibility
- * events implement and register an accessibility service which extends
- * {@code android.accessibilityservice.AccessibilityService}.
- *
- * @see AccessibilityEvent
- * @see android.content.Context#getSystemService
- */
-@SuppressWarnings("UnusedDeclaration")
-public final class AccessibilityManager {
-
- private static AccessibilityManager sInstance = new AccessibilityManager(null, null, 0);
-
-
- /**
- * Listener for the accessibility state.
- */
- public interface AccessibilityStateChangeListener {
-
- /**
- * Called back on change in the accessibility state.
- *
- * @param enabled Whether accessibility is enabled.
- */
- public void onAccessibilityStateChanged(boolean enabled);
- }
-
- /**
- * Listener for the system touch exploration state. To listen for changes to
- * the touch exploration state on the device, implement this interface and
- * register it with the system by calling
- * {@link #addTouchExplorationStateChangeListener}.
- */
- public interface TouchExplorationStateChangeListener {
-
- /**
- * Called when the touch exploration enabled state changes.
- *
- * @param enabled Whether touch exploration is enabled.
- */
- public void onTouchExplorationStateChanged(boolean enabled);
- }
-
- /**
- * Listener for the system high text contrast state. To listen for changes to
- * the high text contrast state on the device, implement this interface and
- * register it with the system by calling
- * {@link #addHighTextContrastStateChangeListener}.
- */
- public interface HighTextContrastChangeListener {
-
- /**
- * Called when the high text contrast enabled state changes.
- *
- * @param enabled Whether high text contrast is enabled.
- */
- public void onHighTextContrastStateChanged(boolean enabled);
- }
-
- /**
- * Policy to inject behavior into the accessibility manager.
- *
- * @hide
- */
- public interface AccessibilityPolicy {
- /**
- * Checks whether accessibility is enabled.
- *
- * @param accessibilityEnabled Whether the accessibility layer is enabled.
- * @return whether accessibility is enabled.
- */
- boolean isEnabled(boolean accessibilityEnabled);
-
- /**
- * Notifies the policy for an accessibility event.
- *
- * @param event The event.
- * @param accessibilityEnabled Whether the accessibility layer is enabled.
- * @param relevantEventTypes The events relevant events.
- * @return The event to dispatch or null.
- */
- @Nullable AccessibilityEvent onAccessibilityEvent(@NonNull AccessibilityEvent event,
- boolean accessibilityEnabled, @EventType int relevantEventTypes);
-
- /**
- * Gets the list of relevant events.
- *
- * @param relevantEventTypes The relevant events.
- * @return The relevant events to report.
- */
- @EventType int getRelevantEventTypes(@EventType int relevantEventTypes);
-
- /**
- * Gets the list of installed services to report.
- *
- * @param installedService The installed services.
- * @return The services to report.
- */
- @NonNull List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList(
- @Nullable List<AccessibilityServiceInfo> installedService);
-
- /**
- * Gets the list of enabled accessibility services.
- *
- * @param feedbackTypeFlags The feedback type to query for.
- * @param enabledService The enabled services.
- * @return The services to report.
- */
- @Nullable List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
- @FeedbackType int feedbackTypeFlags,
- @Nullable List<AccessibilityServiceInfo> enabledService);
- }
-
- private final IAccessibilityManagerClient.Stub mClient =
- new IAccessibilityManagerClient.Stub() {
- public void setState(int state) {
- }
-
- public void notifyServicesStateChanged(long updatedUiTimeout) {
- }
-
- public void setRelevantEventTypes(int eventTypes) {
- }
-
- public void setFocusAppearance(int strokeWidth, int color) {
- }
- };
-
- /**
- * Get an AccessibilityManager instance (create one if necessary).
- *
- */
- public static AccessibilityManager getInstance(Context context) {
- return sInstance;
- }
-
- /**
- * Create an instance.
- *
- * @param context A {@link Context}.
- */
- public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
- }
-
- public IAccessibilityManagerClient getClient() {
- return mClient;
- }
-
- /**
- * Returns if the {@link AccessibilityManager} is enabled.
- *
- * @return True if this {@link AccessibilityManager} is enabled, false otherwise.
- */
- public boolean isEnabled() {
- return false;
- }
-
- /**
- * Returns if the touch exploration in the system is enabled.
- *
- * @return True if touch exploration is enabled, false otherwise.
- */
- public boolean isTouchExplorationEnabled() {
- return true;
- }
-
- /**
- * Returns if the high text contrast in the system is enabled.
- * <p>
- * <strong>Note:</strong> You need to query this only if you application is
- * doing its own rendering and does not rely on the platform rendering pipeline.
- * </p>
- *
- */
- public boolean isHighTextContrastEnabled() {
- return false;
- }
-
- /**
- * Sends an {@link AccessibilityEvent}.
- */
- public void sendAccessibilityEvent(AccessibilityEvent event) {
- }
-
- /**
- * Returns whether there are observers registered for this event type. If
- * this method returns false you shuold not generate events of this type
- * to conserve resources.
- *
- * @param type The event type.
- * @return Whether the event is being observed.
- */
- public boolean isObservedEventType(@AccessibilityEvent.EventType int type) {
- return false;
- }
-
- /**
- * Requests interruption of the accessibility feedback from all accessibility services.
- */
- public void interrupt() {
- }
-
- /**
- * Returns the {@link ServiceInfo}s of the installed accessibility services.
- *
- * @return An unmodifiable list with {@link ServiceInfo}s.
- */
- @Deprecated
- public List<ServiceInfo> getAccessibilityServiceList() {
- return Collections.emptyList();
- }
-
- public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
- return Collections.emptyList();
- }
-
- /**
- * Returns the {@link AccessibilityServiceInfo}s of the enabled accessibility services
- * for a given feedback type.
- *
- * @param feedbackTypeFlags The feedback type flags.
- * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
- *
- * @see AccessibilityServiceInfo#FEEDBACK_AUDIBLE
- * @see AccessibilityServiceInfo#FEEDBACK_GENERIC
- * @see AccessibilityServiceInfo#FEEDBACK_HAPTIC
- * @see AccessibilityServiceInfo#FEEDBACK_SPOKEN
- * @see AccessibilityServiceInfo#FEEDBACK_VISUAL
- */
- public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
- int feedbackTypeFlags) {
- return Collections.emptyList();
- }
-
- /**
- * Registers an {@link AccessibilityStateChangeListener} for changes in
- * the global accessibility state of the system.
- *
- * @param listener The listener.
- * @return True if successfully registered.
- */
- public boolean addAccessibilityStateChangeListener(
- AccessibilityStateChangeListener listener) {
- return true;
- }
-
- /**
- * Registers an {@link AccessibilityStateChangeListener} for changes in
- * the global accessibility state of the system. If the listener has already been registered,
- * the handler used to call it back is updated.
- *
- * @param listener The listener.
- * @param handler The handler on which the listener should be called back, or {@code null}
- * for a callback on the process's main handler.
- */
- public void addAccessibilityStateChangeListener(
- @NonNull AccessibilityStateChangeListener listener, @Nullable Handler handler) {}
-
- public boolean removeAccessibilityStateChangeListener(
- AccessibilityStateChangeListener listener) {
- return true;
- }
-
- /**
- * Registers a {@link TouchExplorationStateChangeListener} for changes in
- * the global touch exploration state of the system.
- *
- * @param listener The listener.
- * @return True if successfully registered.
- */
- public boolean addTouchExplorationStateChangeListener(
- @NonNull TouchExplorationStateChangeListener listener) {
- return true;
- }
-
- /**
- * Registers an {@link TouchExplorationStateChangeListener} for changes in
- * the global touch exploration state of the system. If the listener has already been
- * registered, the handler used to call it back is updated.
- *
- * @param listener The listener.
- * @param handler The handler on which the listener should be called back, or {@code null}
- * for a callback on the process's main handler.
- */
- public void addTouchExplorationStateChangeListener(
- @NonNull TouchExplorationStateChangeListener listener, @Nullable Handler handler) {}
-
- /**
- * Unregisters a {@link TouchExplorationStateChangeListener}.
- *
- * @param listener The listener.
- * @return True if successfully unregistered.
- */
- public boolean removeTouchExplorationStateChangeListener(
- @NonNull TouchExplorationStateChangeListener listener) {
- return true;
- }
-
- /**
- * Registers a {@link HighTextContrastChangeListener} for changes in
- * the global high text contrast state of the system.
- *
- * @param listener The listener.
- *
- * @hide
- */
- public void addHighTextContrastStateChangeListener(
- @NonNull HighTextContrastChangeListener listener, @Nullable Handler handler) {}
-
- /**
- * Unregisters a {@link HighTextContrastChangeListener}.
- *
- * @param listener The listener.
- *
- * @hide
- */
- public void removeHighTextContrastStateChangeListener(
- @NonNull HighTextContrastChangeListener listener) {}
-
- /**
- * Sets the current state and notifies listeners, if necessary.
- *
- * @param stateFlags The state flags.
- */
- private void setStateLocked(int stateFlags) {
- }
-
- public int addAccessibilityInteractionConnection(IWindow windowToken,
- IAccessibilityInteractionConnection connection) {
- return View.NO_ID;
- }
-
- public void removeAccessibilityInteractionConnection(IWindow windowToken) {
- }
-
-}
diff --git a/bridge/src/android/view/accessibility/AccessibilityNodeIdManager.java b/bridge/src/android/view/accessibility/AccessibilityNodeIdManager.java
deleted file mode 100644
index e37711779c..0000000000
--- a/bridge/src/android/view/accessibility/AccessibilityNodeIdManager.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2019 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.view.accessibility;
-
-import android.view.View;
-
-/**
- * Class that replaces the original AccessibilityNodeIdManager with a no-op version. This avoids
- * the accidental leaking of views referenced by the originalin layoutlib.
- */
-public final class AccessibilityNodeIdManager {
- private static AccessibilityNodeIdManager sIdManager = new AccessibilityNodeIdManager();
-
-
- public static synchronized AccessibilityNodeIdManager getInstance() {
- return sIdManager;
- }
-
- private AccessibilityNodeIdManager() {
- }
-
- /**
- * Register view to be kept track of by the accessibility system.
- * Must be paired with unregisterView, otherwise this will leak.
- * @param view The view to be registered.
- * @param id The accessibilityViewId of the view.
- */
- public void registerViewWithId(View view, int id) {
- }
-
- /**
- * Unregister view, accessibility won't keep track of this view after this call.
- * @param id The id returned from registerView when the view as first associated.
- */
- public void unregisterViewWithId(int id) {
- }
-
- /**
- * Accessibility uses this to find the view in the hierarchy.
- * @param id The accessibility view id.
- * @return The view.
- */
- public View findView(int id) {
- return null;
- }
-}
-
diff --git a/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java b/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
index 5dd25b4448..61d90702f8 100644
--- a/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
+++ b/bridge/src/android/view/inputmethod/InputMethodManager_Delegate.java
@@ -18,6 +18,10 @@ package android.view.inputmethod;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import android.os.IBinder;
+import android.os.ResultReceiver;
+import android.view.View;
+
/**
* Delegate used to provide new implementation of a select few methods of {@link InputMethodManager}
@@ -34,4 +38,40 @@ public class InputMethodManager_Delegate {
/*package*/ static boolean isInEditMode() {
return true;
}
+
+
+ @LayoutlibDelegate
+ /*package*/ static boolean showSoftInput(InputMethodManager thisManager, View view, int flags) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean showSoftInput(InputMethodManager thisManager, View view, int flags,
+ ResultReceiver resultReceiver) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/static boolean showSoftInput(InputMethodManager thisManager, View view,
+ ImeTracker.Token statsToken, int flags, ResultReceiver resultReceiver, int reason) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean hideSoftInputFromWindow(InputMethodManager thisManager,
+ IBinder windowToken, int flags) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean hideSoftInputFromWindow(InputMethodManager thisManager,
+ IBinder windowToken, int flags, ResultReceiver resultReceiver) {
+ return false;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean hideSoftInputFromWindow(InputMethodManager thisManager,
+ IBinder windowToken, int flags, ResultReceiver resultReceiver, int reason) {
+ return false;
+ }
}
diff --git a/bridge/src/android/widget/AbsListView_Delegate.java b/bridge/src/android/widget/AbsListView_Delegate.java
new file mode 100644
index 0000000000..a8321b7c57
--- /dev/null
+++ b/bridge/src/android/widget/AbsListView_Delegate.java
@@ -0,0 +1,24 @@
+/*
+ * 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.widget;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+public class AbsListView_Delegate {
+ @LayoutlibDelegate
+ public static void setupDeviceConfigProperties() { }
+}
diff --git a/bridge/src/android/widget/Magnifier_Delegate.java b/bridge/src/android/widget/Magnifier_Delegate.java
new file mode 100644
index 0000000000..cb18a5bb70
--- /dev/null
+++ b/bridge/src/android/widget/Magnifier_Delegate.java
@@ -0,0 +1,34 @@
+/*
+ * 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.widget;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+public class Magnifier_Delegate {
+ @LayoutlibDelegate
+ static void show(Magnifier thisMagnifier, float sourceCenterX, float sourceCenterY) {
+ // Do nothing, the original method tries to create a Surface, which is not supported in
+ // layoutlib.
+ }
+
+ @LayoutlibDelegate
+ static void show(Magnifier thisMagnifier, float sourceCenterX, float sourceCenterY,
+ float magnifierCenterX, float magnifierCenterY) {
+ // Do nothing, the original method tries to create a Surface, which is not supported in
+ // layoutlib.
+ }
+}
diff --git a/bridge/src/com/android/layoutlib/bridge/Bridge.java b/bridge/src/com/android/layoutlib/bridge/Bridge.java
index be8c6177ce..3c62193dad 100644
--- a/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -43,15 +43,20 @@ import org.xmlpull.v1.XmlPullParser;
import android.content.res.BridgeAssetManager;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.graphics.Typeface;
-import android.graphics.Typeface_Builder_Delegate;
import android.graphics.fonts.SystemFonts_Delegate;
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
import android.icu.util.ULocale;
import android.os.Looper;
import android.os.Looper_Accessor;
import android.os.SystemProperties;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.Gravity;
+import android.view.InputDevice;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -75,6 +80,7 @@ import libcore.io.MemoryMappedFile_Delegate;
import static android.graphics.Typeface.DEFAULT_FAMILY;
import static android.graphics.Typeface.RESOLVE_BY_FONT_TABLE;
+
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
/**
@@ -109,7 +115,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
* Reverse map compared to sRMap, resource type -> (resource name -> id).
* This is for com.android.internal.R.
*/
- private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<>(ResourceType.class);
+ private final static Map<ResourceType, Map<String, Integer>> sRevRMap = new EnumMap<>(
+ ResourceType.class);
// framework resources are defined as 0x01XX#### where XX is the resource type (layout,
// drawable, etc...). Using FF as the type allows for 255 resource types before we get a
@@ -120,8 +127,14 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
new WeakHashMap<>();
+ private final static Map<Object, Map<String, SoftReference<Rect>>> sProjectBitmapPaddingCache =
+ new WeakHashMap<>();
+
private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache = new HashMap<>();
+ private final static Map<String, SoftReference<Rect>> sFrameworkBitmapPaddingCache =
+ new HashMap<>();
+
private static Map<String, Map<String, Integer>> sEnumValueMap;
private static Map<String, String> sPlatformProperties;
@@ -157,6 +170,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
private static ILayoutLog sCurrentLog = sDefaultLog;
private static String sIcuDataPath;
+ private static String[] sKeyboardPaths;
private static final String[] LINUX_NATIVE_LIBRARIES = {"libandroid_runtime.so"};
private static final String[] MAC_NATIVE_LIBRARIES = {"libandroid_runtime.dylib"};
@@ -164,15 +178,17 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
{"libicuuc_stubdata.dll", "libicuuc-host.dll", "libandroid_runtime.dll"};
@Override
- public boolean init(Map<String,String> platformProperties,
+ public boolean init(Map<String, String> platformProperties,
File fontLocation,
String nativeLibPath,
String icuDataPath,
+ String[] keyboardPaths,
Map<String, Map<String, Integer>> enumValueMap,
ILayoutLog log) {
sPlatformProperties = platformProperties;
sEnumValueMap = enumValueMap;
sIcuDataPath = icuDataPath;
+ sKeyboardPaths = keyboardPaths;
sCurrentLog = log;
if (!loadNativeLibrariesIfNeeded(log, nativeLibPath)) {
@@ -409,6 +425,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
Typeface.sDynamicTypefaceCache.evictAll();
}
sProjectBitmapCache.clear();
+ sProjectBitmapPaddingCache.clear();
return true;
}
@@ -419,8 +436,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
* <p/>
* If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE},
* this method will only inflate the layout but will NOT render it.
+ *
* @param params the {@link SessionParams} object with all the information necessary to create
- * the scene.
+ * the scene.
* @return a new {@link RenderSession} object that contains the result of the layout.
* @since 5
*/
@@ -489,6 +507,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
public void clearResourceCaches(Object projectKey) {
if (projectKey != null) {
sProjectBitmapCache.remove(projectKey);
+ sProjectBitmapPaddingCache.remove(projectKey);
}
}
@@ -500,7 +519,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
@Override
public Result getViewParent(Object viewObject) {
if (viewObject instanceof View) {
- return Status.SUCCESS.createResult(((View)viewObject).getParent());
+ return Status.SUCCESS.createResult(((View) viewObject).getParent());
}
throw new IllegalArgumentException("viewObject is not a View");
@@ -637,7 +656,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
/**
* Returns the bitmap for a specific path, from a specific project cache, or from the
* framework cache.
- * @param value the path of the bitmap
+ *
+ * @param value the path of the bitmap
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached Bitmap or null if not found.
*/
@@ -661,9 +681,37 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
}
/**
+ * Returns the padding for the bitmap with a specific path, from a specific project cache, or
+ * from the framework cache.
+ *
+ * @param value the path of the bitmap
+ * @param projectKey the key of the project, or null to query the framework cache.
+ * @return the cached padding or null if not found.
+ */
+ public static Rect getCachedBitmapPadding(String value, Object projectKey) {
+ if (projectKey != null) {
+ Map<String, SoftReference<Rect>> map = sProjectBitmapPaddingCache.get(projectKey);
+ if (map != null) {
+ SoftReference<Rect> ref = map.get(value);
+ if (ref != null) {
+ return ref.get();
+ }
+ }
+ } else {
+ SoftReference<Rect> ref = sFrameworkBitmapPaddingCache.get(value);
+ if (ref != null) {
+ return ref.get();
+ }
+ }
+
+ return null;
+ }
+
+ /**
* Sets a bitmap in a project cache or in the framework cache.
- * @param value the path of the bitmap
- * @param bmp the Bitmap object
+ *
+ * @param value the path of the bitmap
+ * @param bmp the Bitmap object
* @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
@@ -678,6 +726,24 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
}
/**
+ * Sets the padding for a bitmap in a project cache or in the framework cache.
+ *
+ * @param value the path of the bitmap
+ * @param padding the padding of that bitmap
+ * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
+ */
+ public static void setCachedBitmapPadding(String value, Rect padding, Object projectKey) {
+ if (projectKey != null) {
+ Map<String, SoftReference<Rect>> map =
+ sProjectBitmapPaddingCache.computeIfAbsent(projectKey, k -> new HashMap<>());
+
+ map.put(value, new SoftReference<>(padding));
+ } else {
+ sFrameworkBitmapPaddingCache.put(value, new SoftReference<>(padding));
+ }
+ }
+
+ /**
* This is called by the native layoutlib loader.
*/
@SuppressWarnings("unused")
@@ -685,6 +751,29 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
return sIcuDataPath;
}
+ /**
+ * This is called by the native layoutlib loader.
+ */
+ @SuppressWarnings("unused")
+ private static void setInputManager(InputDevice[] devices) {
+ int[] ids = Arrays.stream(devices).mapToInt(InputDevice::getId).toArray();
+ SparseArray<InputDevice> idToDevice = new SparseArray<>(devices.length);
+ for (InputDevice device : devices) {
+ idToDevice.append(device.getId(), device);
+ }
+ InputManagerGlobal.sInstance = new InputManagerGlobal(new IInputManager.Default() {
+ @Override
+ public int[] getInputDeviceIds() {
+ return ids;
+ }
+
+ @Override
+ public InputDevice getInputDevice(int deviceId) {
+ return idToDevice.get(deviceId);
+ }
+ });
+ }
+
private static boolean sJniLibLoadAttempted;
private static boolean sJniLibLoaded;
@@ -693,8 +782,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
if (!sJniLibLoadAttempted) {
try {
loadNativeLibraries(nativeLibDir);
- }
- catch (Throwable t) {
+ } catch (Throwable t) {
log.error(ILayoutLog.TAG_BROKEN, "Native layoutlib failed to load", t, null, null);
}
}
@@ -715,12 +803,12 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
System.setProperty("icu.data.path", Bridge.getIcuDataPath());
System.setProperty("use_bridge_for_logging", "true");
System.setProperty("register_properties_during_load", "true");
+ System.setProperty("keyboard_paths", String.join(",", sKeyboardPaths));
for (String library : getNativeLibraries()) {
String path = new File(nativeLibDir, library).getAbsolutePath();
System.load(path);
}
- }
- finally {
+ } finally {
sJniLibLoadAttempted = true;
}
sJniLibLoaded = true;
@@ -741,7 +829,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
public void clearFontCache(String path) {
if (SystemFonts_Delegate.sIsTypefaceInitialized) {
final String key =
- Typeface_Builder_Delegate.createAssetUid(BridgeAssetManager.initSystem(), path,
+ Typeface.Builder.createAssetUid(BridgeAssetManager.initSystem(), path,
0, null, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE, DEFAULT_FAMILY);
Typeface.sDynamicTypefaceCache.remove(key);
}
diff --git a/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
index d95c5088c9..82bbe1013e 100644
--- a/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ b/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
@@ -56,4 +56,7 @@ public class BridgeConstants {
public static final String ATTR_LIST_ITEM = "listitem";
public static final String ATTR_OPEN_DRAWER = "openDrawer";
public static final String ATTR_ITEM_COUNT = "itemCount";
+ public static final String ATTR_LIST_HEADER = "listheader";
+ public static final String ATTR_LIST_FOOTER = "listfooter";
+ public static final String ATTR_NUM_COLUMNS = "numColumns";
}
diff --git a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index 3d1b2c7bcc..bdd3a227f4 100644
--- a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -31,8 +31,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Handler_Delegate;
import android.os.SystemClock_Delegate;
-import android.view.Choreographer;
-import android.view.DisplayEventReceiver_VsyncEventData_Accessor;
import android.view.MotionEvent;
import java.awt.image.BufferedImage;
@@ -195,6 +193,10 @@ public class BridgeRenderSession extends RenderSession {
});
}
+ public void triggerKeyEvent(java.awt.event.KeyEvent event) {
+ execute(() -> mSession.dispatchKeyEvent(event, System_Delegate.nanoTime()));
+ }
+
@Override
public void execute(Runnable r) {
if (mSession != null) {
diff --git a/bridge/src/com/android/layoutlib/bridge/android/ApplicationContext.java b/bridge/src/com/android/layoutlib/bridge/android/ApplicationContext.java
new file mode 100644
index 0000000000..8e14030d6f
--- /dev/null
+++ b/bridge/src/com/android/layoutlib/bridge/android/ApplicationContext.java
@@ -0,0 +1,1323 @@
+/*
+ * 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 com.android.layoutlib.bridge.android;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.ComponentCallbacks;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.IntentSender.SendIntentException;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
+import android.database.DatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Executor;
+
+public class ApplicationContext extends Context {
+ private final WeakReference<Context> mContextRef;
+
+ public ApplicationContext(Context context) {
+ mContextRef = new WeakReference<>(context);
+ }
+
+ @Override
+ public AssetManager getAssets() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getAssets();
+ }
+ return null;
+ }
+
+ @Override
+ public Resources getResources() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getResources();
+ }
+ return null;
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getPackageManager();
+ }
+ return null;
+ }
+
+ @Override
+ public ContentResolver getContentResolver() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getContentResolver();
+ }
+ return null;
+ }
+
+ @Override
+ public Looper getMainLooper() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getMainLooper();
+ }
+ return null;
+ }
+
+ @Override
+ public Context getApplicationContext() {
+ return this;
+ }
+
+ @Override
+ public void setTheme(int resid) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.setTheme(resid);
+ }
+ }
+
+ @Override
+ public Theme getTheme() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getTheme();
+ }
+ return null;
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getClassLoader();
+ }
+ return null;
+ }
+
+ @Override
+ public String getPackageName() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getPackageName();
+ }
+ return null;
+ }
+
+ @Override
+ public String getBasePackageName() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getBasePackageName();
+ }
+ return null;
+ }
+
+ @Override
+ public ApplicationInfo getApplicationInfo() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getApplicationInfo();
+ }
+ return null;
+ }
+
+ @Override
+ public String getPackageResourcePath() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getPackageResourcePath();
+ }
+ return null;
+ }
+
+ @Override
+ public String getPackageCodePath() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getPackageCodePath();
+ }
+ return null;
+ }
+
+ @Override
+ public SharedPreferences getSharedPreferences(String name, int mode) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getSharedPreferences(name, mode);
+ }
+ return null;
+ }
+
+ @Override
+ public SharedPreferences getSharedPreferences(File file, int mode) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getSharedPreferences(file, mode);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.moveSharedPreferencesFrom(sourceContext, name);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean deleteSharedPreferences(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.deleteSharedPreferences(name);
+ }
+ return false;
+ }
+
+ @Override
+ public void reloadSharedPreferences() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.reloadSharedPreferences();
+ }
+ }
+
+ @Override
+ public FileInputStream openFileInput(String name) throws FileNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.openFileInput(name);
+ }
+ return null;
+ }
+
+ @Override
+ public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.openFileOutput(name, mode);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean deleteFile(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.deleteFile(name);
+ }
+ return false;
+ }
+
+ @Override
+ public File getFileStreamPath(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getFileStreamPath(name);
+ }
+ return null;
+ }
+
+ @Override
+ public File getSharedPreferencesPath(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getSharedPreferencesPath(name);
+ }
+ return null;
+ }
+
+ @Override
+ public File getDataDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDataDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getFilesDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getFilesDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getNoBackupFilesDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getNoBackupFilesDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getExternalFilesDir(String type) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getExternalFilesDir(type);
+ }
+ return null;
+ }
+
+ @Override
+ public File[] getExternalFilesDirs(String type) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getExternalFilesDirs(type);
+ }
+ return new File[0];
+ }
+
+ @Override
+ public File getObbDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getObbDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File[] getObbDirs() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getObbDirs();
+ }
+ return new File[0];
+ }
+
+ @Override
+ public File getCacheDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getCacheDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getCodeCacheDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getCodeCacheDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getExternalCacheDir() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getExternalCacheDir();
+ }
+ return null;
+ }
+
+ @Override
+ public File getPreloadsFileCache() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getPreloadsFileCache();
+ }
+ return null;
+ }
+
+ @Override
+ public File[] getExternalCacheDirs() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getExternalCacheDirs();
+ }
+ return new File[0];
+ }
+
+ @Override
+ public File[] getExternalMediaDirs() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getExternalMediaDirs();
+ }
+ return new File[0];
+ }
+
+ @Override
+ public String[] fileList() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.fileList();
+ }
+ return new String[0];
+ }
+
+ @Override
+ public File getDir(String name, int mode) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDir(name, mode);
+ }
+ return null;
+ }
+
+ @Override
+ public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.openOrCreateDatabase(name, mode, factory);
+ }
+ return null;
+ }
+
+ @Override
+ public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
+ DatabaseErrorHandler errorHandler) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.openOrCreateDatabase(name, mode, factory);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean moveDatabaseFrom(Context sourceContext, String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.moveDatabaseFrom(sourceContext, name);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean deleteDatabase(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.deleteDatabase(name);
+ }
+ return false;
+ }
+
+ @Override
+ public File getDatabasePath(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDatabasePath(name);
+ }
+ return null;
+ }
+
+ @Override
+ public String[] databaseList() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.databaseList();
+ }
+ return new String[0];
+ }
+
+ @Override
+ public Drawable getWallpaper() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getWallpaper();
+ }
+ return null;
+ }
+
+ @Override
+ public Drawable peekWallpaper() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.peekWallpaper();
+ }
+ return null;
+ }
+
+ @Override
+ public int getWallpaperDesiredMinimumWidth() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getWallpaperDesiredMinimumWidth();
+ }
+ return 0;
+ }
+
+ @Override
+ public int getWallpaperDesiredMinimumHeight() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getWallpaperDesiredMinimumHeight();
+ }
+ return 0;
+ }
+
+ @Override
+ public void setWallpaper(Bitmap bitmap) throws IOException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.setWallpaper(bitmap);
+ }
+ }
+
+ @Override
+ public void setWallpaper(InputStream data) throws IOException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.setWallpaper(data);
+ }
+ }
+
+ @Override
+ public void clearWallpaper() throws IOException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.clearWallpaper();
+ }
+ }
+
+ @Override
+ public void startActivity(Intent intent) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startActivity(intent);
+ }
+ }
+
+ @Override
+ public void startActivity(Intent intent, Bundle options) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startActivity(intent, options);
+ }
+ }
+
+ @Override
+ public void startActivities(Intent[] intents) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startActivities(intents);
+ }
+ }
+
+ @Override
+ public void startActivities(Intent[] intents, Bundle options) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startActivities(intents, options);
+ }
+ }
+
+ @Override
+ public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask,
+ int flagsValues, int extraFlags) throws SendIntentException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags);
+ }
+ }
+
+ @Override
+ public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask,
+ int flagsValues, int extraFlags, Bundle options) throws SendIntentException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, options);
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcast(intent);
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent, String receiverPermission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcast(intent, receiverPermission);
+ }
+ }
+
+ @Override
+ public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+ String[] receiverPermissions) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions);
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcast(intent, receiverPermission, options);
+ }
+ }
+
+ @Override
+ public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcast(intent, receiverPermission, appOp);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcast(intent, receiverPermission);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastAsUser(intent, user);
+ }
+ }
+
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastAsUser(intent, user, receiverPermission);
+ }
+ }
+
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
+ Bundle options) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastAsUser(intent, user, receiverPermission, options);
+ }
+ }
+
+ @Override
+ public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
+ int appOp) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
+ int initialCode, String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void sendStickyBroadcast(Intent intent) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendStickyBroadcast(intent);
+ }
+ }
+
+ @Override
+ public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void removeStickyBroadcast(Intent intent) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.removeStickyBroadcast(intent);
+ }
+ }
+
+ @Override
+ public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendStickyBroadcastAsUser(intent, user);
+ }
+ }
+
+ @Override
+ public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendStickyBroadcastAsUser(intent, user, options);
+ }
+ }
+
+ @Override
+ public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
+ String initialData, Bundle initialExtras) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, initialData, initialExtras);
+ }
+ }
+
+ @Override
+ public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.removeStickyBroadcastAsUser(intent, user);
+ }
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiver(receiver, filter);
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiver(receiver, filter, flags);
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiver(receiver, filter, broadcastPermission, scheduler);
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+ String broadcastPermission, Handler scheduler, int flags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiver(receiver, filter, broadcastPermission, scheduler, flags);
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+ IntentFilter filter, String broadcastPermission, Handler scheduler) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler);
+ }
+ return null;
+ }
+
+ @Override
+ public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+ IntentFilter filter, String broadcastPermission, Handler scheduler, int flags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.registerReceiverAsUser(receiver, user, filter, broadcastPermission, scheduler, flags);
+ }
+ return null;
+ }
+
+ @Override
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.unregisterReceiver(receiver);
+ }
+ }
+
+ @Override
+ public ComponentName startService(Intent service) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.startService(service);
+ }
+ return null;
+ }
+
+ @Override
+ public ComponentName startForegroundService(Intent service) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.startForegroundService(service);
+ }
+ return null;
+ }
+
+ @Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.startForegroundServiceAsUser(service, user);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean stopService(Intent service) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.stopService(service);
+ }
+ return false;
+ }
+
+ @Override
+ public ComponentName startServiceAsUser(Intent service, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.startServiceAsUser(service, user);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean stopServiceAsUser(Intent service, UserHandle user) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.stopServiceAsUser(service, user);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean bindService(Intent service, ServiceConnection conn, int flags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.bindService(service, conn, flags);
+ }
+ return false;
+ }
+
+ @Override
+ public void unbindService(ServiceConnection conn) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.unbindService(conn);
+ }
+ }
+
+ @Override
+ public boolean startInstrumentation(ComponentName className, String profileFile,
+ Bundle arguments) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.startInstrumentation(className, profileFile, arguments);
+ }
+ return false;
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getSystemService(name);
+ }
+ return null;
+ }
+
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getSystemServiceName(serviceClass);
+ }
+ return null;
+ }
+
+ @Override
+ public int checkPermission(String permission, int pid, int uid) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkPermission(permission, pid, uid);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkPermission(permission, pid, uid, callerToken);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkCallingPermission(String permission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkCallingPermission(permission);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkCallingOrSelfPermission(permission);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkSelfPermission(String permission) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkSelfPermission(permission);
+ }
+ return 0;
+ }
+
+ @Override
+ public void enforcePermission(String permission, int pid, int uid, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforcePermission(permission, pid, uid, message);
+ }
+ }
+
+ @Override
+ public void enforceCallingPermission(String permission, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceCallingPermission(permission, message);
+ }
+ }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceCallingOrSelfPermission(permission, message);
+ }
+ }
+
+ @Override
+ public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.grantUriPermission(toPackage, uri, modeFlags);
+ }
+ }
+
+ @Override
+ public void revokeUriPermission(Uri uri, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.revokeUriPermission(uri, modeFlags);
+ }
+ }
+
+ @Override
+ public void revokeUriPermission(String toPackage, Uri uri, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.revokeUriPermission(toPackage, uri, modeFlags);
+ }
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkUriPermission(uri, pid, uid, modeFlags);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkUriPermission(uri, pid, uid, modeFlags, callerToken);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkCallingUriPermission(Uri uri, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkCallingUriPermission(uri, modeFlags);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkCallingOrSelfUriPermission(uri, modeFlags);
+ }
+ return 0;
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, String readPermission, String writePermission, int pid,
+ int uid, int modeFlags) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.checkUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags);
+ }
+ return 0;
+ }
+
+ @Override
+ public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceUriPermission(uri, pid, uid, modeFlags, message);
+ }
+ }
+
+ @Override
+ public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceCallingUriPermission(uri, modeFlags, message);
+ }
+ }
+
+ @Override
+ public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceCallingOrSelfUriPermission(uri, modeFlags, message);
+ }
+ }
+
+ @Override
+ public void enforceUriPermission(Uri uri, String readPermission, String writePermission,
+ int pid, int uid, int modeFlags, String message) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.enforceUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags, message);
+ }
+ }
+
+ @Override
+ public Context createPackageContext(String packageName, int flags)
+ throws NameNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createPackageContext(packageName, flags);
+ }
+ return null;
+ }
+
+ @Override
+ public Context createApplicationContext(ApplicationInfo application, int flags)
+ throws NameNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createApplicationContext(application, flags);
+ }
+ return null;
+ }
+
+ @Override
+ public Context createContextForSplit(String splitName) throws NameNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createContextForSplit(splitName);
+ }
+ return null;
+ }
+
+ @Override
+ public Context createConfigurationContext(Configuration overrideConfiguration) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createConfigurationContext(overrideConfiguration);
+ }
+ return null;
+ }
+
+ @Override
+ public Context createDisplayContext(Display display) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createDisplayContext(display);
+ }
+ return null;
+ }
+
+ @Override
+ public Context createDeviceProtectedStorageContext() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createDeviceProtectedStorageContext();
+ }
+ return null;
+ }
+
+ @Override
+ public Context createCredentialProtectedStorageContext() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createCredentialProtectedStorageContext();
+ }
+ return null;
+ }
+
+ @Override
+ public DisplayAdjustments getDisplayAdjustments(int displayId) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDisplayAdjustments(displayId);
+ }
+ return null;
+ }
+
+ @Override
+ public int getDisplayId() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDisplayId();
+ }
+ return 0;
+ }
+
+ @Override
+ public void updateDisplay(int displayId) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.updateDisplay(displayId);
+ }
+ }
+
+ @Override
+ public boolean isDeviceProtectedStorage() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.isDeviceProtectedStorage();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isCredentialProtectedStorage() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.isCredentialProtectedStorage();
+ }
+ return false;
+ }
+
+ @Override
+ public boolean canLoadUnsafeResources() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.canLoadUnsafeResources();
+ }
+ return false;
+ }
+
+ @Override
+ public String getOpPackageName() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getOpPackageName();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean bindService(Intent arg0, int arg1, Executor arg2, ServiceConnection arg3) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.bindService(arg0, arg1, arg2, arg3);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean bindIsolatedService(Intent arg0,
+ int arg1, String arg2, Executor arg3, ServiceConnection arg4) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.bindIsolatedService(arg0, arg1, arg2, arg3, arg4);
+ }
+ return false;
+ }
+
+ @Override
+ public Context createPackageContextAsUser(String arg0, int arg1, UserHandle user)
+ throws NameNotFoundException {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.createPackageContextAsUser(arg0, arg1, user);
+ }
+ return null;
+ }
+
+ @Override
+ public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.sendBroadcastMultiplePermissions(intent, receiverPermissions);
+ }
+ }
+
+ @Override
+ public void updateServiceGroup(@NonNull ServiceConnection conn, int group,
+ int importance) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.updateServiceGroup(conn, group, importance);
+ }
+ }
+
+ @Override
+ public Display getDisplay() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.getDisplay();
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isUiContext() {
+ Context context = mContextRef.get();
+ if (context != null) {
+ return context.isUiContext();
+ }
+ return true;
+ }
+
+ @Override
+ public void registerComponentCallbacks(ComponentCallbacks callback) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.registerComponentCallbacks(callback);
+ }
+ }
+
+ @Override
+ public void unregisterComponentCallbacks(ComponentCallbacks callback) {
+ Context context = mContextRef.get();
+ if (context != null) {
+ context.unregisterComponentCallbacks(callback);
+ }
+ }
+}
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 8934b122a3..a194dc5b1b 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -74,18 +74,20 @@ public final class BridgeContentProvider implements IContentProvider {
}
@Override
- public String getType(Uri arg0) throws RemoteException {
+ public String getType(AttributionSource attributionSource, Uri arg0) throws RemoteException {
// TODO Auto-generated method stub
return null;
}
@SuppressWarnings("deprecation")
@Override
- public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) {
+ public void getTypeAsync(AttributionSource attributionSource, Uri uri,
+ RemoteCallback remoteCallback) {
AsyncTask.SERIAL_EXECUTOR.execute(() -> {
try {
final Bundle bundle = new Bundle();
- bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
+ bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT,
+ getType(attributionSource, uri));
remoteCallback.sendResult(bundle);
} catch (RemoteException e) {
// Ignore
@@ -93,6 +95,26 @@ public final class BridgeContentProvider implements IContentProvider {
});
}
+
+ public String getTypeAnonymous(Uri arg0) throws RemoteException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void getTypeAnonymousAsync(Uri uri, RemoteCallback remoteCallback) {
+ AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+ try {
+ final Bundle bundle = new Bundle();
+ bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT,
+ getTypeAnonymous(uri));
+ remoteCallback.sendResult(bundle);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ });
+ }
@Override
public Uri insert(AttributionSource attributionSource, Uri arg0, ContentValues arg1,
Bundle arg2) throws RemoteException {
@@ -137,7 +159,8 @@ public final class BridgeContentProvider implements IContentProvider {
}
@Override
- public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException {
+ public String[] getStreamTypes(AttributionSource attributionSource, Uri arg0, String arg1)
+ throws RemoteException {
// TODO Auto-generated method stub
return null;
}
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 1d42d0a316..a0cf2b23b2 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -72,6 +72,7 @@ import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.hardware.display.DisplayManager;
+import android.hardware.input.InputManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.Uri;
@@ -118,7 +119,6 @@ import java.util.Map;
import java.util.concurrent.Executor;
import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
/**
* Custom implementation of Context/Activity to handle non compiled resources.
@@ -128,6 +128,8 @@ public class BridgeContext extends Context {
private static final Map<String, ResourceValue> FRAMEWORK_PATCHED_VALUES = new HashMap<>(2);
private static final Map<String, ResourceValue> FRAMEWORK_REPLACE_VALUES = new HashMap<>(3);
+ private static final int MAX_PARSER_STACK_SIZE = Integer.getInteger(
+ "layoutlib.max.parser.stack.size", 1000);
static {
FRAMEWORK_PATCHED_VALUES.put("animateFirstView",
@@ -162,7 +164,7 @@ public class BridgeContext extends Context {
private Resources mSystemResources;
private final Object mProjectKey;
private final DisplayMetrics mMetrics;
- private final RenderResources mRenderResources;
+ private final DynamicRenderResources mRenderResources;
private final Configuration mConfig;
private final ApplicationInfo mApplicationInfo;
private final LayoutlibCallback mLayoutlibCallback;
@@ -173,6 +175,7 @@ public class BridgeContext extends Context {
private final ActivityManager mActivityManager;
private final ConnectivityManager mConnectivityManager;
private final AudioManager mAudioManager;
+ private final InputManager mInputManager;
private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
@@ -194,6 +197,8 @@ public class BridgeContext extends Context {
private IBinder mBinder;
private PackageManager mPackageManager;
private Boolean mIsThemeAppCompat;
+ private boolean mUseThemedIcon;
+ private Context mApplicationContext;
private final ResourceNamespace mAppCompatNamespace;
private final Map<Key<?>, Object> mUserData = new HashMap<>();
@@ -240,7 +245,7 @@ public class BridgeContext extends Context {
mMetrics = metrics;
mLayoutlibCallback = layoutlibCallback;
- mRenderResources = renderResources;
+ mRenderResources = new DynamicRenderResources(renderResources);
mConfig = config;
AssetManager systemAssetManager = AssetManager.getSystem();
if (systemAssetManager instanceof BridgeAssetManager) {
@@ -263,6 +268,7 @@ public class BridgeContext extends Context {
mActivityManager = ActivityManager_Accessor.getActivityManagerInstance(this);
mConnectivityManager = new ConnectivityManager(this, null);
mAudioManager = new AudioManager(this);
+ mInputManager = new InputManager(this);
if (mLayoutlibCallback.isResourceNamespacingRequired()) {
if (mLayoutlibCallback.hasAndroidXAppCompat()) {
@@ -365,6 +371,9 @@ public class BridgeContext extends Context {
if (ParserFactory.LOG_PARSER) {
System.out.println("PUSH " + parser.getParser().toString());
}
+ if (mParserStack.size() > MAX_PARSER_STACK_SIZE) {
+ throw new RuntimeException("Potential cycle encountered during inflation");
+ }
mParserStack.push(parser);
}
@@ -449,6 +458,15 @@ public class BridgeContext extends Context {
outValue.type = TypedValue.TYPE_INT_BOOLEAN;
outValue.data = "true".equals(stringValue) ? 1 : 0;
}
+ else {
+ try {
+ outValue.data = Integer.parseInt(stringValue);
+ outValue.type = TypedValue.TYPE_INT_DEC;
+ } catch (NumberFormatException e) {
+ outValue.type = TypedValue.TYPE_STRING;
+ outValue.string = stringValue;
+ }
+ }
}
int a = getResourceId(value.asReference(), 0 /*defValue*/);
@@ -669,6 +687,9 @@ public class BridgeContext extends Context {
case AUDIO_SERVICE:
return mAudioManager;
+ case INPUT_SERVICE:
+ return mInputManager;
+
case TEXT_CLASSIFICATION_SERVICE:
case CONTENT_CAPTURE_MANAGER_SERVICE:
case ALARM_SERVICE:
@@ -694,7 +715,7 @@ public class BridgeContext extends Context {
* Same as Context#obtainStyledAttributes. We do not override the base method to give the
* original Context the chance to override the theme when needed.
*/
- @Nullable
+ @NonNull
public final BridgeTypedArray internalObtainStyledAttributes(int resId, int[] attrs)
throws Resources.NotFoundException {
StyleResourceValue style = null;
@@ -711,9 +732,8 @@ public class BridgeContext extends Context {
}
if (style == null) {
- Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
+ Bridge.getLog().warning(ILayoutLog.TAG_INFO,
"Failed to find style with " + resId, null, null);
- return null;
}
}
@@ -1018,7 +1038,7 @@ public class BridgeContext extends Context {
@Override
public String getPackageName() {
if (mApplicationInfo.packageName == null) {
- mApplicationInfo.packageName = mLayoutlibCallback.getFlag(FLAG_KEY_APPLICATION_PACKAGE);
+ mApplicationInfo.packageName = mLayoutlibCallback.getApplicationId();
}
return mApplicationInfo.packageName;
}
@@ -1982,7 +2002,10 @@ public class BridgeContext extends Context {
@Override
public Context getApplicationContext() {
- return this;
+ if (mApplicationContext == null) {
+ mApplicationContext = new ApplicationContext(this);
+ }
+ return mApplicationContext;
}
@Override
@@ -2254,4 +2277,16 @@ public class BridgeContext extends Context {
public SessionInteractiveData getSessionInteractiveData() {
return mSessionInteractiveData;
}
+
+ public boolean useThemedIcon() {
+ return mUseThemedIcon && mRenderResources.hasDynamicColors();
+ }
+
+ public void setUseThemedIcon(boolean useThemedIcon) {
+ mUseThemedIcon = useThemedIcon;
+ }
+
+ public void applyWallpaper(String wallpaperPath) {
+ mRenderResources.setWallpaper(wallpaperPath, mConfig.isNightModeActive());
+ }
}
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 902f11d34b..c52bcc231b 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -55,6 +55,7 @@ import android.os.PersistableBundle;
import android.os.UserHandle;
import android.os.storage.VolumeInfo;
+import java.util.Collections;
import java.util.List;
/**
@@ -148,7 +149,7 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
throws NameNotFoundException {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -164,63 +165,63 @@ public class BridgePackageManager extends PackageManager {
@Override
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public List<PackageInfo> getInstalledPackages(int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -308,12 +309,12 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<ApplicationInfo> getInstalledApplications(int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -409,28 +410,28 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
Intent intent, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -445,23 +446,23 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryIntentContentProvidersAsUser(Intent intent, int flags,
int userId) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -476,18 +477,18 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -497,12 +498,12 @@ public class BridgePackageManager extends PackageManager {
@Override
public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
@@ -527,7 +528,7 @@ public class BridgePackageManager extends PackageManager {
@Override
public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
@@ -604,24 +605,24 @@ public class BridgePackageManager extends PackageManager {
@Override
public Resources getResourcesForActivity(ComponentName activityName)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public Resources getResourcesForApplication(String appPackageName)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
throws NameNotFoundException {
- return null;
+ throw new NameNotFoundException("PackageManager features are not supported");
}
@Override
@@ -667,12 +668,12 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
- return null;
+ return Collections.emptyList();
}
@Override
public List<IntentFilter> getAllIntentFilters(String packageName) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -744,7 +745,7 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<PackageInfo> getPreferredPackages(int flags) {
- return null;
+ return Collections.emptyList();
}
@Override
@@ -878,7 +879,7 @@ public class BridgePackageManager extends PackageManager {
@Override
public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
- return null;
+ return Collections.emptyList();
}
@Override
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 22676e4312..85bf637d00 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -27,6 +27,9 @@ import android.os.PowerSaveState;
import android.os.RemoteException;
import android.os.WorkSource;
+import java.util.Collections;
+import java.util.List;
+
/**
* Fake implementation of IPowerManager.
*/
@@ -38,6 +41,16 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
+ public boolean isDisplayInteractive(int displayId) {
+ return true;
+ }
+
+ @Override
+ public boolean areAutoPowerSaveModesEnabled() throws RemoteException {
+ return false;
+ }
+
+ @Override
public boolean isPowerSaveMode() throws RemoteException {
return false;
}
@@ -151,6 +164,12 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
+ public void goToSleepWithDisplayId(int arg0, long arg1, int arg2, int arg3)
+ throws RemoteException {
+ // pass for now.
+ }
+
+ @Override
public void nap(long arg0) throws RemoteException {
// pass for now.
}
@@ -259,6 +278,47 @@ public class BridgePowerManager implements IPowerManager {
}
@Override
+ public void setLowPowerStandbyPolicy(LowPowerStandbyPolicy policy) {
+ // pass for now.
+ }
+
+ @Override
+ public LowPowerStandbyPolicy getLowPowerStandbyPolicy() {
+ return null;
+ }
+
+ @Override
+ public boolean isExemptFromLowPowerStandby() {
+ return true;
+ }
+
+ @Override
+ public boolean isReasonAllowedInLowPowerStandby(int reason) {
+ return true;
+ }
+
+ @Override
+ public boolean isFeatureAllowedInLowPowerStandby(String feature) {
+ return true;
+ }
+
+ @Override
+ public void acquireLowPowerStandbyPorts(IBinder token,
+ List<LowPowerStandbyPortDescription> ports) {
+ // pass for now
+ }
+
+ @Override
+ public void releaseLowPowerStandbyPorts(IBinder token) {
+ // pass for now
+ }
+
+ @Override
+ public List<LowPowerStandbyPortDescription> getActiveLowPowerStandbyPorts() {
+ return Collections.emptyList();
+ }
+
+ @Override
public void setLowPowerStandbyEnabled(boolean enabled) {
// pass for now
}
diff --git a/bridge/src/com/android/layoutlib/bridge/android/DynamicRenderResources.java b/bridge/src/com/android/layoutlib/bridge/android/DynamicRenderResources.java
new file mode 100644
index 0000000000..406d7b38e6
--- /dev/null
+++ b/bridge/src/com/android/layoutlib/bridge/android/DynamicRenderResources.java
@@ -0,0 +1,207 @@
+/*
+ * 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 com.android.layoutlib.bridge.android;
+
+import com.android.ide.common.rendering.api.ILayoutLog;
+import com.android.ide.common.rendering.api.RenderResources;
+import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.ResourceValueImpl;
+import com.android.ide.common.rendering.api.StyleResourceValue;
+import com.android.internal.graphics.ColorUtils;
+import com.android.resources.ResourceType;
+import com.android.systemui.monet.ColorScheme;
+import com.android.systemui.monet.Style;
+import com.android.systemui.monet.TonalPalette;
+import com.android.tools.layoutlib.annotations.VisibleForTesting;
+
+import android.app.WallpaperColors;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Wrapper for RenderResources that allows overriding default system colors
+ * when using dynamic theming.
+ */
+public class DynamicRenderResources extends RenderResources {
+ private final RenderResources mBaseResources;
+ private Map<String, Integer> mDynamicColorMap;
+
+ public DynamicRenderResources(RenderResources baseResources) {
+ mBaseResources = baseResources;
+ }
+
+ @Override
+ public void setLogger(ILayoutLog logger) {
+ mBaseResources.setLogger(logger);
+ }
+
+ @Override
+ public StyleResourceValue getDefaultTheme() {
+ return mBaseResources.getDefaultTheme();
+ }
+
+ @Override
+ public void applyStyle(StyleResourceValue theme, boolean useAsPrimary) {
+ mBaseResources.applyStyle(theme, useAsPrimary);
+ }
+
+ @Override
+ public void clearStyles() {
+ mBaseResources.clearStyles();
+ }
+
+ @Override
+ public List<StyleResourceValue> getAllThemes() {
+ return mBaseResources.getAllThemes();
+ }
+
+ @Override
+ public ResourceValue findItemInTheme(ResourceReference attr) {
+ ResourceValue baseValue = mBaseResources.findItemInTheme(attr);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue findItemInStyle(StyleResourceValue style, ResourceReference attr) {
+ ResourceValue baseValue = mBaseResources.findItemInStyle(style, attr);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue findResValue(String reference, boolean forceFrameworkOnly) {
+ ResourceValue baseValue = mBaseResources.findResValue(reference, forceFrameworkOnly);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue dereference(ResourceValue resourceValue) {
+ ResourceValue baseValue = mBaseResources.dereference(resourceValue);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue getUnresolvedResource(ResourceReference reference) {
+ ResourceValue baseValue = mBaseResources.getUnresolvedResource(reference);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue getResolvedResource(ResourceReference reference) {
+ ResourceValue baseValue = mBaseResources.getResolvedResource(reference);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public ResourceValue resolveResValue(ResourceValue value) {
+ ResourceValue baseValue = mBaseResources.resolveResValue(value);
+ return resolveDynamicColors(baseValue);
+ }
+
+ @Override
+ public StyleResourceValue getParent(StyleResourceValue style) {
+ return mBaseResources.getParent(style);
+ }
+
+ @Override
+ public StyleResourceValue getStyle(ResourceReference reference) {
+ return mBaseResources.getStyle(reference);
+ }
+
+ private ResourceValue resolveDynamicColors(ResourceValue baseValue) {
+ if (hasDynamicColors() && baseValue != null && isDynamicColor(baseValue)) {
+ int dynamicColor = mDynamicColorMap.get(baseValue.getName());
+ String colorHex = "#" + Integer.toHexString(dynamicColor).substring(2);
+ return new ResourceValueImpl(baseValue.getNamespace(), baseValue.getResourceType(),
+ baseValue.getName(), colorHex);
+ }
+ return baseValue;
+ }
+
+ public void setWallpaper(String wallpaperPath, boolean isNightMode) {
+ if (wallpaperPath == null) {
+ mDynamicColorMap = null;
+ return;
+ }
+ mDynamicColorMap = createDynamicColorMap(wallpaperPath, isNightMode);
+ }
+
+ /**
+ * Extracts colors from the wallpaper and creates the corresponding dynamic theme.
+ * It uses the main wallpaper color and the {@link Style#TONAL_SPOT} style.
+ *
+ * @param wallpaperPath path of the wallpaper resource to use
+ * @param isNightMode whether to use night mode or not
+ *
+ * @return map of system color names to their dynamic values
+ */
+ @VisibleForTesting
+ static Map<String, Integer> createDynamicColorMap(String wallpaperPath, boolean isNightMode) {
+ try (InputStream stream = DynamicRenderResources.class.getResourceAsStream(wallpaperPath)) {
+ Bitmap wallpaper = BitmapFactory.decodeStream(stream);
+ if (wallpaper == null) {
+ return null;
+ }
+ WallpaperColors wallpaperColors = WallpaperColors.fromBitmap(wallpaper);
+ int seed = ColorScheme.getSeedColor(wallpaperColors);
+ ColorScheme scheme = new ColorScheme(seed, isNightMode);
+ Map<String, Integer> dynamicColorMap = new HashMap<>();
+ extractPalette("accent1", dynamicColorMap, scheme.getAccent1());
+ extractPalette("accent2", dynamicColorMap, scheme.getAccent2());
+ extractPalette("accent3", dynamicColorMap, scheme.getAccent3());
+ extractPalette("neutral1", dynamicColorMap, scheme.getNeutral1());
+ extractPalette("neutral2", dynamicColorMap, scheme.getNeutral2());
+ return dynamicColorMap;
+ } catch (IllegalArgumentException | IOException ignore) {
+ return null;
+ }
+ }
+
+ /**
+ * Builds the dynamic theme from the {@link ColorScheme} copying what is done
+ * in {@link ThemeOverlayController#getOverlay}
+ */
+ private static void extractPalette(String name,
+ Map<String, Integer> colorMap, TonalPalette tonalPalette) {
+ String resourcePrefix = "system_" + name;
+ tonalPalette.getAllShadesMapped().forEach((key, value) -> {
+ String resourceName = resourcePrefix + "_" + key;
+ int colorValue = ColorUtils.setAlphaComponent(value, 0xFF);
+ colorMap.put(resourceName, colorValue);
+ });
+ colorMap.put(resourcePrefix + "_0", Color.WHITE);
+ }
+
+ private static boolean isDynamicColor(ResourceValue resourceValue) {
+ if (!resourceValue.isFramework() || resourceValue.getResourceType() != ResourceType.COLOR) {
+ return false;
+ }
+ return resourceValue.getName().startsWith("system_accent")
+ || resourceValue.getName().startsWith("system_neutral");
+ }
+
+ public boolean hasDynamicColors() {
+ return mDynamicColorMap != null;
+ }
+}
diff --git a/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
index e370fa0c72..6620b6daab 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java
@@ -17,7 +17,6 @@
package com.android.layoutlib.bridge.android;
import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.ide.common.rendering.api.RenderParams;
import com.android.ide.common.rendering.api.SessionParams.Key;
@@ -38,19 +37,13 @@ public final class RenderParamsFlags {
new Key<Boolean>("renderAllDrawableStates", Boolean.class);
/**
- * The application package name. Used via {@link LayoutlibCallback#getFlag(Key)}
- */
- public static final Key<String> FLAG_KEY_APPLICATION_PACKAGE =
- new Key<String>("applicationPackage", String.class);
-
- /**
* To tell LayoutLib to not render when creating a new session. This allows controlling when the first
* layout rendering will happen.
*/
public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE =
new Key<Boolean>("doNotRenderOnCreate", Boolean.class);
/**
- * The adaptive icon mask path. Used via {@link LayoutlibCallback#getFlag(Key)}
+ * To tell Layoutlib which path to use for the adaptive icon mask.
*/
public static final Key<String> FLAG_KEY_ADAPTIVE_ICON_MASK_PATH =
new Key<>("adaptiveIconMaskPath", String.class);
@@ -77,6 +70,19 @@ public final class RenderParamsFlags {
public static final Key<Boolean> FLAG_ENABLE_LAYOUT_VALIDATOR_IMAGE_CHECK =
new Key<>("enableLayoutValidatorImageCheck", Boolean.class);
+ /**
+ * To tell Layoutlib the path of the image resource of the wallpaper to use for dynamic theming.
+ * If null, use default system colors.
+ */
+ public static final Key<String> FLAG_KEY_WALLPAPER_PATH =
+ new Key<>("wallpaperPath", String.class);
+
+ /**
+ * To tell Layoutlib to use the themed version of adaptive icons.
+ */
+ public static final Key<Boolean> FLAG_KEY_USE_THEMED_ICON =
+ new Key<>("useThemedIcon", Boolean.class);
+
// Disallow instances.
private RenderParamsFlags() {}
}
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 1c6d55c568..d89960ea68 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -92,8 +92,8 @@ public class Config {
}
public static String getTime(int platformVersion) {
- if (isGreaterOrEqual(platformVersion, S)) {
- return "12:00";
+ if (isGreaterOrEqual(platformVersion, TIRAMISU)) {
+ return "13:00";
}
if (platformVersion < GINGERBREAD) {
return "2:20";
@@ -140,6 +140,9 @@ public class Config {
if (platformVersion < S) {
return "11:00";
}
+ if (platformVersion < TIRAMISU) {
+ return "12:00";
+ }
// Should never happen.
return "4:04";
}
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index d444754145..c2430a8959 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -34,6 +34,7 @@ import com.android.tools.layoutlib.annotations.VisibleForTesting;
import android.animation.PropertyValuesHolder_Accessor;
import android.content.res.Configuration;
+import android.graphics.drawable.AdaptiveIconDrawable_Delegate;
import android.os.HandlerThread_Delegate;
import android.util.DisplayMetrics;
import android.view.IWindowManager;
@@ -138,6 +139,10 @@ public abstract class RenderAction<T extends RenderParams> {
RenderResources resources = mParams.getResources();
+ // sets the custom adaptive icon path
+ AdaptiveIconDrawable_Delegate.sPath =
+ mParams.getFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH);
+
// build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
mParams.getAssets(), mParams.getLayoutlibCallback(), getConfiguration(mParams),
@@ -256,6 +261,9 @@ public abstract class RenderAction<T extends RenderParams> {
// scene
mContext.initResources(mParams.getAssets());
sCurrentContext = mContext;
+ mContext.applyWallpaper(mParams.getFlag(RenderParamsFlags.FLAG_KEY_WALLPAPER_PATH));
+ mContext.setUseThemedIcon(
+ Boolean.TRUE.equals(mParams.getFlag(RenderParamsFlags.FLAG_KEY_USE_THEMED_ICON)));
// Set-up WindowManager
// FIXME: find those out, and possibly add them to the render params
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index 60c3864a66..6a6e184617 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -115,7 +115,7 @@ public class RenderDrawable extends RenderAction<DrawableParams> {
content.setBackground(d);
// Set the AttachInfo on the root view.
- AttachInfo_Accessor.setAttachInfo(content, null);
+ AttachInfo_Accessor.setAttachInfo(content);
// Measure.
int w = d.getIntrinsicWidth();
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 8c46e33c3b..ae5e401edc 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -16,7 +16,6 @@
package com.android.layoutlib.bridge.impl;
-import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.HardwareConfig;
import com.android.ide.common.rendering.api.ILayoutLog;
import com.android.ide.common.rendering.api.ILayoutPullParser;
@@ -30,6 +29,7 @@ import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode.SizeAction;
import com.android.ide.common.rendering.api.ViewInfo;
import com.android.ide.common.rendering.api.ViewType;
+import com.android.internal.R;
import com.android.internal.view.menu.ActionMenuItemView;
import com.android.internal.view.menu.BridgeMenuItemImpl;
import com.android.internal.view.menu.IconMenuItemView;
@@ -44,15 +44,9 @@ import com.android.layoutlib.bridge.android.graphics.NopCanvas;
import com.android.layoutlib.bridge.android.support.DesignLibUtil;
import com.android.layoutlib.bridge.android.support.FragmentTabHostUtil;
import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
-import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
-import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
+import com.android.layoutlib.bridge.util.KeyEventHandling;
import com.android.tools.idea.validator.LayoutValidator;
-import com.android.tools.idea.validator.ValidatorData.Issue.IssueBuilder;
-import com.android.tools.idea.validator.ValidatorData.Level;
-import com.android.tools.idea.validator.ValidatorData.Type;
import com.android.tools.idea.validator.ValidatorHierarchy;
-import com.android.tools.idea.validator.ValidatorResult;
-import com.android.tools.idea.validator.ValidatorResult.Builder;
import com.android.tools.idea.validator.hierarchy.CustomHierarchyHelper;
import com.android.tools.layoutlib.annotations.NotNull;
@@ -60,22 +54,18 @@ import android.animation.AnimationHandler;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
-import android.graphics.HardwareRenderer;
-import android.graphics.LayoutlibRenderer;
-import android.graphics.PixelFormat;
-import android.graphics.RenderNode;
import android.graphics.drawable.AnimatedVectorDrawable_VectorDrawableAnimatorUI_Delegate;
-import android.media.Image;
-import android.media.Image.Plane;
-import android.media.ImageReader;
import android.preference.Preference_Delegate;
import android.util.Pair;
import android.util.TimeUtils;
import android.view.AttachInfo_Accessor;
import android.view.BridgeInflater;
-import android.view.Choreographer_Delegate;
+import android.view.InputDevice;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
@@ -83,15 +73,12 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewParent;
+import android.view.ViewRootImpl;
+import android.view.ViewRootImpl_Accessor;
import android.view.WindowManagerImpl;
-import android.widget.AbsListView;
-import android.widget.AbsSpinner;
import android.widget.ActionMenuView;
-import android.widget.AdapterView;
-import android.widget.ExpandableListView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
-import android.widget.ListView;
import android.widget.QuickContactBadge;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
@@ -101,15 +88,11 @@ import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
-import com.android.internal.R;
-import android.content.res.TypedArray;
-
import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
@@ -146,9 +129,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
private List<ViewInfo> mSystemViewInfoList;
private Layout.Builder mLayoutBuilder;
private boolean mNewRenderSize;
- private ImageReader mImageReader;
- private Image mNativeImage;
- private LayoutlibRenderer mRenderer = new LayoutlibRenderer();
+ private Canvas mCanvas;
+ private Bitmap mBitmap;
// Passed in MotionEvent initialization when dispatching a touch event.
private final MotionEvent.PointerProperties[] mPointerProperties =
@@ -157,7 +139,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
MotionEvent.PointerCoords.createArray(1);
private long mLastActionDownTimeNanos = -1;
- @Nullable private ValidatorResult mValidatorResult = null;
@Nullable private ValidatorHierarchy mValidatorHierarchy = null;
private static final class PostInflateException extends Exception {
@@ -213,9 +194,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
Bitmap.setDefaultDensity(params.getHardwareConfig().getDensity().getDpiValue());
- // Needed in order to initialize static state of ImageReader
- ImageReader.nativeClassInit();
-
return SUCCESS.createResult();
}
@@ -368,7 +346,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
context.popParser();
// set the AttachInfo on the root view.
- AttachInfo_Accessor.setAttachInfo(mViewRoot, mRenderer);
+ AttachInfo_Accessor.setAttachInfo(mViewRoot);
// post-inflate process. For now this supports TabHost/TabWidget
postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
@@ -381,6 +359,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
mMeasuredScreenWidth, MeasureSpec.EXACTLY,
mMeasuredScreenHeight, MeasureSpec.EXACTLY);
mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+ mViewRoot.getViewRootImpl().mTmpFrames.displayFrame.set(mViewRoot.getLeft(),
+ mViewRoot.getTop(), mViewRoot.getRight(), mViewRoot.getBottom());
+
+ ViewRootImpl rootImpl = AttachInfo_Accessor.getRootView(mViewRoot);
+ if (rootImpl != null) {
+ ViewRootImpl_Accessor.setChild(rootImpl, mViewRoot);
+ }
+
mSystemViewInfoList =
visitAllChildren(mViewRoot, 0, 0, params.getExtendedViewInfoMode(),
false);
@@ -430,13 +416,12 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
* shadows).
*/
private static Result renderAndBuildResult(@NonNull ViewGroup viewRoot,
- @NonNull HardwareRenderer renderer) {
-
+ @Nullable Canvas canvas) {
+ if (canvas == null) {
+ return SUCCESS.createResult();
+ }
AttachInfo_Accessor.dispatchOnPreDraw(viewRoot);
-
- RenderNode node = viewRoot.updateDisplayListIfDirty();
- renderer.setContentRoot(node);
- renderer.createRenderRequest().syncAndDraw();
+ viewRoot.draw(canvas);
return SUCCESS.createResult();
}
@@ -519,7 +504,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
boolean disableBitmapCaching = Boolean.TRUE.equals(params.getFlag(
RenderParamsFlags.FLAG_KEY_DISABLE_BITMAP_CACHING));
- if (mNewRenderSize || mImageReader == null || disableBitmapCaching) {
+ if (mNewRenderSize || mCanvas == null || disableBitmapCaching) {
if (params.getImageFactory() != null) {
mImage = params.getImageFactory().getImage(
mMeasuredScreenWidth,
@@ -531,29 +516,33 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
BufferedImage.TYPE_INT_ARGB);
}
+ // create an Android bitmap around the BufferedImage
+ mBitmap = Bitmap.createBitmap(mImage.getWidth(), mImage.getHeight(),
+ Config.ARGB_8888);
+ int[] imageData = ((DataBufferInt) mImage.getRaster().getDataBuffer()).getData();
+ mBitmap.setPixels(imageData, 0, mImage.getWidth(), 0, 0, mImage.getWidth(), mImage.getHeight());
+
+ if (mCanvas == null) {
+ // create a Canvas around the Android bitmap
+ mCanvas = new Canvas(mBitmap);
+ } else {
+ mCanvas.setBitmap(mBitmap);
+ }
+
boolean enableImageResizing =
mImage.getWidth() != mMeasuredScreenWidth &&
mImage.getHeight() != mMeasuredScreenHeight &&
Boolean.TRUE.equals(params.getFlag(
RenderParamsFlags.FLAG_KEY_RESULT_IMAGE_AUTO_SCALE));
- if (enableImageResizing || mNewRenderSize) {
- disposeImageSurface();
- }
-
if (enableImageResizing) {
scaleX = mImage.getWidth() * 1.0f / mMeasuredScreenWidth;
scaleY = mImage.getHeight() * 1.0f / mMeasuredScreenHeight;
- mRenderer.setScale(scaleX, scaleY);
+ mCanvas.scale(scaleX, scaleY);
} else {
- mRenderer.setScale(1.0f, 1.0f);
+ mCanvas.scale(1.0f, 1.0f);
}
- if (mImageReader == null) {
- mImageReader = ImageReader.newInstance(mImage.getWidth(), mImage.getHeight(), PixelFormat.RGBA_8888, 1);
- mRenderer.setSurface(mImageReader.getSurface());
- mNativeImage = mImageReader.acquireNextImage();
- }
mNewRenderSize = false;
}
@@ -573,25 +562,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
mElapsedFrameTimeNanos / 1000000;
}
- final TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
- float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
- float lightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
- float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
- float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
- float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
- a.recycle();
-
- mRenderer.setLightSourceGeometry(mMeasuredScreenWidth / 2, lightY, lightZ, lightRadius);
- mRenderer.setLightSourceAlpha(ambientShadowAlpha, spotShadowAlpha);
-
- renderResult = renderAndBuildResult(mViewRoot, mRenderer);
+ renderResult = renderAndBuildResult(mViewRoot, mCanvas);
int[] imageData = ((DataBufferInt) mImage.getRaster().getDataBuffer()).getData();
-
- Plane[] planes = mNativeImage.getPlanes();
- IntBuffer buff = planes[0].getBuffer().asIntBuffer();
- int len = buff.remaining();
- buff.get(imageData, 0, len);
+ mBitmap.getPixels(imageData, 0, mImage.getWidth(), 0, 0, mImage.getWidth(),
+ mImage.getHeight());
}
mSystemViewInfoList =
@@ -690,72 +665,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
} else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault();
- } else if (view instanceof AdapterView<?>) {
- // get the view ID.
- int id = view.getId();
-
- BridgeContext context = getContext();
-
- // get a ResourceReference from the integer ID.
- ResourceReference listRef = context.resolveId(id);
-
- if (listRef != null) {
- SessionParams params = getParams();
- AdapterBinding binding = params.getAdapterBindings().get(listRef);
-
- // if there was no adapter binding, trying to get it from the call back.
- if (binding == null) {
- binding = layoutlibCallback.getAdapterBinding(
- listRef, context.getViewKey(view), view);
- }
-
- if (binding != null) {
-
- if (view instanceof AbsListView) {
- if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) &&
- view instanceof ListView) {
- ListView list = (ListView) view;
-
- boolean skipCallbackParser = false;
-
- int count = binding.getHeaderCount();
- for (int i = 0; i < count; i++) {
- Pair<View, Boolean> pair = context.inflateView(
- binding.getHeaderAt(i),
- list, false, skipCallbackParser);
- if (pair.first != null) {
- list.addHeaderView(pair.first);
- }
-
- skipCallbackParser |= pair.second;
- }
-
- count = binding.getFooterCount();
- for (int i = 0; i < count; i++) {
- Pair<View, Boolean> pair = context.inflateView(
- binding.getFooterAt(i),
- list, false, skipCallbackParser);
- if (pair.first != null) {
- list.addFooterView(pair.first);
- }
-
- skipCallbackParser |= pair.second;
- }
- }
-
- if (view instanceof ExpandableListView) {
- ((ExpandableListView) view).setAdapter(
- new FakeExpandableAdapter(listRef, binding, layoutlibCallback));
- } else {
- ((AbsListView) view).setAdapter(
- new FakeAdapter(listRef, binding, layoutlibCallback));
- }
- } else if (view instanceof AbsSpinner) {
- ((AbsSpinner) view).setAdapter(
- new FakeAdapter(listRef, binding, layoutlibCallback));
- }
- }
- }
} else if (view instanceof ViewGroup) {
mInflater.postInflateProcess(view);
ViewGroup group = (ViewGroup) view;
@@ -1194,15 +1103,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
}
@Nullable
- public ValidatorResult getValidatorResult() {
- return mValidatorResult;
- }
-
- public void setValidatorResult(ValidatorResult result) {
- mValidatorResult = result;
- }
-
- @Nullable
public ValidatorHierarchy getValidatorHierarchy() {
return mValidatorHierarchy;
}
@@ -1252,22 +1152,48 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
currentTimeNanos / TimeUtils.NANOS_PER_MS,
motionEventType,
1, mPointerProperties, mPointerCoords,
- 0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
+ 0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
root.dispatchTouchEvent(event);
}
+ public void dispatchKeyEvent(java.awt.event.KeyEvent event, long currentTimeNanos) {
+ WindowManagerImpl wm =
+ (WindowManagerImpl)getContext().getSystemService(Context.WINDOW_SERVICE);
+ ViewGroup root = wm.getCurrentRootView();
+ if (root == null) {
+ root = mViewRoot;
+ }
+ if (root == null) {
+ return;
+ }
+ if (event.getID() == java.awt.event.KeyEvent.KEY_PRESSED) {
+ mLastActionDownTimeNanos = currentTimeNanos;
+ }
+ // Ignore events not started with KeyEvent.ACTION_DOWN
+ if (mLastActionDownTimeNanos == -1) {
+ return;
+ }
+
+ KeyEvent androidEvent = KeyEventHandling.javaToAndroidKeyEvent(event,
+ mLastActionDownTimeNanos, currentTimeNanos);
+ boolean success = root.dispatchKeyEvent(androidEvent);
+ if (!success && root != mViewRoot) {
+ // If the event was not consumed by a Window, pass it down to the root layout
+ mViewRoot.dispatchKeyEvent(androidEvent);
+ }
+ }
+
private void disposeImageSurface() {
- if (mImageReader != null) {
- mImageReader.close();
- mImageReader = null;
+ if (mCanvas != null) {
+ mCanvas.release();
+ mCanvas = null;
}
}
@Override
public void dispose() {
try {
- mRenderer.destroy();
disposeImageSurface();
mImage = null;
// detachFromWindow might create Handler callbacks, thus before Handler_Delegate.dispose
@@ -1285,7 +1211,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
if (mSystemViewInfoList != null) {
mSystemViewInfoList.clear();
}
- mValidatorResult = null;
mValidatorHierarchy = null;
mViewRoot = null;
mContentRoot = null;
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index b344537b2b..87bed3d967 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -421,7 +421,8 @@ public final class ResourceHelper {
}
Options options = new Options();
options.inDensity = density.getDpiValue();
- bitmap = BitmapFactory.decodeStream(stream, null, options);
+ Rect padding = new Rect();
+ bitmap = BitmapFactory.decodeStream(stream, padding, options);
if (bitmap != null && bitmap.getNinePatchChunk() == null &&
lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
//We are dealing with a non-compiled nine patch.
@@ -441,14 +442,20 @@ public final class ResourceHelper {
bitmap.setDensity(options.inDensity);
bitmap.setNinePatchChunk(ninePatch.getChunk().getSerializedChunk());
+ int[] padArray = ninePatch.getChunk().getPadding();
+ padding.set(padArray[0], padArray[1], padArray[2], padArray[3]);
}
+ Bridge.setCachedBitmapPadding(stringValue, padding,
+ value.isFramework() ? null : context.getProjectKey());
Bridge.setCachedBitmap(stringValue, bitmap,
value.isFramework() ? null : context.getProjectKey());
}
if (bitmap != null && bitmap.getNinePatchChunk() != null) {
+ Rect padding = Bridge.getCachedBitmapPadding(stringValue,
+ value.isFramework() ? null : context.getProjectKey());
return new NinePatchDrawable(context.getResources(), bitmap, bitmap
- .getNinePatchChunk(), new Rect(), lowerCaseValue);
+ .getNinePatchChunk(), padding, lowerCaseValue);
} else {
return new BitmapDrawable(context.getResources(), bitmap);
}
@@ -474,7 +481,7 @@ public final class ResourceHelper {
*/
public static Typeface getFont(String fontName, BridgeContext context, Theme theme, boolean
isFramework) {
- if (fontName == null) {
+ if (fontName == null || fontName.isBlank()) {
return null;
}
@@ -542,6 +549,9 @@ public final class ResourceHelper {
String str = string.replaceAll("<li>", "<ul><li>")
.replaceAll("</li>","</li></ul>");
int firstTagIndex = str.indexOf('<');
+ if (firstTagIndex == -1) {
+ return string;
+ }
int lastTagIndex = str.lastIndexOf('>');
StringBuilder stringBuilder = new StringBuilder(str.substring(0, firstTagIndex));
List<Tag> tagList = new ArrayList<>();
diff --git a/bridge/src/com/android/layoutlib/bridge/util/ChoreographerCallbacks.java b/bridge/src/com/android/layoutlib/bridge/util/ChoreographerCallbacks.java
index 9d5830b4de..8862f7c89e 100644
--- a/bridge/src/com/android/layoutlib/bridge/util/ChoreographerCallbacks.java
+++ b/bridge/src/com/android/layoutlib/bridge/util/ChoreographerCallbacks.java
@@ -20,13 +20,11 @@ import com.android.ide.common.rendering.api.ILayoutLog;
import com.android.tools.layoutlib.annotations.NotNull;
import android.os.SystemClock_Delegate;
-import android.util.Pair;
import android.util.TimeUtils;
import android.view.Choreographer.FrameCallback;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Manages {@link android.view.Choreographer} callbacks. Keeps track of the currently active
@@ -40,37 +38,50 @@ public class ChoreographerCallbacks {
}
}
- private final RangeList<Pair<Object, Long>> mCallbacks = new RangeList<>();
+ private static class Callback {
+ private final Object mAction;
+ private final Object mToken;
+ private final long mDueTime;
- public void add(Object action, long delayMillis) {
+ private Callback(@NotNull Object action, Object token, long dueTime) {
+ mAction = action;
+ mToken = token;
+ mDueTime = dueTime;
+ }
+ }
+
+ private final RangeList<Callback> mCallbacks = new RangeList<>();
+
+ public void add(Object action, Object token, long delayMillis) {
synchronized (mCallbacks) {
int idx = 0;
final long now = SystemClock_Delegate.uptimeMillis();
final long dueTime = now + delayMillis;
while (idx < mCallbacks.size()) {
- if (mCallbacks.get(idx).second > dueTime) {
+ if (mCallbacks.get(idx).mDueTime > dueTime) {
break;
} else {
++idx;
}
}
- mCallbacks.add(idx, Pair.create(action, dueTime));
+ mCallbacks.add(idx, new Callback(action, token, dueTime));
}
}
- public void remove(Object action) {
+ public void remove(Object action, Object token) {
synchronized (mCallbacks) {
- mCallbacks.removeIf(el -> el.first == action);
+ mCallbacks.removeIf(el -> (action == null || el.mAction == action)
+ && (token == null || el.mToken == token));
}
}
public void execute(long currentTimeMs, @NotNull ILayoutLog logger) {
final long currentTimeNanos = currentTimeMs * TimeUtils.NANOS_PER_MS;
- List<Pair<Object, Long>> toExecute;
+ List<Callback> toExecute;
synchronized (mCallbacks) {
int idx = 0;
while (idx < mCallbacks.size()) {
- if (mCallbacks.get(idx).second > currentTimeMs) {
+ if (mCallbacks.get(idx).mDueTime > currentTimeMs) {
break;
} else {
++idx;
@@ -82,7 +93,7 @@ public class ChoreographerCallbacks {
// We run the callbacks outside of the synchronized block to avoid deadlocks caused by
// callbacks calling back into ChoreographerCallbacks.
- toExecute.forEach(p -> executeSafely(p.first, currentTimeNanos, logger));
+ toExecute.forEach(p -> executeSafely(p.mAction, currentTimeNanos, logger));
}
public void clear() {
diff --git a/bridge/src/com/android/layoutlib/bridge/util/HandlerMessageQueue.java b/bridge/src/com/android/layoutlib/bridge/util/HandlerMessageQueue.java
index e1737177c7..595b57556c 100644
--- a/bridge/src/com/android/layoutlib/bridge/util/HandlerMessageQueue.java
+++ b/bridge/src/com/android/layoutlib/bridge/util/HandlerMessageQueue.java
@@ -43,18 +43,20 @@ public class HandlerMessageQueue {
* @param r {@link Runnable} to be added
*/
public void add(@NotNull Handler h, long uptimeMillis, @NotNull Runnable r) {
- LinkedList<Pair<Long, Runnable>> runnables = runnablesMap.computeIfAbsent(h,
- k -> new LinkedList<>());
+ synchronized (runnablesMap) {
+ LinkedList<Pair<Long, Runnable>> runnables = runnablesMap.computeIfAbsent(h,
+ k -> new LinkedList<>());
- int idx = 0;
- while (idx < runnables.size()) {
- if (runnables.get(idx).first <= uptimeMillis) {
- idx++;
- } else {
- break;
+ int idx = 0;
+ while (idx < runnables.size()) {
+ if (runnables.get(idx).first <= uptimeMillis) {
+ idx++;
+ } else {
+ break;
+ }
}
+ runnables.add(idx, Pair.create(uptimeMillis, r));
}
- runnables.add(idx, Pair.create(uptimeMillis, r));
}
private static class HandlerWrapper {
@@ -69,42 +71,50 @@ public class HandlerMessageQueue {
*/
@Nullable
public Runnable extractFirst(long uptimeMillis) {
- final HandlerWrapper w = new HandlerWrapper();
- runnablesMap.forEach((h, l) -> {
- if (!l.isEmpty()) {
- long currentUptime = l.getFirst().first;
- if (currentUptime <= uptimeMillis) {
- if (w.handler == null || currentUptime <
- runnablesMap.get(w.handler).getFirst().first) {
- w.handler = h;
+ synchronized (runnablesMap) {
+ final HandlerWrapper w = new HandlerWrapper();
+ runnablesMap.forEach((h, l) -> {
+ if (!l.isEmpty()) {
+ long currentUptime = l.getFirst().first;
+ if (currentUptime <= uptimeMillis) {
+ if (w.handler == null || currentUptime <
+ runnablesMap.get(w.handler).getFirst().first) {
+ w.handler = h;
+ }
}
}
+ });
+ if (w.handler != null) {
+ return runnablesMap.get(w.handler).pollFirst().second;
}
- });
- if (w.handler != null) {
- return runnablesMap.get(w.handler).pollFirst().second;
+ return null;
}
- return null;
}
/**
* @return true is queue has no runnables left
*/
public boolean isNotEmpty() {
- return runnablesMap.values().stream().anyMatch(l -> !l.isEmpty());
+ synchronized (runnablesMap) {
+ return runnablesMap.values().stream().anyMatch(l -> !l.isEmpty());
+ }
}
/**
* @return number of runnables in the queue
*/
public int size() {
- return runnablesMap.values().stream().mapToInt(LinkedList::size).sum();
+ synchronized (runnablesMap) {
+ return runnablesMap.values().stream().mapToInt(LinkedList::size).sum();
+ }
}
/**
* Completely clears the entire queue
*/
public void clear() {
- runnablesMap.clear();
+ synchronized (runnablesMap) {
+ runnablesMap.clear();
+ }
}
}
diff --git a/bridge/src/com/android/layoutlib/bridge/util/KeyEventHandling.java b/bridge/src/com/android/layoutlib/bridge/util/KeyEventHandling.java
new file mode 100644
index 0000000000..ab3155cf46
--- /dev/null
+++ b/bridge/src/com/android/layoutlib/bridge/util/KeyEventHandling.java
@@ -0,0 +1,395 @@
+/*
+ * 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 com.android.layoutlib.bridge.util;
+
+import android.util.TimeUtils;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+
+import java.awt.Toolkit;
+
+import static android.view.KeyEvent.KEYCODE_0;
+import static android.view.KeyEvent.KEYCODE_1;
+import static android.view.KeyEvent.KEYCODE_2;
+import static android.view.KeyEvent.KEYCODE_3;
+import static android.view.KeyEvent.KEYCODE_4;
+import static android.view.KeyEvent.KEYCODE_5;
+import static android.view.KeyEvent.KEYCODE_6;
+import static android.view.KeyEvent.KEYCODE_7;
+import static android.view.KeyEvent.KEYCODE_8;
+import static android.view.KeyEvent.KEYCODE_9;
+import static android.view.KeyEvent.KEYCODE_A;
+import static android.view.KeyEvent.KEYCODE_ALT_LEFT;
+import static android.view.KeyEvent.KEYCODE_ALT_RIGHT;
+import static android.view.KeyEvent.KEYCODE_APOSTROPHE;
+import static android.view.KeyEvent.KEYCODE_B;
+import static android.view.KeyEvent.KEYCODE_BACKSLASH;
+import static android.view.KeyEvent.KEYCODE_BREAK;
+import static android.view.KeyEvent.KEYCODE_C;
+import static android.view.KeyEvent.KEYCODE_COMMA;
+import static android.view.KeyEvent.KEYCODE_CTRL_LEFT;
+import static android.view.KeyEvent.KEYCODE_CTRL_RIGHT;
+import static android.view.KeyEvent.KEYCODE_D;
+import static android.view.KeyEvent.KEYCODE_DEL;
+import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
+import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
+import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
+import static android.view.KeyEvent.KEYCODE_DPAD_UP;
+import static android.view.KeyEvent.KEYCODE_E;
+import static android.view.KeyEvent.KEYCODE_ENTER;
+import static android.view.KeyEvent.KEYCODE_EQUALS;
+import static android.view.KeyEvent.KEYCODE_ESCAPE;
+import static android.view.KeyEvent.KEYCODE_F;
+import static android.view.KeyEvent.KEYCODE_F1;
+import static android.view.KeyEvent.KEYCODE_F10;
+import static android.view.KeyEvent.KEYCODE_F11;
+import static android.view.KeyEvent.KEYCODE_F12;
+import static android.view.KeyEvent.KEYCODE_F2;
+import static android.view.KeyEvent.KEYCODE_F3;
+import static android.view.KeyEvent.KEYCODE_F4;
+import static android.view.KeyEvent.KEYCODE_F5;
+import static android.view.KeyEvent.KEYCODE_F6;
+import static android.view.KeyEvent.KEYCODE_F7;
+import static android.view.KeyEvent.KEYCODE_F8;
+import static android.view.KeyEvent.KEYCODE_F9;
+import static android.view.KeyEvent.KEYCODE_FORWARD_DEL;
+import static android.view.KeyEvent.KEYCODE_G;
+import static android.view.KeyEvent.KEYCODE_GRAVE;
+import static android.view.KeyEvent.KEYCODE_H;
+import static android.view.KeyEvent.KEYCODE_I;
+import static android.view.KeyEvent.KEYCODE_INSERT;
+import static android.view.KeyEvent.KEYCODE_J;
+import static android.view.KeyEvent.KEYCODE_K;
+import static android.view.KeyEvent.KEYCODE_L;
+import static android.view.KeyEvent.KEYCODE_LEFT_BRACKET;
+import static android.view.KeyEvent.KEYCODE_M;
+import static android.view.KeyEvent.KEYCODE_META_LEFT;
+import static android.view.KeyEvent.KEYCODE_META_RIGHT;
+import static android.view.KeyEvent.KEYCODE_MINUS;
+import static android.view.KeyEvent.KEYCODE_MOVE_END;
+import static android.view.KeyEvent.KEYCODE_MOVE_HOME;
+import static android.view.KeyEvent.KEYCODE_N;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_0;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_1;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_2;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_3;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_4;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_5;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_6;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_7;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_8;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_9;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_ADD;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_COMMA;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_DIVIDE;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_DOT;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_MULTIPLY;
+import static android.view.KeyEvent.KEYCODE_NUMPAD_SUBTRACT;
+import static android.view.KeyEvent.KEYCODE_O;
+import static android.view.KeyEvent.KEYCODE_P;
+import static android.view.KeyEvent.KEYCODE_PAGE_DOWN;
+import static android.view.KeyEvent.KEYCODE_PAGE_UP;
+import static android.view.KeyEvent.KEYCODE_PERIOD;
+import static android.view.KeyEvent.KEYCODE_Q;
+import static android.view.KeyEvent.KEYCODE_R;
+import static android.view.KeyEvent.KEYCODE_RIGHT_BRACKET;
+import static android.view.KeyEvent.KEYCODE_S;
+import static android.view.KeyEvent.KEYCODE_SEMICOLON;
+import static android.view.KeyEvent.KEYCODE_SHIFT_LEFT;
+import static android.view.KeyEvent.KEYCODE_SHIFT_RIGHT;
+import static android.view.KeyEvent.KEYCODE_SLASH;
+import static android.view.KeyEvent.KEYCODE_SPACE;
+import static android.view.KeyEvent.KEYCODE_T;
+import static android.view.KeyEvent.KEYCODE_TAB;
+import static android.view.KeyEvent.KEYCODE_U;
+import static android.view.KeyEvent.KEYCODE_UNKNOWN;
+import static android.view.KeyEvent.KEYCODE_V;
+import static android.view.KeyEvent.KEYCODE_W;
+import static android.view.KeyEvent.KEYCODE_X;
+import static android.view.KeyEvent.KEYCODE_Y;
+import static android.view.KeyEvent.KEYCODE_Z;
+import static java.awt.event.KeyEvent.KEY_LOCATION_RIGHT;
+import static java.awt.event.KeyEvent.VK_0;
+import static java.awt.event.KeyEvent.VK_1;
+import static java.awt.event.KeyEvent.VK_2;
+import static java.awt.event.KeyEvent.VK_3;
+import static java.awt.event.KeyEvent.VK_4;
+import static java.awt.event.KeyEvent.VK_5;
+import static java.awt.event.KeyEvent.VK_6;
+import static java.awt.event.KeyEvent.VK_7;
+import static java.awt.event.KeyEvent.VK_8;
+import static java.awt.event.KeyEvent.VK_9;
+import static java.awt.event.KeyEvent.VK_A;
+import static java.awt.event.KeyEvent.VK_ADD;
+import static java.awt.event.KeyEvent.VK_ALT;
+import static java.awt.event.KeyEvent.VK_ALT_GRAPH;
+import static java.awt.event.KeyEvent.VK_B;
+import static java.awt.event.KeyEvent.VK_BACK_QUOTE;
+import static java.awt.event.KeyEvent.VK_BACK_SLASH;
+import static java.awt.event.KeyEvent.VK_BACK_SPACE;
+import static java.awt.event.KeyEvent.VK_C;
+import static java.awt.event.KeyEvent.VK_CAPS_LOCK;
+import static java.awt.event.KeyEvent.VK_CLOSE_BRACKET;
+import static java.awt.event.KeyEvent.VK_COMMA;
+import static java.awt.event.KeyEvent.VK_CONTROL;
+import static java.awt.event.KeyEvent.VK_D;
+import static java.awt.event.KeyEvent.VK_DECIMAL;
+import static java.awt.event.KeyEvent.VK_DELETE;
+import static java.awt.event.KeyEvent.VK_DIVIDE;
+import static java.awt.event.KeyEvent.VK_DOWN;
+import static java.awt.event.KeyEvent.VK_E;
+import static java.awt.event.KeyEvent.VK_END;
+import static java.awt.event.KeyEvent.VK_ENTER;
+import static java.awt.event.KeyEvent.VK_EQUALS;
+import static java.awt.event.KeyEvent.VK_ESCAPE;
+import static java.awt.event.KeyEvent.VK_F;
+import static java.awt.event.KeyEvent.VK_F1;
+import static java.awt.event.KeyEvent.VK_F10;
+import static java.awt.event.KeyEvent.VK_F11;
+import static java.awt.event.KeyEvent.VK_F12;
+import static java.awt.event.KeyEvent.VK_F2;
+import static java.awt.event.KeyEvent.VK_F3;
+import static java.awt.event.KeyEvent.VK_F4;
+import static java.awt.event.KeyEvent.VK_F5;
+import static java.awt.event.KeyEvent.VK_F6;
+import static java.awt.event.KeyEvent.VK_F7;
+import static java.awt.event.KeyEvent.VK_F8;
+import static java.awt.event.KeyEvent.VK_F9;
+import static java.awt.event.KeyEvent.VK_G;
+import static java.awt.event.KeyEvent.VK_H;
+import static java.awt.event.KeyEvent.VK_HOME;
+import static java.awt.event.KeyEvent.VK_I;
+import static java.awt.event.KeyEvent.VK_INSERT;
+import static java.awt.event.KeyEvent.VK_J;
+import static java.awt.event.KeyEvent.VK_K;
+import static java.awt.event.KeyEvent.VK_L;
+import static java.awt.event.KeyEvent.VK_LEFT;
+import static java.awt.event.KeyEvent.VK_M;
+import static java.awt.event.KeyEvent.VK_META;
+import static java.awt.event.KeyEvent.VK_MINUS;
+import static java.awt.event.KeyEvent.VK_MULTIPLY;
+import static java.awt.event.KeyEvent.VK_N;
+import static java.awt.event.KeyEvent.VK_NUMPAD0;
+import static java.awt.event.KeyEvent.VK_NUMPAD1;
+import static java.awt.event.KeyEvent.VK_NUMPAD2;
+import static java.awt.event.KeyEvent.VK_NUMPAD3;
+import static java.awt.event.KeyEvent.VK_NUMPAD4;
+import static java.awt.event.KeyEvent.VK_NUMPAD5;
+import static java.awt.event.KeyEvent.VK_NUMPAD6;
+import static java.awt.event.KeyEvent.VK_NUMPAD7;
+import static java.awt.event.KeyEvent.VK_NUMPAD8;
+import static java.awt.event.KeyEvent.VK_NUMPAD9;
+import static java.awt.event.KeyEvent.VK_NUM_LOCK;
+import static java.awt.event.KeyEvent.VK_O;
+import static java.awt.event.KeyEvent.VK_OPEN_BRACKET;
+import static java.awt.event.KeyEvent.VK_P;
+import static java.awt.event.KeyEvent.VK_PAGE_DOWN;
+import static java.awt.event.KeyEvent.VK_PAGE_UP;
+import static java.awt.event.KeyEvent.VK_PAUSE;
+import static java.awt.event.KeyEvent.VK_PERIOD;
+import static java.awt.event.KeyEvent.VK_Q;
+import static java.awt.event.KeyEvent.VK_QUOTE;
+import static java.awt.event.KeyEvent.VK_R;
+import static java.awt.event.KeyEvent.VK_RIGHT;
+import static java.awt.event.KeyEvent.VK_S;
+import static java.awt.event.KeyEvent.VK_SEMICOLON;
+import static java.awt.event.KeyEvent.VK_SEPARATOR;
+import static java.awt.event.KeyEvent.VK_SHIFT;
+import static java.awt.event.KeyEvent.VK_SLASH;
+import static java.awt.event.KeyEvent.VK_SPACE;
+import static java.awt.event.KeyEvent.VK_SUBTRACT;
+import static java.awt.event.KeyEvent.VK_T;
+import static java.awt.event.KeyEvent.VK_TAB;
+import static java.awt.event.KeyEvent.VK_U;
+import static java.awt.event.KeyEvent.VK_UP;
+import static java.awt.event.KeyEvent.VK_V;
+import static java.awt.event.KeyEvent.VK_W;
+import static java.awt.event.KeyEvent.VK_X;
+import static java.awt.event.KeyEvent.VK_Y;
+import static java.awt.event.KeyEvent.VK_Z;
+
+public class KeyEventHandling {
+
+ /**
+ * Creates an Android KeyEvent from a Java KeyEvent
+ */
+ public static KeyEvent javaToAndroidKeyEvent(java.awt.event.KeyEvent event, long downTimeNanos,
+ long currentTimeNanos) {
+ int androidKeyCode = javaToAndroidKeyCode(event.getKeyCode(), event.getKeyLocation());
+ int metaState = 0;
+ if (event.isAltDown() | event.isAltGraphDown()) {
+ metaState |= KeyEvent.META_ALT_ON;
+ }
+ if (event.isMetaDown()) {
+ metaState |= KeyEvent.META_META_ON;
+ }
+ if (event.isControlDown()) {
+ metaState |= KeyEvent.META_CTRL_ON;
+ }
+ if (event.isShiftDown()) {
+ metaState |= KeyEvent.META_SHIFT_ON;
+ }
+ try {
+ if (Toolkit.getDefaultToolkit().getLockingKeyState(VK_CAPS_LOCK)) {
+ metaState |= KeyEvent.META_CAPS_LOCK_ON;
+ }
+ if (Toolkit.getDefaultToolkit().getLockingKeyState(VK_NUM_LOCK)) {
+ metaState |= KeyEvent.META_NUM_LOCK_ON;
+ }
+ } catch (UnsupportedOperationException ignore) {
+ }
+ int keyEventType;
+ if (event.getID() == java.awt.event.KeyEvent.KEY_PRESSED) {
+ keyEventType = KeyEvent.ACTION_DOWN;
+ } else {
+ keyEventType = KeyEvent.ACTION_UP;
+ }
+ // Use deviceId 1 as that corresponds to the Generic keyboard.
+ return KeyEvent.obtain(downTimeNanos / TimeUtils.NANOS_PER_MS,
+ currentTimeNanos / TimeUtils.NANOS_PER_MS, keyEventType, androidKeyCode, 0,
+ metaState, 1, 0, 0, InputDevice.SOURCE_KEYBOARD, null);
+ }
+
+ private static int javaToAndroidKeyCode(int keyCode, int location) {
+ switch(keyCode) {
+ case VK_0: return KEYCODE_0;
+ case VK_1: return KEYCODE_1;
+ case VK_2: return KEYCODE_2;
+ case VK_3: return KEYCODE_3;
+ case VK_4: return KEYCODE_4;
+ case VK_5: return KEYCODE_5;
+ case VK_6: return KEYCODE_6;
+ case VK_7: return KEYCODE_7;
+ case VK_8: return KEYCODE_8;
+ case VK_9: return KEYCODE_9;
+
+ case VK_A: return KEYCODE_A;
+ case VK_B: return KEYCODE_B;
+ case VK_C: return KEYCODE_C;
+ case VK_D: return KEYCODE_D;
+ case VK_E: return KEYCODE_E;
+ case VK_F: return KEYCODE_F;
+ case VK_G: return KEYCODE_G;
+ case VK_H: return KEYCODE_H;
+ case VK_I: return KEYCODE_I;
+ case VK_J: return KEYCODE_J;
+ case VK_K: return KEYCODE_K;
+ case VK_L: return KEYCODE_L;
+ case VK_M: return KEYCODE_M;
+ case VK_N: return KEYCODE_N;
+ case VK_O: return KEYCODE_O;
+ case VK_P: return KEYCODE_P;
+ case VK_Q: return KEYCODE_Q;
+ case VK_R: return KEYCODE_R;
+ case VK_S: return KEYCODE_S;
+ case VK_T: return KEYCODE_T;
+ case VK_U: return KEYCODE_U;
+ case VK_V: return KEYCODE_V;
+ case VK_W: return KEYCODE_W;
+ case VK_X: return KEYCODE_X;
+ case VK_Y: return KEYCODE_Y;
+ case VK_Z: return KEYCODE_Z;
+
+ case VK_SPACE: return KEYCODE_SPACE;
+ case VK_ENTER: return KEYCODE_ENTER;
+ case VK_TAB: return KEYCODE_TAB;
+ case VK_COMMA: return KEYCODE_COMMA;
+ case VK_PERIOD: return KEYCODE_PERIOD;
+ case VK_SLASH: return KEYCODE_SLASH;
+ case VK_BACK_QUOTE: return KEYCODE_GRAVE;
+ case VK_MINUS: return KEYCODE_MINUS;
+ case VK_EQUALS: return KEYCODE_EQUALS;
+ case VK_OPEN_BRACKET: return KEYCODE_LEFT_BRACKET;
+ case VK_CLOSE_BRACKET: return KEYCODE_RIGHT_BRACKET;
+ case VK_BACK_SLASH: return KEYCODE_BACKSLASH;
+ case VK_SEMICOLON: return KEYCODE_SEMICOLON;
+ case VK_QUOTE: return KEYCODE_APOSTROPHE;
+
+ case VK_ESCAPE: return KEYCODE_ESCAPE;
+ case VK_BACK_SPACE: return KEYCODE_DEL;
+
+ case VK_NUMPAD0: return KEYCODE_NUMPAD_0;
+ case VK_NUMPAD1: return KEYCODE_NUMPAD_1;
+ case VK_NUMPAD2: return KEYCODE_NUMPAD_2;
+ case VK_NUMPAD3: return KEYCODE_NUMPAD_3;
+ case VK_NUMPAD4: return KEYCODE_NUMPAD_4;
+ case VK_NUMPAD5: return KEYCODE_NUMPAD_5;
+ case VK_NUMPAD6: return KEYCODE_NUMPAD_6;
+ case VK_NUMPAD7: return KEYCODE_NUMPAD_7;
+ case VK_NUMPAD8: return KEYCODE_NUMPAD_8;
+ case VK_NUMPAD9: return KEYCODE_NUMPAD_9;
+ case VK_MULTIPLY: return KEYCODE_NUMPAD_MULTIPLY;
+ case VK_ADD: return KEYCODE_NUMPAD_ADD;
+ case VK_SEPARATOR: return KEYCODE_NUMPAD_COMMA;
+ case VK_SUBTRACT: return KEYCODE_NUMPAD_SUBTRACT;
+ case VK_DECIMAL: return KEYCODE_NUMPAD_DOT;
+ case VK_DIVIDE: return KEYCODE_NUMPAD_DIVIDE;
+
+ case VK_DOWN: return KEYCODE_DPAD_DOWN;
+ case VK_LEFT: return KEYCODE_DPAD_LEFT;
+ case VK_RIGHT: return KEYCODE_DPAD_RIGHT;
+ case VK_UP: return KEYCODE_DPAD_UP;
+
+ case VK_ALT: return KEYCODE_ALT_LEFT;
+ case VK_ALT_GRAPH: return KEYCODE_ALT_RIGHT;
+ case VK_SHIFT: {
+ if (location == KEY_LOCATION_RIGHT) {
+ return KEYCODE_SHIFT_RIGHT;
+ } else {
+ return KEYCODE_SHIFT_LEFT;
+ }
+ }
+ case VK_CONTROL: {
+ if (location == KEY_LOCATION_RIGHT) {
+ return KEYCODE_CTRL_RIGHT;
+ } else {
+ return KEYCODE_CTRL_LEFT;
+ }
+ }
+ case VK_META: {
+ if (location == KEY_LOCATION_RIGHT) {
+ return KEYCODE_META_RIGHT;
+ } else {
+ return KEYCODE_META_LEFT;
+ }
+ }
+
+ case VK_PAGE_DOWN: return KEYCODE_PAGE_DOWN;
+ case VK_PAGE_UP: return KEYCODE_PAGE_UP;
+ case VK_INSERT: return KEYCODE_INSERT;
+ case VK_DELETE: return KEYCODE_FORWARD_DEL;
+ case VK_HOME: return KEYCODE_MOVE_HOME;
+ case VK_END: return KEYCODE_MOVE_END;
+ case VK_PAUSE: return KEYCODE_BREAK;
+
+ case VK_F1: return KEYCODE_F1;
+ case VK_F2: return KEYCODE_F2;
+ case VK_F3: return KEYCODE_F3;
+ case VK_F4: return KEYCODE_F4;
+ case VK_F5: return KEYCODE_F5;
+ case VK_F6: return KEYCODE_F6;
+ case VK_F7: return KEYCODE_F7;
+ case VK_F8: return KEYCODE_F8;
+ case VK_F9: return KEYCODE_F9;
+ case VK_F10: return KEYCODE_F10;
+ case VK_F11: return KEYCODE_F11;
+ case VK_F12: return KEYCODE_F12;
+ }
+
+ return KEYCODE_UNKNOWN;
+ }
+}
diff --git a/delegates/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java b/bridge/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java
index 351d9b4e15..351d9b4e15 100644
--- a/delegates/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java
+++ b/bridge/src/com/android/tools/layoutlib/java/nio/Buffer_Delegate.java
diff --git a/delegates/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java b/bridge/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java
index addcc0bd35..addcc0bd35 100644
--- a/delegates/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java
+++ b/bridge/src/com/android/tools/layoutlib/java/nio/NIOAccess_Delegate.java
diff --git a/delegates/src/dalvik/system/VMRuntimeCommonHelper.java b/bridge/src/dalvik/system/VMRuntimeCommonHelper.java
index ae63625e16..ae63625e16 100644
--- a/delegates/src/dalvik/system/VMRuntimeCommonHelper.java
+++ b/bridge/src/dalvik/system/VMRuntimeCommonHelper.java
diff --git a/bridge/tests/Android.bp b/bridge/tests/Android.bp
index 4aec3ad213..368d093185 100644
--- a/bridge/tests/Android.bp
+++ b/bridge/tests/Android.bp
@@ -26,22 +26,15 @@ java_test_host {
],
java_resource_dirs: ["res"],
- libs: [
- "layoutlib",
- "kxml2-2.3.0",
- "layoutlib_api-prebuilt",
- "tools-common-prebuilt",
- "ninepatch-prebuilt",
- "sdk-common",
- "junit",
- "guava",
+ static_libs: [
+ "kotlin-stdlib",
+ "layoutlib-bridge-client",
"mockito",
+ "ninepatch-prebuilt",
"objenesis",
- "hamcrest",
- "trove-prebuilt",
],
- required: ["layoutlib"],
+ required: ["libandroid_runtime"],
// Copy the jar to DIST_DIR for sdk builds
dist: {
diff --git a/bridge/tests/bridge_tests.iml b/bridge/tests/bridge_tests.iml
new file mode 100644
index 0000000000..8494210f69
--- /dev/null
+++ b/bridge/tests/bridge_tests.iml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/res" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/res/testApp/MyApplication/src/main/myapplication.widgets" isTestSource="true" />
+ <excludeFolder url="file://$MODULE_DIR$/out" />
+ </content>
+ <content url="file://$MODULE_DIR$/res" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module" module-name="bridge" />
+ <orderEntry type="library" name="kotlin-stdlib" level="project" />
+ <orderEntry type="module" module-name="bridge_client" />
+ <orderEntry type="library" name="mockito" level="project" />
+ <orderEntry type="library" name="ninepatch-prebuilt" level="project" />
+ <orderEntry type="library" name="objenesis" level="project" />
+ <orderEntry type="library" name="junit" level="project" />
+ <orderEntry type="library" name="framework.jar" level="project" />
+ <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
+ <orderEntry type="library" name="kxml" level="project" />
+ <orderEntry type="library" name="guava" level="project" />
+ <orderEntry type="library" name="tools-common-prebuilt" level="project" />
+ <orderEntry type="module" module-name="common" />
+ <orderEntry type="module" module-name="validator" />
+ </component>
+</module> \ No newline at end of file
diff --git a/bridge/tests/res/com/android/layoutlib/testdata/wallpaper1.webp b/bridge/tests/res/com/android/layoutlib/testdata/wallpaper1.webp
new file mode 100644
index 0000000000..6460b17b01
--- /dev/null
+++ b/bridge/tests/res/com/android/layoutlib/testdata/wallpaper1.webp
Binary files differ
diff --git a/bridge/tests/res/com/android/layoutlib/testdata/wallpaper2.webp b/bridge/tests/res/com/android/layoutlib/testdata/wallpaper2.webp
new file mode 100644
index 0000000000..786712d078
--- /dev/null
+++ b/bridge/tests/res/com/android/layoutlib/testdata/wallpaper2.webp
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/a11y_test1.png b/bridge/tests/res/testApp/MyApplication/golden/a11y_test1.png
index 067a19363e..7108915e9d 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/a11y_test1.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/a11y_test1.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/activity.png b/bridge/tests/res/testApp/MyApplication/golden/activity.png
index 0dbe45fa86..a05349d73c 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/activity.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/activity.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
index efcd49e750..2d6938aa28 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_circle.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_circle.png
index f85ef1b7fe..5570291230 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_circle.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_circle.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_green.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_green.png
new file mode 100644
index 0000000000..61f1f18af1
--- /dev/null
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_green.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_orange.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_orange.png
new file mode 100644
index 0000000000..dd1dd57027
--- /dev/null
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_dynamic_orange.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_rounded_corners.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_rounded_corners.png
index 3bb70551c2..e0b60374cd 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_rounded_corners.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_rounded_corners.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_squircle.png b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_squircle.png
index f3b3a08d5d..3e41ccc2c1 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_squircle.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/adaptive_icon_squircle.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
index d99df26898..48a40cd191 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
index 5ddd9d2e85..f8cec3261b 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png b/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
index b4bed24937..c00823d326 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/animated_vector.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png b/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
index 37863c7e05..db0b343eb3 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/animated_vector_1.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/array_check.png b/bridge/tests/res/testApp/MyApplication/golden/array_check.png
index db6e934548..ccdd9c180d 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/array_check.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/array_check.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/asset.png b/bridge/tests/res/testApp/MyApplication/golden/asset.png
index 9e587206eb..b6193f61e4 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/asset.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/asset.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/auto-scale-image.png b/bridge/tests/res/testApp/MyApplication/golden/auto-scale-image.png
index 7644183a59..6a23995415 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/auto-scale-image.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/auto-scale-image.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/bitmap_decoder.png b/bridge/tests/res/testApp/MyApplication/golden/bitmap_decoder.png
new file mode 100644
index 0000000000..20f15a9ecd
--- /dev/null
+++ b/bridge/tests/res/testApp/MyApplication/golden/bitmap_decoder.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/button_resize.png b/bridge/tests/res/testApp/MyApplication/golden/button_resize.png
index dc81204ad6..d1ed37b386 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/button_resize.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/button_resize.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/button_resize2.png b/bridge/tests/res/testApp/MyApplication/golden/button_resize2.png
index 9b7957628a..28aa155f9b 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/button_resize2.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/button_resize2.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/canvas.png b/bridge/tests/res/testApp/MyApplication/golden/canvas.png
index 55f84c0073..ff23e2c1f8 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/canvas.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/canvas.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/color_interpolation.png b/bridge/tests/res/testApp/MyApplication/golden/color_interpolation.png
index c816e57273..09efad4f6f 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/color_interpolation.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/color_interpolation.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/context_theme_wrapper.png b/bridge/tests/res/testApp/MyApplication/golden/context_theme_wrapper.png
index 63578fafa9..323d51493e 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/context_theme_wrapper.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/context_theme_wrapper.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/dialog.png b/bridge/tests/res/testApp/MyApplication/golden/dialog.png
index 2f029e5a52..55250f2860 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/dialog.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/dialog.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png b/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
index f179977a92..5ed270620f 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/expand_horz_layout.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png b/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
index 269b7ac4ea..80e72b0199 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/expand_vert_layout.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/font_test.png b/bridge/tests/res/testApp/MyApplication/golden/font_test.png
index e036c162ad..22da766330 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/font_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/font_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/four_corners.png b/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
index fc68ac18d1..82e40ac58e 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/four_corners.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png b/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
index 2aae93b01a..39a1e758d7 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png b/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
index dae944a2ff..7f6663f375 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/four_corners_translucent_land.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/gradient_colors.png b/bridge/tests/res/testApp/MyApplication/golden/gradient_colors.png
index d5b7c101a2..f478afe0dd 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/gradient_colors.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/gradient_colors.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/html.png b/bridge/tests/res/testApp/MyApplication/golden/html.png
new file mode 100644
index 0000000000..9d37ec87b5
--- /dev/null
+++ b/bridge/tests/res/testApp/MyApplication/golden/html.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/justified_inter_word.png b/bridge/tests/res/testApp/MyApplication/golden/justified_inter_word.png
index 48078217cb..dbf22b1c39 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/justified_inter_word.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/justified_inter_word.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/justified_none.png b/bridge/tests/res/testApp/MyApplication/golden/justified_none.png
index e083346b66..e2d44056a0 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/justified_none.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/justified_none.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/large_shadows_test.png b/bridge/tests/res/testApp/MyApplication/golden/large_shadows_test.png
index a79ad55557..045b5235c2 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/large_shadows_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/large_shadows_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/many_line_breaks.png b/bridge/tests/res/testApp/MyApplication/golden/many_line_breaks.png
index ea5750c79c..318ced9328 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/many_line_breaks.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/many_line_breaks.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/ninepatch_background.png b/bridge/tests/res/testApp/MyApplication/golden/ninepatch_background.png
index 014df65928..fefb3b7181 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/ninepatch_background.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/ninepatch_background.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/ninepatch_drawable.png b/bridge/tests/res/testApp/MyApplication/golden/ninepatch_drawable.png
index 211594dfe3..de69d8d2c5 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/ninepatch_drawable.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/ninepatch_drawable.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/ondraw_crash.png b/bridge/tests/res/testApp/MyApplication/golden/ondraw_crash.png
index 8633a259d8..d69667c6b7 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/ondraw_crash.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/ondraw_crash.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/onmeasure_crash.png b/bridge/tests/res/testApp/MyApplication/golden/onmeasure_crash.png
index 5559a89456..4d9f7769d9 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/onmeasure_crash.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/onmeasure_crash.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/remote_component_load.png b/bridge/tests/res/testApp/MyApplication/golden/remote_component_load.png
deleted file mode 100644
index 2920b7d534..0000000000
--- a/bridge/tests/res/testApp/MyApplication/golden/remote_component_load.png
+++ /dev/null
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/remote_component_load_fail.png b/bridge/tests/res/testApp/MyApplication/golden/remote_component_load_fail.png
deleted file mode 100644
index 0ed85d18a4..0000000000
--- a/bridge/tests/res/testApp/MyApplication/golden/remote_component_load_fail.png
+++ /dev/null
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/render_effect.png b/bridge/tests/res/testApp/MyApplication/golden/render_effect.png
index 7a909981e9..792f2bd85f 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/render_effect.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/render_effect.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/rtl_ltr.png b/bridge/tests/res/testApp/MyApplication/golden/rtl_ltr.png
index 40bb188ab2..118e926796 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/rtl_ltr.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/rtl_ltr.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/shadow_scrollview_test.png b/bridge/tests/res/testApp/MyApplication/golden/shadow_scrollview_test.png
index 2f1544f79c..19e65aa167 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/shadow_scrollview_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/shadow_scrollview_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/shadow_sizes_test.png b/bridge/tests/res/testApp/MyApplication/golden/shadow_sizes_test.png
index 301f40f650..84b7299a56 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/shadow_sizes_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/shadow_sizes_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png b/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
index c8dea1bf57..0ef304ec4e 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/shadows_test_rounded_edge.png b/bridge/tests/res/testApp/MyApplication/golden/shadows_test_rounded_edge.png
index d9672f1d4a..7d9a51d793 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/shadows_test_rounded_edge.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/shadows_test_rounded_edge.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png b/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
index d782cd198c..460c199da7 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/simple_activity-old-theme.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png b/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
index efb7ac3ae3..2b2aab8a0e 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/simple_activity.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png b/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
index 36350a04ad..38924a322c 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/simple_activity_noactionbar.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/textclock.png b/bridge/tests/res/testApp/MyApplication/golden/textclock.png
index 108380c4d3..7f1ccc6aff 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/textclock.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/textclock.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/translate_test.png b/bridge/tests/res/testApp/MyApplication/golden/translate_test.png
index 032089f012..741c5e05e6 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/translate_test.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/translate_test.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/transparent_drawable.png b/bridge/tests/res/testApp/MyApplication/golden/transparent_drawable.png
index 68ccf2f91d..3df5385e7d 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/transparent_drawable.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/transparent_drawable.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/typed_arrays.png b/bridge/tests/res/testApp/MyApplication/golden/typed_arrays.png
index e3f4df7c20..dd58a0b56d 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/typed_arrays.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/typed_arrays.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
index ecc4497a3c..b7905fc5bd 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
index 1d4ac397f0..5832c67a71 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_91383.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_gradient.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_gradient.png
index 0268d9c33f..769406e5fb 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_gradient.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_gradient.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_radial_gradient.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_radial_gradient.png
index a27a48eb21..6882d79b87 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_radial_gradient.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_radial_gradient.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_in_image_view.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_in_image_view.png
index 48f0f0542a..759d535f6e 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_in_image_view.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_in_image_view.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_itself.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_itself.png
index 92855d13db..4396a51816 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_itself.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable_with_tint_itself.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/view_boundaries.png b/bridge/tests/res/testApp/MyApplication/golden/view_boundaries.png
index da770e1f94..b1e4a7c505 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/view_boundaries.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/view_boundaries.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/view_stub.png b/bridge/tests/res/testApp/MyApplication/golden/view_stub.png
index b66ff2d524..14566c8f69 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/view_stub.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/view_stub.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/golden/window_background.png b/bridge/tests/res/testApp/MyApplication/golden/window_background.png
index 1d25725e4e..a43d4dfc04 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/window_background.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/window_background.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml b/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
index cc9c449563..80f760a278 100644
--- a/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
+++ b/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/adaptive.xml
@@ -3,4 +3,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/red" />
<foreground android:drawable="@drawable/headset" />
+ <monochrome android:drawable="@drawable/headset" />
</adaptive-icon> \ No newline at end of file
diff --git a/bridge/tests/run_tests.sh b/bridge/tests/run_tests.sh
index de2ed79283..91e88b6c94 100755
--- a/bridge/tests/run_tests.sh
+++ b/bridge/tests/run_tests.sh
@@ -1,58 +1,79 @@
#!/bin/bash
+set -u
readonly OUT_DIR="$1"
readonly DIST_DIR="$2"
-readonly BUILD_NUMBER="$3"
-
readonly SCRIPT_DIR="$(dirname "$0")"
-
+readonly BASE_DIR=`readlink -m ${SCRIPT_DIR}/../../../../`
+echo "BASE_DIR: $BASE_DIR"
readonly FAILURE_DIR=layoutlib-test-failures
readonly FAILURE_ZIP=layoutlib-test-failures.zip
-STUDIO_JDK=${SCRIPT_DIR}"/../../../../prebuilts/jdk/jdk11/linux-x86"
-MISC_COMMON=${SCRIPT_DIR}"/../../../../prebuilts/misc/common"
-OUT_INTERMEDIATES=${SCRIPT_DIR}"/../../../../out/soong/.intermediates"
-NATIVE_LIBRARIES=${SCRIPT_DIR}"/../../../../out/host/linux-x86/lib64/"
-SDK=${SCRIPT_DIR}"/../../../../out/host/linux-x86/sdk/sdk*/android-sdk*"
-SDK_REPO=${SCRIPT_DIR}"/../../../../out/host/linux-x86/sdk-repo"
-FONT_DIR=${SCRIPT_DIR}"/../../../../out/host/common/obj/PACKAGING/fonts_intermediates"
-ICU_DATA_PATH=${SCRIPT_DIR}"/../../../../out/host/linux-x86/com.android.i18n/etc/icu/icudt70l.dat"
-TMP_DIR=$(mktemp -d)
+readonly CLEAN_TMP_FILES=0
+readonly USE_SOONG=1
+
+readonly APP_NAME="regression"
+#readonly APP_NAME="test_HelloActivity"
+
+STUDIO_JDK="${BASE_DIR}/prebuilts/jdk/jdk17/linux-x86"
+MISC_COMMON="${BASE_DIR}/prebuilts/misc/common"
+OUT_INTERMEDIATES="${BASE_DIR}/out/soong/.intermediates"
+NATIVE_LIBRARIES="${BASE_DIR}/out/host/linux-x86/lib64/"
+JAVA_LIBRARIES="${BASE_DIR}/out/host/common/obj/JAVA_LIBRARIES/"
+HOST_LIBRARIES="${BASE_DIR}/out/host/linux-x86/"
+SDK="${BASE_DIR}/out/host/linux-x86/sdk/sdk*/android-sdk*"
+SDK_REPO="${BASE_DIR}/out/host/linux-x86/sdk-repo"
+FONT_DIR="${BASE_DIR}/out/host/common/obj/PACKAGING/fonts_intermediates"
+KEYBOARD_DIR="${BASE_DIR}/out/host/common/obj/PACKAGING/keyboards_intermediates"
+ICU_DATA_PATH="${BASE_DIR}/out/host/linux-x86/com.android.i18n/etc/icu/icudt72l.dat"
+TMP_DIR=${OUT_DIR}"/layoutlib_tmp"
+
PLATFORM=${TMP_DIR}/"android"
-# Copy resources to a temp directory
-cp -r ${SDK}/platforms/android* ${PLATFORM}
+if [ ! -d $TMP_DIR ]; then
+ # Copy resources to a temp directory
+ mkdir -p ${TMP_DIR} ${PLATFORM} ${TMP_DIR}/build-tools ${TMP_DIR}/compiled ${TMP_DIR}/manifest
+
+ cp -r ${SDK}/platforms/android*/** ${PLATFORM}
-# Unzip build-tools to access aapt2
-mkdir ${TMP_DIR}/build-tools
-unzip -q ${SDK_REPO}/sdk-repo-linux-build-tools.zip -d ${TMP_DIR}/build-tools
+ # Unzip build-tools to access aapt2
+ unzip -q ${SDK_REPO}/sdk-repo-linux-build-tools.zip -d ${TMP_DIR}/build-tools
-# Compile 9-patch files
-mkdir ${TMP_DIR}/compiled
-mkdir ${TMP_DIR}/manifest
-echo \
+ # Compile 9-patch files
+ echo \
'<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.android.layoutlib" />' \
> ${TMP_DIR}/manifest/AndroidManifest.xml
-find ${SDK}/platforms/android*/data/res -name "*.9.png" -print0 | xargs -0 ${TMP_DIR}/build-tools/android-*/aapt2 compile -o ${TMP_DIR}/compiled/
-find ${TMP_DIR}/compiled -name "*.flat" -print0 | xargs -0 -s 1000000 ${TMP_DIR}/build-tools/android-*/aapt2 link -o ${TMP_DIR}/compiled.apk --manifest ${TMP_DIR}/manifest/AndroidManifest.xml -R
-unzip -q ${TMP_DIR}/compiled.apk -d ${TMP_DIR}
-for f in ${TMP_DIR}/res/*; do mv "$f" "${f/-v4/}";done
-cp -RL ${TMP_DIR}/res ${PLATFORM}/data
+ find ${SDK}/platforms/android*/data/res -name "*.9.png" -print0 | xargs -0 ${TMP_DIR}/build-tools/android-*/aapt2 compile -o ${TMP_DIR}/compiled/
+ find ${TMP_DIR}/compiled -name "*.flat" -print0 | xargs -0 -s 1000000 ${TMP_DIR}/build-tools/android-*/aapt2 link -o ${TMP_DIR}/compiled.apk --manifest ${TMP_DIR}/manifest/AndroidManifest.xml -R
+ unzip -q ${TMP_DIR}/compiled.apk -d ${TMP_DIR}
+ for f in ${TMP_DIR}/res/*; do mv "$f" "${f/-v4/}";done
+ cp -RL ${TMP_DIR}/res ${PLATFORM}/data
+fi
+
+
+TEST_JARS="${OUT_INTERMEDIATES}/frameworks/layoutlib/bridge/tests/layoutlib-tests/linux_glibc_common/withres/layoutlib-tests.jar"
+GRADLE_RES="-Dtest_res.dir=${SCRIPT_DIR}/res"
# Run layoutlib tests
-${STUDIO_JDK}/bin/java -ea \
+#DEBUGGER=' -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 '
+DEBUGGER=' '
+
+set -x
+${STUDIO_JDK}/bin/java -ea $DEBUGGER \
-Dnative.lib.path=${NATIVE_LIBRARIES} \
-Dfont.dir=${FONT_DIR} \
-Dicu.data.path=${ICU_DATA_PATH} \
+ -Dkeyboard.dir=${KEYBOARD_DIR} \
-Dplatform.dir=${PLATFORM} \
- -Dtest_res.dir=${SCRIPT_DIR}/res \
-Dtest_failure.dir=${OUT_DIR}/${FAILURE_DIR} \
- -cp ${MISC_COMMON}/tools-common/tools-common-prebuilt.jar:${MISC_COMMON}/ninepatch/ninepatch-prebuilt.jar:${MISC_COMMON}/sdk-common/sdk-common.jar:${MISC_COMMON}/kxml2/kxml2-2.3.0.jar:${MISC_COMMON}/layoutlib_api/layoutlib_api-prebuilt.jar:${OUT_INTERMEDIATES}/prebuilts/tools/common/m2/trove-prebuilt/linux_glibc_common/combined/trove-prebuilt.jar:${OUT_INTERMEDIATES}/external/junit/junit/linux_glibc_common/javac/junit.jar:${OUT_INTERMEDIATES}/external/guava/guava-jre/linux_glibc_common/javac/guava-jre.jar:${OUT_INTERMEDIATES}/external/hamcrest/hamcrest-core/hamcrest/linux_glibc_common/javac/hamcrest.jar:${OUT_INTERMEDIATES}/external/mockito/mockito/linux_glibc_common/combined/mockito.jar:${OUT_INTERMEDIATES}/external/objenesis/objenesis/linux_glibc_common/javac/objenesis.jar:${OUT_INTERMEDIATES}/frameworks/layoutlib/bridge/layoutlib/linux_glibc_common/withres/layoutlib.jar:${OUT_INTERMEDIATES}/frameworks/layoutlib/temp_layoutlib/linux_glibc_common/gen/temp_layoutlib.jar:${OUT_INTERMEDIATES}/frameworks/layoutlib/bridge/tests/layoutlib-tests/linux_glibc_common/withres/layoutlib-tests.jar \
+ ${GRADLE_RES} \
+ -cp ${TEST_JARS} \
org.junit.runner.JUnitCore \
com.android.layoutlib.bridge.intensive.Main
-
test_exit_code=$?
+set +x
+
# Create zip of all failure screenshots
if [[ -d "${OUT_DIR}/${FAILURE_DIR}" ]]; then
@@ -65,7 +86,9 @@ if [[ -d "${DIST_DIR}" ]] && [[ -e "${OUT_DIR}/${FAILURE_ZIP}" ]]; then
fi
# Clean
-rm -rf ${TMP_DIR}
-rm -rf ${OUT_DIR}/${FAILURE_DIR}
+if [[ $CLEAN_TMP_FILES -eq 1 ]]; then
+ rm -rf ${TMP_DIR}
+ rm -rf ${OUT_DIR}/${FAILURE_DIR}
+fi
exit ${test_exit_code}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/android/AccessibilityTest.java b/bridge/tests/src/com/android/layoutlib/bridge/android/AccessibilityTest.java
new file mode 100644
index 0000000000..ed90d9b60c
--- /dev/null
+++ b/bridge/tests/src/com/android/layoutlib/bridge/android/AccessibilityTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.android.layoutlib.bridge.android;
+
+import com.android.ide.common.rendering.api.RenderSession;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.intensive.LayoutLibTestCallback;
+import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
+import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.io.FileNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class AccessibilityTest extends RenderTestBase {
+ @BeforeClass
+ public static void setUp() {
+ Bridge.prepareThread();
+ }
+
+ @Test
+ public void accessibilityNodeInfoCreation() throws FileNotFoundException,
+ ClassNotFoundException {
+ LayoutPullParser parser = createParserFromPath("allwidgets.xml");
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParamsBuilder()
+ .setParser(parser)
+ .setConfigGenerator(ConfigGenerator.NEXUS_5)
+ .setCallback(layoutLibCallback)
+ .build();
+ RenderSession session = sBridge.createSession(params);
+ try {
+ Result renderResult = session.render(50000);
+ assertTrue(renderResult.isSuccess());
+ View rootView = (View)session.getSystemRootViews().get(0).getViewObject();
+ AccessibilityNodeInfo rootNode = rootView.createAccessibilityNodeInfo();
+ assertNotNull(rootNode);
+ rootNode.setQueryFromAppProcessEnabled(rootView, true);
+ assertEquals(38, rootNode.getChildCount());
+ AccessibilityNodeInfo child = rootNode.getChild(0);
+ assertNotNull(child);
+ assertEquals(136, child.getBoundsInScreen().right);
+ assertEquals(75, child.getBoundsInScreen().bottom);
+ } finally {
+ session.dispose();
+ }
+ }
+}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/android/BitmapTest.java b/bridge/tests/src/com/android/layoutlib/bridge/android/BitmapTest.java
index 67d21e9a1f..4c0ac4ce30 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/android/BitmapTest.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/android/BitmapTest.java
@@ -16,17 +16,28 @@
package com.android.layoutlib.bridge.android;
+import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.intensive.RenderTestBase;
+import com.android.layoutlib.bridge.impl.RenderAction;
+import com.android.layoutlib.bridge.impl.RenderActionTestUtil;
+import com.android.layoutlib.bridge.intensive.LayoutLibTestCallback;
+import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.ninepatch.NinePatch;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
+import android.R;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.ImageDecoder;
+import android.graphics.ImageDecoder.Source;
+import android.util.DisplayMetrics;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
@@ -53,15 +64,54 @@ public class BitmapTest extends RenderTestBase {
Assert.assertArrayEquals(compiledBitmap.getNinePatchChunk(), ninePatch.getChunk().getSerializedChunk());
}
+// @Test
+// public void testNativeBitmap() {
+// InputStream compiled =
+// getClass().getResourceAsStream("/com/android/layoutlib/testdata/compiled.9.png");
+// Bitmap compiledBitmap = BitmapFactory.decodeStream(compiled, null, null);
+// assertNotNull(compiledBitmap);
+// Buffer buffer = ByteBuffer.allocate(compiledBitmap.getByteCount());
+// compiledBitmap.copyPixelsToBuffer(buffer);
+// buffer.rewind();
+// compiledBitmap.copyPixelsFromBuffer(buffer);
+// }
+
@Test
- public void testNativeBitmap() {
- InputStream compiled =
- getClass().getResourceAsStream("/com/android/layoutlib/testdata/compiled.9.png");
- Bitmap compiledBitmap = BitmapFactory.decodeStream(compiled, null, null);
- assertNotNull(compiledBitmap);
- Buffer buffer = ByteBuffer.allocate(compiledBitmap.getByteCount());
- compiledBitmap.copyPixelsToBuffer(buffer);
- buffer.rewind();
- compiledBitmap.copyPixelsFromBuffer(buffer);
+ public void testImageDecoder() throws Exception {
+ // Setup
+ // Create the layout pull parser for our resources (empty.xml can not be part of the test
+ // app as it won't compile).
+ LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
+ // Create LayoutLibCallback.
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParamsBuilder()
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material", false)
+ .build();
+ DisplayMetrics metrics = new DisplayMetrics();
+ Configuration configuration = RenderAction.getConfiguration(params);
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ params.getAssets(), params.getLayoutlibCallback(), configuration,
+ params.getTargetSdkVersion(), params.isRtlSupported());
+
+ context.initResources(params.getAssets());
+ BridgeContext oldContext = RenderActionTestUtil.setBridgeContext(context);
+ try {
+ Source source = ImageDecoder.createSource(context.getResources(),
+ R.drawable.button_onoff_indicator_on);
+ Bitmap bitmap = ImageDecoder.decodeBitmap(source);
+ BufferedImage image = new BufferedImage(bitmap.getWidth(), bitmap.getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+ int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
+ bitmap.getPixels(imageData, 0, image.getWidth(), 0, 0, image.getWidth(),
+ image.getHeight());
+ verify("bitmap_decoder.png", image);
+ } finally {
+ RenderActionTestUtil.setBridgeContext(oldContext);
+ context.disposeResources();
+ }
}
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeContextTest.java b/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeContextTest.java
index 5266c57909..b12adc93e4 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeContextTest.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeContextTest.java
@@ -20,8 +20,7 @@ import com.android.ide.common.rendering.api.SessionParams;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.layoutlib.bridge.impl.RenderActionTestUtil;
-import com.android.layoutlib.bridge.intensive.RenderTestBase;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
+import com.android.layoutlib.bridge.intensive.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import org.junit.BeforeClass;
@@ -32,9 +31,12 @@ import android.R.style;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
+import android.os.PowerManager;
import android.util.DisplayMetrics;
import android.view.ContextThemeWrapper;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -148,4 +150,58 @@ public class BridgeContextTest extends RenderTestBase {
assertNull(context.getSystemService("my_custom_service"));
sRenderMessages.removeIf(message -> message.equals("Service my_custom_service was not found or is unsupported"));
}
+
+ @Test
+ public void dynamicTheming() throws ClassNotFoundException {
+ LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParamsBuilder()
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material", false)
+ .build();
+ DisplayMetrics metrics = new DisplayMetrics();
+ Configuration configuration = RenderAction.getConfiguration(params);
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ params.getAssets(), params.getLayoutlibCallback(), configuration,
+ params.getTargetSdkVersion(), params.isRtlSupported());
+ context.initResources(params.getAssets());
+ try {
+ assertEquals(-13749965, context.getResources().getColor(android.R.color.system_neutral1_800, null));
+
+ ((DynamicRenderResources) context.getRenderResources()).setWallpaper(
+ "/com/android/layoutlib/testdata/wallpaper1.webp",
+ configuration.isNightModeActive());
+ assertEquals(-13226195, context.getResources().getColor(android.R.color.system_neutral1_800, null));
+
+ ((DynamicRenderResources) context.getRenderResources()).setWallpaper(
+ "/com/android/layoutlib/testdata/wallpaper2.webp",
+ configuration.isNightModeActive());
+ assertEquals(-13749969, context.getResources().getColor(android.R.color.system_neutral1_800, null));
+ } finally {
+ context.disposeResources();
+ }
+ }
+
+ @Test
+ public void noCrashInPowerManager() throws ClassNotFoundException {
+ LayoutPullParser parser = LayoutPullParser.createFromPath("/empty.xml");
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
+ "Theme.Material", false).build();
+ DisplayMetrics metrics = new DisplayMetrics();
+ Configuration configuration = RenderAction.getConfiguration(params);
+ BridgeContext context =
+ new BridgeContext(params.getProjectKey(), metrics, params.getResources(), params.getAssets(), params.getLayoutlibCallback(), configuration,
+ params.getTargetSdkVersion(), params.isRtlSupported());
+
+ PowerManager powerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ // Check that the following calls do not trigger a native crash
+ assertFalse(powerManager.isPowerSaveMode());
+ assertTrue(powerManager.isInteractive());
+ }
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/android/DynamicRenderResourcesTest.java b/bridge/tests/src/com/android/layoutlib/bridge/android/DynamicRenderResourcesTest.java
new file mode 100644
index 0000000000..16a809b3e7
--- /dev/null
+++ b/bridge/tests/src/com/android/layoutlib/bridge/android/DynamicRenderResourcesTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.Bridge;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class DynamicRenderResourcesTest extends RenderTestBase {
+ @BeforeClass
+ public static void setUp() {
+ Bridge.prepareThread();
+ }
+
+ @Test
+ public void createDynamicTheme() {
+ Map<String, Integer> dynamicColorMap = DynamicRenderResources.createDynamicColorMap(
+ "/com/android/layoutlib/testdata/wallpaper1.webp", false);
+ assertNotNull(dynamicColorMap);
+ assertEquals(-1, (int)dynamicColorMap.get("system_accent1_0"));
+ assertEquals(-4632, (int)dynamicColorMap.get("system_accent1_50"));
+ assertEquals(-1403268, (int)dynamicColorMap.get("system_accent1_300"));
+ assertEquals(-11198451, (int)dynamicColorMap.get("system_accent1_800"));
+ assertEquals(-1, (int)dynamicColorMap.get("system_accent2_0"));
+ assertEquals(-4632, (int)dynamicColorMap.get("system_accent2_50"));
+ assertEquals(-3497321, (int)dynamicColorMap.get("system_accent2_300"));
+ assertEquals(-12309982, (int)dynamicColorMap.get("system_accent2_800"));
+ assertEquals(-1, (int)dynamicColorMap.get("system_accent3_0"));
+ assertEquals(-3900, (int)dynamicColorMap.get("system_accent3_50"));
+ assertEquals(-4478092, (int)dynamicColorMap.get("system_accent3_300"));
+ assertEquals(-12963835, (int)dynamicColorMap.get("system_accent3_800"));
+ assertEquals(-1, (int)dynamicColorMap.get("system_neutral1_0"));
+ assertEquals(-266518, (int)dynamicColorMap.get("system_neutral1_50"));
+ assertEquals(-4937306, (int)dynamicColorMap.get("system_neutral1_300"));
+ assertEquals(-13226195, (int)dynamicColorMap.get("system_neutral1_800"));
+ assertEquals(-1, (int)dynamicColorMap.get("system_neutral2_0"));
+ assertEquals(-4632, (int)dynamicColorMap.get("system_neutral2_50"));
+ assertEquals(-4413535, (int)dynamicColorMap.get("system_neutral2_300"));
+ assertEquals(-12899031, (int)dynamicColorMap.get("system_neutral2_800"));
+ }
+}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/android/RenderTestBase.java b/bridge/tests/src/com/android/layoutlib/bridge/android/RenderTestBase.java
new file mode 100644
index 0000000000..ee41c6cd41
--- /dev/null
+++ b/bridge/tests/src/com/android/layoutlib/bridge/android/RenderTestBase.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.layoutlib.bridge.android;
+
+import org.junit.Before;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Locale;
+
+import com.android.layoutlib.bridge.intensive.BridgeClient;
+
+public class RenderTestBase extends BridgeClient {
+ private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
+ public static final String S_PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
+
+ public String getAppTestDir() {
+ return "testApp/MyApplication";
+ }
+
+ public String getAppTestRes() {
+ return getBaseResourceDir() + "/" + getAppTestDir() + "/src/main/res";
+ }
+
+ public String getAppResources() {
+ return getAppTestDir() + "/src/main/res";
+ }
+
+ public String getAppTestAsset() {
+ return getBaseResourceDir() + "/" + getAppTestDir() + "/src/main/assets/";
+ }
+
+ public String getAppClassesLocation() {
+ return getAppTestDir()
+ + "/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/";
+ }
+
+ public String getAppGoldenDir() {
+ String goldenImagePath = getAppTestDir();
+ boolean isMac = System.getProperty("os.name").toLowerCase(Locale.US).contains("mac");
+ if (isMac) {
+ goldenImagePath += "/golden-mac/";
+ } else {
+ goldenImagePath += "/golden/";
+ }
+ return goldenImagePath;
+ }
+
+ private static String getBaseResourceDir() {
+ String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
+ if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
+ return resourceDir;
+ }
+ // resource directory not explicitly set. Fallback to the class's source location.
+ try {
+ URL location = RenderTestBase.class.getProtectionDomain().getCodeSource().getLocation();
+ return new File(location.getPath()).exists() ? location.getPath() : null;
+ } catch (NullPointerException e) {
+ // Prevent a lot of null checks by just catching the exception.
+ return null;
+ }
+ }
+
+ @Before
+ public void initPackageName() {
+ setPackageName(S_PACKAGE_NAME);
+ }
+
+}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java b/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java
index aedd845ce4..d88f77a0ee 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/impl/ResourceHelperTest.java
@@ -99,4 +99,10 @@ public class ResourceHelperTest {
assertEquals(ends[i], spanned.getSpanEnd(spans[i]));
}
}
+
+ @Test
+ public void testParsePlainHtml() {
+ String plainText = "This text has no html tags";
+ assertEquals(plainText, ResourceHelper.parseHtml(plainText));
+ }
} \ No newline at end of file
diff --git a/delegates/src/com/android/tools/layoutlib/java/text/DateFormat_Delegate.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/LayoutLibTestCallback.java
index cb72c2d060..23b80e9e2f 100644
--- a/delegates/src/com/android/tools/layoutlib/java/text/DateFormat_Delegate.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/LayoutLibTestCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2014 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,19 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.tools.layoutlib.java.text;
-import java.text.DateFormat;
+package com.android.layoutlib.bridge.intensive;
-/**
- * Provides alternate implementation to java.text.DateFormat.set24HourTimePref, which is present
- * as a
- * non-public method in the Android VM, but not present on the host VM. This is injected in the
- * layoutlib using {@link ReplaceMethodCallsAdapter}.
- */
-public class DateFormat_Delegate {
+import com.android.utils.ILogger;
+import com.android.layoutlib.bridge.intensive.setup.LayoutlibBridgeClientCallback;
+
+public class LayoutLibTestCallback extends LayoutlibBridgeClientCallback {
+ private static final String S_PACKAGE_NAME = "com.android.layoutlib.test.myapplication";
- public static final void set24HourTimePref(Boolean is24Hour) {
- // ignore
+ public LayoutLibTestCallback(ILogger logger, ClassLoader classLoader) {
+ super(logger, classLoader, S_PACKAGE_NAME);
}
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index 2c69f3a2e9..95ec97de36 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -18,9 +18,11 @@ package com.android.layoutlib.bridge.intensive;
import com.android.layoutlib.bridge.BridgeRenderSessionTest;
import com.android.layoutlib.bridge.TestDelegates;
+import com.android.layoutlib.bridge.android.AccessibilityTest;
import com.android.layoutlib.bridge.android.BitmapTest;
import com.android.layoutlib.bridge.android.BridgeContextTest;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParserTest;
+import com.android.layoutlib.bridge.android.DynamicRenderResourcesTest;
import com.android.layoutlib.bridge.impl.LayoutParserWrapperTest;
import com.android.layoutlib.bridge.impl.ResourceHelperTest;
import com.android.tools.idea.validator.LayoutValidatorTests;
@@ -45,7 +47,8 @@ import android.util.BridgeXmlPullAttributesTest;
TestDelegates.class, BridgeRenderSessionTest.class, ResourceHelperTest.class,
BridgeContextTest.class, Resources_DelegateTest.class, ShadowsRenderTests.class,
LayoutValidatorTests.class, AccessibilityValidatorTests.class, BridgeTypedArrayTest.class,
- ValidatorResultTests.class, BitmapTest.class
+ ValidatorResultTests.class, BitmapTest.class, DynamicRenderResourcesTest.class,
+ AccessibilityTest.class
})
public class Main {
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
index 4d7438fd3a..0572bf4760 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/PerformanceTests.java
@@ -17,6 +17,7 @@
package com.android.layoutlib.bridge.intensive;
import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.android.RenderTestBase;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
import com.android.layoutlib.bridge.intensive.util.perf.PerformanceRunner;
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
index 91c79c9587..7b9c163634 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
@@ -29,12 +29,12 @@ import com.android.internal.R;
import com.android.internal.lang.System_Delegate;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
+import com.android.layoutlib.bridge.android.RenderTestBase;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.RenderAction;
import com.android.layoutlib.bridge.impl.RenderActionTestUtil;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.resources.Density;
import com.android.resources.Navigation;
@@ -67,6 +67,7 @@ import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;
@@ -101,20 +102,26 @@ public class RenderTests extends RenderTestBase {
LayoutPullParser parser = LayoutPullParser.createFromString(
"<RelativeLayout xmlns:android=\"http://schemas" +
- ".android.com/apk/res/android\"\n" +
- " android:layout_width=\"match_parent\"\n" +
- " android:layout_height=\"match_parent\"\n" +
- " android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
- " android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
- " android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
- " android:paddingBottom=\"@dimen/activity_vertical_margin\">\n" +
- " <TextView\n" +
- " android:text=\"@string/hello_world\"\n" +
- " android:layout_width=\"wrap_content\"\n" +
- " android:layout_height=\"200dp\"\n" +
- " android:background=\"#FF0000\"\n" +
- " android:id=\"@+id/text1\"/>\n" +
- "</RelativeLayout>");
+ ".android.com/apk/res/android\"\n" +
+ " android:layout_width=\"match_parent\"\n" +
+ " android:layout_height=\"match_parent\"\n" +
+ " android:paddingLeft=\"@dimen/activity_horizontal_margin"
+ + "\"\n"
+ +
+ " android:paddingRight=\"@dimen/activity_horizontal_margin"
+ + "\"\n"
+ +
+ " android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
+ " android:paddingBottom=\"@dimen/activity_vertical_margin"
+ + "\">\n"
+ +
+ " <TextView\n" +
+ " android:text=\"@string/hello_world\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"200dp\"\n" +
+ " android:background=\"#FF0000\"\n" +
+ " android:id=\"@+id/text1\"/>\n" +
+ "</RelativeLayout>");
SessionParams params = getSessionParamsBuilder()
.setParser(parser)
.setCallback(layoutLibCallback)
@@ -149,10 +156,10 @@ public class RenderTests extends RenderTestBase {
parser = createParserFromPath("four_corners.xml");
params = getSessionParamsBuilder()
- .setParser(parser)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.Light.NoActionBar", false)
- .build();
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.Light.NoActionBar", false)
+ .build();
renderAndVerify(params, "four_corners.png");
}
@@ -194,19 +201,25 @@ public class RenderTests extends RenderTestBase {
public void testActivityActionBar() throws ClassNotFoundException {
String simpleActivity =
"<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
- " android:layout_width=\"match_parent\"\n" +
- " android:layout_height=\"match_parent\"\n" +
- " android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n" +
- " android:paddingRight=\"@dimen/activity_horizontal_margin\"\n" +
- " android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
- " android:paddingBottom=\"@dimen/activity_vertical_margin\">\n" +
- " <TextView\n" +
- " android:text=\"@string/hello_world\"\n" +
- " android:layout_width=\"wrap_content\"\n" +
- " android:layout_height=\"200dp\"\n" +
- " android:background=\"#FF0000\"\n" +
- " android:id=\"@+id/text1\"/>\n" +
- "</RelativeLayout>";
+ " android:layout_width=\"match_parent\"\n" +
+ " android:layout_height=\"match_parent\"\n" +
+ " android:paddingLeft=\"@dimen/activity_horizontal_margin"
+ + "\"\n"
+ +
+ " android:paddingRight=\"@dimen/activity_horizontal_margin"
+ + "\"\n"
+ +
+ " android:paddingTop=\"@dimen/activity_vertical_margin\"\n" +
+ " android:paddingBottom=\"@dimen/activity_vertical_margin"
+ + "\">\n"
+ +
+ " <TextView\n" +
+ " android:text=\"@string/hello_world\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"200dp\"\n" +
+ " android:background=\"#FF0000\"\n" +
+ " android:id=\"@+id/text1\"/>\n" +
+ "</RelativeLayout>";
LayoutPullParser parser = LayoutPullParser.createFromString(simpleActivity);
LayoutLibTestCallback layoutLibCallback =
@@ -224,11 +237,11 @@ public class RenderTests extends RenderTestBase {
parser = LayoutPullParser.createFromString(simpleActivity);
params = getSessionParamsBuilder()
- .setParser(parser)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.Light", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.Light", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
renderAndVerify(params, "simple_activity.png");
@@ -236,11 +249,11 @@ public class RenderTests extends RenderTestBase {
// displaying menus.
parser = LayoutPullParser.createFromString(simpleActivity);
params = getSessionParamsBuilder()
- .setParser(parser)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.Light.NoActionBar", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.Light.NoActionBar", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
params.setFlag(RenderParamsFlags.FLAG_KEY_ROOT_TAG, "menu");
renderAndVerify(params, "simple_activity.png");
}
@@ -253,19 +266,19 @@ public class RenderTests extends RenderTestBase {
Class insetsWidgetClass = Class.forName("com.android.layoutlib.test.myapplication.widgets" +
".InsetsWidget");
Field field = insetsWidgetClass.getDeclaredField("sApplyInsetsCalled");
- assertFalse((Boolean)field.get(null));
+ assertFalse((Boolean) field.get(null));
LayoutPullParser parser = LayoutPullParser.createFromString(
"<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
- " android:padding=\"16dp\"\n" +
- " android:orientation=\"horizontal\"\n" +
- " android:layout_width=\"wrap_content\"\n" +
- " android:layout_height=\"wrap_content\">\n" + "\n" +
- " <com.android.layoutlib.test.myapplication.widgets.InsetsWidget\n" +
- " android:text=\"Hello world\"\n" +
- " android:layout_width=\"wrap_content\"\n" +
- " android:layout_height=\"wrap_content\"\n" +
- " android:id=\"@+id/text1\"/>\n" + "</LinearLayout>\n");
+ " android:padding=\"16dp\"\n" +
+ " android:orientation=\"horizontal\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"wrap_content\">\n" + "\n" +
+ " <com.android.layoutlib.test.myapplication.widgets.InsetsWidget\n" +
+ " android:text=\"Hello world\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"wrap_content\"\n" +
+ " android:id=\"@+id/text1\"/>\n" + "</LinearLayout>\n");
LayoutLibTestCallback layoutLibCallback =
new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
layoutLibCallback.initResources();
@@ -277,7 +290,7 @@ public class RenderTests extends RenderTestBase {
render(sBridge, params, -1);
- assertTrue((Boolean)field.get(null));
+ assertTrue((Boolean) field.get(null));
field.set(null, false);
}
@@ -314,12 +327,12 @@ public class RenderTests extends RenderTestBase {
.setNavigation(Navigation.NONAV);
parser = createParserFromPath("expand_horz_layout.xml");
params = getSessionParamsBuilder()
- .setParser(parser)
- .setConfigGenerator(customConfigGenerator)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.Light.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.H_SCROLL)
- .build();
+ .setParser(parser)
+ .setConfigGenerator(customConfigGenerator)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.Light.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.H_SCROLL)
+ .build();
renderAndVerify(params, "expand_horz_layout.png");
}
@@ -399,11 +412,11 @@ public class RenderTests extends RenderTestBase {
parser = LayoutPullParser.createFromString(layout);
params = getSessionParamsBuilder()
- .setParser(parser)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
renderAndVerify(params, "animated_vector_1.png", TimeUnit.SECONDS.toNanos(3));
}
@@ -415,16 +428,16 @@ public class RenderTests extends RenderTestBase {
public void testVectorDrawable() throws ClassNotFoundException {
// Create the layout pull parser.
LayoutPullParser parser = LayoutPullParser.createFromString(
- "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
- " android:padding=\"16dp\"\n" +
- " android:orientation=\"horizontal\"\n" +
- " android:layout_width=\"fill_parent\"\n" +
- " android:layout_height=\"fill_parent\">\n" +
- " <ImageView\n" +
- " android:layout_height=\"fill_parent\"\n" +
- " android:layout_width=\"fill_parent\"\n" +
- " android:src=\"@drawable/multi_path\" />\n" + "\n" +
- "</LinearLayout>");
+ "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+ " android:padding=\"16dp\"\n" +
+ " android:orientation=\"horizontal\"\n" +
+ " android:layout_width=\"fill_parent\"\n" +
+ " android:layout_height=\"fill_parent\">\n" +
+ " <ImageView\n" +
+ " android:layout_height=\"fill_parent\"\n" +
+ " android:layout_width=\"fill_parent\"\n" +
+ " android:src=\"@drawable/multi_path\" />\n" + "\n" +
+ "</LinearLayout>");
// Create LayoutLibCallback.
LayoutLibTestCallback layoutLibCallback =
new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
@@ -792,12 +805,12 @@ public class RenderTests extends RenderTestBase {
parser = createParserFromPath("scrolled.xml");
params = getSessionParamsBuilder()
- .setParser(parser)
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .disableDecoration()
- .build();
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .disableDecoration()
+ .build();
params.setExtendedViewInfoMode(true);
result = renderAndVerify(params, "scrolled.png");
@@ -824,7 +837,8 @@ public class RenderTests extends RenderTestBase {
AssetManager assetManager = AssetManager.getSystem();
DisplayMetrics metrics = new DisplayMetrics();
Configuration configuration = RenderAction.getConfiguration(params);
- BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics,
+ params.getResources(),
params.getAssets(), params.getLayoutlibCallback(), configuration,
params.getTargetSdkVersion(), params.isRtlSupported());
Resources resources = Resources_Delegate.initSystem(context, assetManager, metrics,
@@ -866,7 +880,8 @@ public class RenderTests extends RenderTestBase {
AssetManager assetManager = AssetManager.getSystem();
DisplayMetrics metrics = new DisplayMetrics();
Configuration configuration = RenderAction.getConfiguration(params);
- BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics,
+ params.getResources(),
params.getAssets(), params.getLayoutlibCallback(), configuration,
params.getTargetSdkVersion(), params.isRtlSupported());
Resources resources = Resources_Delegate.initSystem(context, assetManager, metrics,
@@ -915,46 +930,46 @@ public class RenderTests extends RenderTestBase {
new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
layoutLibCallback.initResources();
- layoutLibCallback.setAdaptiveIconMaskPath("M50,0L100,0 100,100 0,100 0,0z");
SessionParams params = getSessionParamsBuilder()
.setParser(parser)
.setCallback(layoutLibCallback)
.setTheme("Theme.Material.NoActionBar.Fullscreen", false)
.setRenderingMode(RenderingMode.V_SCROLL)
.build();
-
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50,0L100,0 100,100 0,100 0,0z");
renderAndVerify(params, "adaptive_icon.png");
- layoutLibCallback.setAdaptiveIconMaskPath(
+ params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
"M50 0C77.6 0 100 22.4 100 50C100 77.6 77.6 100 50 100C22.4 100 0 77.6 0 50C0 " +
"22.4 22.4 0 50 0Z");
- params = getSessionParamsBuilder()
- .setParser(LayoutPullParser.createFromString(layout))
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
renderAndVerify(params, "adaptive_icon_circle.png");
- layoutLibCallback.setAdaptiveIconMaskPath(
+ params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
"M50,0L92,0C96.42,0 100,4.58 100 8L100,92C100, 96.42 96.42 100 92 100L8 100C4.58," +
" 100 0 96.42 0 92L0 8 C 0 4.42 4.42 0 8 0L50 0Z");
- params = getSessionParamsBuilder()
- .setParser(LayoutPullParser.createFromString(layout))
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
renderAndVerify(params, "adaptive_icon_rounded_corners.png");
- layoutLibCallback.setAdaptiveIconMaskPath(
- "M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z");
params = getSessionParamsBuilder()
- .setParser(LayoutPullParser.createFromString(layout))
- .setCallback(layoutLibCallback)
- .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
- .setRenderingMode(RenderingMode.V_SCROLL)
- .build();
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z");
renderAndVerify(params, "adaptive_icon_squircle.png");
}
@@ -1000,20 +1015,31 @@ public class RenderTests extends RenderTestBase {
mContext.resolveThemeAttribute(android.R.attr.isLightTheme, outValue, true);
assertEquals(TypedValue.TYPE_INT_BOOLEAN, outValue.type);
assertEquals(1, outValue.data);
+
+ outValue = new TypedValue();
+ mContext.resolveThemeAttribute(android.R.attr.scrollbarFadeDuration, outValue, true);
+ assertEquals(TypedValue.TYPE_INT_DEC, outValue.type);
+ assertEquals(250, outValue.data);
+
+ outValue = new TypedValue();
+ mContext.resolveThemeAttribute(android.R.attr.scrollbarThumbHorizontal, outValue, true);
+ assertEquals(TypedValue.TYPE_STRING, outValue.type);
+ assertNotNull(outValue.string);
assertTrue(sRenderMessages.isEmpty());
}
@Test
public void testColorStateList() throws Exception {
- final String STATE_LIST = "<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n" +
- " <item android:state_pressed=\"true\"\n" +
- " android:color=\"?android:attr/colorForeground\"/> \n" +
- " <item android:state_focused=\"true\"\n" +
- " android:color=\"?android:attr/colorBackground\"/> \n" +
- " <item android:color=\"#a000\"/> <!-- default -->\n" + "</selector>";
+ final String STATE_LIST =
+ "<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n" +
+ " <item android:state_pressed=\"true\"\n" +
+ " android:color=\"?android:attr/colorForeground\"/> \n" +
+ " <item android:state_focused=\"true\"\n" +
+ " android:color=\"?android:attr/colorBackground\"/> \n" +
+ " <item android:color=\"#a000\"/> <!-- default -->\n" + "</selector>";
File tmpColorList = File.createTempFile("statelist", "xml");
- try(PrintWriter output = new PrintWriter(new FileOutputStream(tmpColorList))) {
+ try (PrintWriter output = new PrintWriter(new FileOutputStream(tmpColorList))) {
output.println(STATE_LIST);
}
@@ -1126,7 +1152,8 @@ public class RenderTests extends RenderTestBase {
AssetManager assetManager = AssetManager.getSystem();
DisplayMetrics metrics = new DisplayMetrics();
Configuration configuration = RenderAction.getConfiguration(params);
- BridgeContext context = new BridgeContext(params.getProjectKey(), metrics, params.getResources(),
+ BridgeContext context = new BridgeContext(params.getProjectKey(), metrics,
+ params.getResources(),
params.getAssets(), params.getLayoutlibCallback(), configuration,
params.getTargetSdkVersion(), params.isRtlSupported());
Resources resources = Resources_Delegate.initSystem(context, assetManager, metrics,
@@ -1294,17 +1321,17 @@ public class RenderTests extends RenderTestBase {
public void testCrashes() throws ClassNotFoundException {
final String layout =
"<LinearLayout " +
- "xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
- " android:layout_width=\"match_parent\"\n" +
- " android:layout_height=\"match_parent\">\n" +
- "<com.android.layoutlib.bridge.test.widgets.HookWidget " +
- " android:layout_width=\"100dp\"\n" +
- " android:layout_height=\"200dp\" />\n" +
- "<LinearLayout " +
- " android:background=\"#CBBAF0\"\n" +
- " android:layout_width=\"100dp\"\n" +
- " android:layout_height=\"200dp\" />\n" +
- "</LinearLayout>";
+ "xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+ " android:layout_width=\"match_parent\"\n" +
+ " android:layout_height=\"match_parent\">\n" +
+ "<com.android.layoutlib.bridge.test.widgets.HookWidget " +
+ " android:layout_width=\"100dp\"\n" +
+ " android:layout_height=\"200dp\" />\n" +
+ "<LinearLayout " +
+ " android:background=\"#CBBAF0\"\n" +
+ " android:layout_width=\"100dp\"\n" +
+ " android:layout_height=\"200dp\" />\n" +
+ "</LinearLayout>";
{
com.android.layoutlib.bridge.test.widgets.HookWidget.setOnPreDrawHook(() -> {
throw new NullPointerException();
@@ -1429,7 +1456,7 @@ public class RenderTests extends RenderTestBase {
.disableDecoration()
.build();
- RenderResult result = RenderTestBase.render(sBridge, params, -1);
+ RenderResult result = render(sBridge, params, -1);
BufferedImage image = result.getImage();
assertNotNull(image);
Graphics2D g = (Graphics2D) image.getGraphics();
@@ -1438,7 +1465,7 @@ public class RenderTests extends RenderTestBase {
paintBorders(g, 0, 0, 0, vInfo);
}
- RenderTestBase.verify("view_boundaries.png", image);
+ verify("view_boundaries.png", image);
}
/**
@@ -1555,7 +1582,7 @@ public class RenderTests extends RenderTestBase {
.setCallback(layoutLibCallback)
.setImageFactory((width, height) ->
new BufferedImage(width / 10, height / 10,
- BufferedImage.TYPE_INT_ARGB))
+ BufferedImage.TYPE_INT_ARGB))
.setFlag(RenderParamsFlags.FLAG_KEY_RESULT_IMAGE_AUTO_SCALE, true)
.build();
@@ -1737,7 +1764,8 @@ public class RenderTests extends RenderTestBase {
// Create the layout pull parser.
LayoutPullParser parser = LayoutPullParser.createFromString(layout);
// Create LayoutLibCallback.
- LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(),
+ mDefaultClassLoader);
layoutLibCallback.initResources();
SessionParams params = getSessionParamsBuilder()
@@ -1754,7 +1782,8 @@ public class RenderTests extends RenderTestBase {
// Create the layout pull parser.
LayoutPullParser parser = LayoutPullParser.createFromString(layout);
// Create LayoutLibCallback.
- LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(),
+ mDefaultClassLoader);
layoutLibCallback.initResources();
SessionParams params = getSessionParamsBuilder()
@@ -1818,7 +1847,8 @@ public class RenderTests extends RenderTestBase {
// Create the layout pull parser.
LayoutPullParser parser = LayoutPullParser.createFromString(layout);
// Create LayoutLibCallback.
- LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger(),
+ mDefaultClassLoader);
layoutLibCallback.initResources();
SessionParams params = getSessionParamsBuilder()
@@ -1838,8 +1868,7 @@ public class RenderTests extends RenderTestBase {
if (!session.getResult().isSuccess()) {
getLogger().error(session.getResult().getException(),
session.getResult().getErrorMessage());
- }
- else {
+ } else {
// Render the session with a timeout of 50s.
Result renderResult = session.render(50000);
if (!renderResult.isSuccess()) {
@@ -2001,4 +2030,104 @@ public class RenderTests extends RenderTestBase {
renderAndVerify(params, "window_background.png",
TimeUnit.SECONDS.toNanos(2));
}
+
+ @Test
+ public void testThemedAdaptiveIcon() throws ClassNotFoundException, IOException {
+ // Create the layout pull parser.
+ String layout =
+ "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+ " android:padding=\"16dp\"\n" +
+ " android:orientation=\"horizontal\"\n" +
+ " android:layout_width=\"fill_parent\"\n" +
+ " android:layout_height=\"fill_parent\">\n" +
+ " <ImageView\n" +
+ " android:layout_height=\"wrap_content\"\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:src=\"@drawable/adaptive\" />\n" +
+ "</LinearLayout>\n";
+ // Create LayoutLibCallback.
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+ SessionParams params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50 0C77.6 0 100 22.4 100 50C100 77.6 77.6 100 50 100C22.4 100 0 77.6 0 50C0 " +
+ "22.4 22.4 0 50 0Z");
+ renderAndVerify(params, "adaptive_icon_circle.png");
+
+ params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50 0C77.6 0 100 22.4 100 50C100 77.6 77.6 100 50 100C22.4 100 0 77.6 0 50C0 " +
+ "22.4 22.4 0 50 0Z");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_WALLPAPER_PATH,
+ "/com/android/layoutlib/testdata/wallpaper1.webp");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_USE_THEMED_ICON, true);
+ renderAndVerify(params, "adaptive_icon_dynamic_orange.png");
+
+ params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50 0C77.6 0 100 22.4 100 50C100 77.6 77.6 100 50 100C22.4 100 0 77.6 0 50C0 " +
+ "22.4 22.4 0 50 0Z");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_WALLPAPER_PATH,
+ "/com/android/layoutlib/testdata/wallpaper2.webp");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_USE_THEMED_ICON, true);
+ renderAndVerify(params, "adaptive_icon_dynamic_green.png");
+
+ params = getSessionParamsBuilder()
+ .setParser(LayoutPullParser.createFromString(layout))
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .build();
+ params.setFlag(RenderParamsFlags.FLAG_KEY_ADAPTIVE_ICON_MASK_PATH,
+ "M50 0C77.6 0 100 22.4 100 50C100 77.6 77.6 100 50 100C22.4 100 0 77.6 0 50C0 " +
+ "22.4 22.4 0 50 0Z");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_WALLPAPER_PATH,
+ "/com/android/layoutlib/testdata/wallpaper2.webp");
+ params.setFlag(RenderParamsFlags.FLAG_KEY_USE_THEMED_ICON, false);
+ renderAndVerify(params, "adaptive_icon_circle.png");
+ }
+
+ @Test
+ public void testHtmlText() throws ClassNotFoundException {
+ final String layout =
+ "<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" +
+ " android:layout_width=\"match_parent\"\n" +
+ " android:layout_height=\"match_parent\">\n" + "\n" +
+ " <com.android.layoutlib.bridge.test.widgets.HtmlTextView\n" +
+ " android:layout_width=\"wrap_content\"\n" +
+ " android:layout_height=\"wrap_content\"\n" +
+ " android:textSize=\"30sp\"/>\n" +
+ "</FrameLayout>";
+ LayoutPullParser parser = LayoutPullParser.createFromString(layout);
+ // Create LayoutLibCallback.
+ LayoutLibTestCallback layoutLibCallback =
+ new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
+ layoutLibCallback.initResources();
+
+ SessionParams params = getSessionParamsBuilder()
+ .setParser(parser)
+ .setCallback(layoutLibCallback)
+ .setTheme("Theme.Material.Light.NoActionBar.Fullscreen", false)
+ .setRenderingMode(RenderingMode.V_SCROLL)
+ .disableDecoration()
+ .build();
+
+ renderAndVerify(params, "html.png", TimeUnit.SECONDS.toNanos(2));
+ }
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/ShadowsRenderTests.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/ShadowsRenderTests.java
index 5c997dcd34..2432fdbf9c 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/ShadowsRenderTests.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/ShadowsRenderTests.java
@@ -17,8 +17,8 @@
package com.android.layoutlib.bridge.intensive;
import com.android.ide.common.rendering.api.SessionParams;
+import com.android.layoutlib.bridge.android.RenderTestBase;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import org.junit.After;
diff --git a/remote/tests/src/CustomComponent.java b/bridge/tests/src/com/android/layoutlib/bridge/test/widgets/HtmlTextView.java
index 6d6272d2ff..ab31f7af26 100644
--- a/remote/tests/src/CustomComponent.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/test/widgets/HtmlTextView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,41 +14,35 @@
* limitations under the License.
*/
+package com.android.layoutlib.bridge.test.widgets;
+
import android.content.Context;
-import android.graphics.Color;
+import android.text.Html;
import android.util.AttributeSet;
import android.widget.TextView;
-@SuppressWarnings("unused") // Used by test
-public class CustomComponent extends TextView {
- public CustomComponent(Context context) {
+public class HtmlTextView extends TextView {
+ public HtmlTextView(Context context) {
super(context);
-
- init();
+ init(context);
}
- public CustomComponent(Context context, AttributeSet attrs) {
+ public HtmlTextView(Context context, AttributeSet attrs) {
super(context, attrs);
-
- init();
+ init(context);
}
- public CustomComponent(Context context, AttributeSet attrs, int defStyleAttr) {
+ public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
-
- init();
+ init(context);
}
- public CustomComponent(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
-
- init();
+ init(context);
}
- private void init() {
- setText("CustomComponent text");
- setBackgroundColor(Color.RED);
- setTextColor(Color.WHITE);
- setTextSize(40f);
+ private void init(Context context) {
+ setText(Html.fromHtml("This is <b>bold</>!", Html.FROM_HTML_MODE_COMPACT));
}
}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/util/ChoreographerCallbacksTest.java b/bridge/tests/src/com/android/layoutlib/bridge/util/ChoreographerCallbacksTest.java
index 68e7006b05..c0c7ec23eb 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/util/ChoreographerCallbacksTest.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/util/ChoreographerCallbacksTest.java
@@ -58,8 +58,8 @@ public class ChoreographerCallbacksTest {
ChoreographerCallbacks callbacks = new ChoreographerCallbacks();
ArrayList<Integer> order = new ArrayList<>();
- callbacks.add((Runnable) () -> order.add(2), 200);
- callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), 100);
+ callbacks.add((Runnable) () -> order.add(2), null, 200);
+ callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), null, 100);
callbacks.execute(200, logger);
Assert.assertArrayEquals(order.toArray(), new Object[] { 1, 2 });
@@ -71,8 +71,8 @@ public class ChoreographerCallbacksTest {
ChoreographerCallbacks callbacks = new ChoreographerCallbacks();
ArrayList<Integer> order = new ArrayList<>();
- callbacks.add((Runnable) () -> order.add(2), 200);
- callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), 100);
+ callbacks.add((Runnable) () -> order.add(2), null, 200);
+ callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), null, 100);
callbacks.execute(100, logger);
Assert.assertArrayEquals(order.toArray(), new Object[] { 1 });
@@ -85,9 +85,9 @@ public class ChoreographerCallbacksTest {
ArrayList<Integer> order = new ArrayList<>();
Runnable runnable = () -> order.add(2);
- callbacks.add(runnable, 200);
- callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), 100);
- callbacks.remove(runnable);
+ callbacks.add(runnable, null, 200);
+ callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), null, 100);
+ callbacks.remove(runnable, null);
callbacks.execute(200, logger);
Assert.assertArrayEquals(order.toArray(), new Object[] { 1 });
@@ -98,10 +98,28 @@ public class ChoreographerCallbacksTest {
public void testErrorIfUnknownCallbackType() {
ChoreographerCallbacks callbacks = new ChoreographerCallbacks();
- callbacks.add(new Object(), 100);
+ callbacks.add(new Object(), null, 100);
callbacks.execute(200, logger);
Assert.assertFalse(logger.errorMessages.isEmpty());
Assert.assertEquals(logger.errorMessages.get(0), "Unexpected action as Choreographer callback");
}
+
+ @Test
+ public void testRemoveNullAction() {
+ ChoreographerCallbacks callbacks = new ChoreographerCallbacks();
+ ArrayList<Integer> order = new ArrayList<>();
+
+ Object token1 = new Object();
+ Object token2 = new Object();
+ callbacks.add((Runnable) () -> order.add(2), token1, 200);
+ callbacks.add((FrameCallback) frameTimeNanos -> order.add(1), token1, 100);
+ callbacks.add((Runnable) () -> order.add(3), token2, 100);
+ callbacks.add((Runnable) () -> order.add(4), null, 200);
+ callbacks.remove(null, token1);
+ callbacks.execute(200, logger);
+
+ Assert.assertArrayEquals(order.toArray(), new Object[] { 3, 4 });
+ Assert.assertTrue(logger.errorMessages.isEmpty());
+ }
}
diff --git a/bridge/tests/src/com/android/tools/idea/validator/AccessibilityValidatorTests.java b/bridge/tests/src/com/android/tools/idea/validator/AccessibilityValidatorTests.java
index 4ab7863d38..2dfefaca99 100644
--- a/bridge/tests/src/com/android/tools/idea/validator/AccessibilityValidatorTests.java
+++ b/bridge/tests/src/com/android/tools/idea/validator/AccessibilityValidatorTests.java
@@ -17,9 +17,9 @@
package com.android.tools.idea.validator;
import com.android.ide.common.rendering.api.RenderSession;
-import com.android.layoutlib.bridge.intensive.RenderTestBase;
+import com.android.layoutlib.bridge.android.RenderTestBase;
+import com.android.layoutlib.bridge.intensive.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.layoutlib.bridge.intensive.util.SessionParamsBuilder;
import com.android.tools.idea.validator.ValidatorData.Issue;
@@ -27,18 +27,17 @@ import com.android.tools.idea.validator.ValidatorData.Level;
import com.android.tools.idea.validator.ValidatorData.Policy;
import com.android.tools.idea.validator.ValidatorData.Type;
-import org.junit.Ignore;
import org.junit.Test;
import java.util.EnumSet;
import java.util.List;
+import java.util.stream.Collectors;
import com.google.android.apps.common.testing.accessibility.framework.uielement.DefaultCustomViewBuilderAndroid;
import com.google.android.apps.common.testing.accessibility.framework.uielement.ViewHierarchyElementAndroid;
import static com.android.tools.idea.validator.ValidatorUtil.filter;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
@@ -174,9 +173,8 @@ public class AccessibilityValidatorTests extends RenderTestBase {
// ATF doesn't count alpha values unless image is passed.
ExpectedLevels expectedLevels = new ExpectedLevels();
- expectedLevels.expectedErrors = 3;
- expectedLevels.expectedWarnings = 1; // This is true only if image is passed.
- expectedLevels.expectedVerboses = 2;
+ expectedLevels.expectedErrors = 4;
+ expectedLevels.expectedVerboses = 1;
expectedLevels.expectedFixes = 4;
expectedLevels.check(textContrast);
@@ -189,7 +187,6 @@ public class AccessibilityValidatorTests extends RenderTestBase {
/* TODO: {@link LayoutValidator::obtainCharacterLocations is false by default for now }*/
@Test
- @Ignore
public void testSwitchTextContrastCheck() throws Exception {
render("a11y_test_switch_text_contrast.xml", session -> {
ValidatorResult result = getRenderResult(session);
@@ -219,9 +216,9 @@ public class AccessibilityValidatorTests extends RenderTestBase {
// ATF doesn't count alpha values unless image is passed.
ExpectedLevels expectedLevels = new ExpectedLevels();
- expectedLevels.expectedErrors = 3;
- expectedLevels.expectedVerboses = 3;
- expectedLevels.expectedFixes = 3;
+ expectedLevels.expectedErrors = 4;
+ expectedLevels.expectedVerboses = 1;
+ expectedLevels.expectedFixes = 4;
expectedLevels.check(textContrast);
// Make sure no other errors in the system.
@@ -328,6 +325,26 @@ public class AccessibilityValidatorTests extends RenderTestBase {
});
}
+ @Test
+ public void testCharacterLocationArgMaxLength() throws Exception {
+ render("justified_none.xml", session -> {
+ ValidatorHierarchy hierarchy = (ValidatorHierarchy)session.getValidationData();
+
+ List<ViewHierarchyElementAndroid> textViews =
+ hierarchy.mView.getActiveWindow().getAllViews().stream().filter(view->
+ (view.getClassName() != null &&
+ view.getClassName().toString().contains("TextView"))).collect(
+ Collectors.toList());
+
+ // The text of the only TextView is very long (more than 1000 characters), but
+ // only 100 text character locations are retrieved because
+ // setCharacterLocationArgMaxLength method works as expected.
+ assertEquals(textViews.size(), 1);
+ assertEquals(textViews.get(0).getTextCharacterLocations().size(),
+ ValidatorUtil.CHARACTER_LOCATION_ARG_MAX_LENGTH - 1);
+ });
+ }
+
private void checkEquals(List<Issue> list1, List<Issue> list2) {
assertEquals(list1.size(), list2.size());
for (int i = 0; i < list1.size(); i++) {
@@ -366,7 +383,7 @@ public class AccessibilityValidatorTests extends RenderTestBase {
LayoutValidator.updatePolicy(new Policy(
EnumSet.of(Type.ACCESSIBILITY, Type.RENDER),
EnumSet.of(Level.ERROR, Level.WARNING, Level.INFO, Level.VERBOSE)));
- LayoutValidator.setObtainCharacterLocations(false);
+ LayoutValidator.setObtainCharacterLocations(true);
LayoutPullParser parser = createParserFromPath(fileName);
layoutLibCallback.initResources();
diff --git a/bridge/tests/src/com/android/tools/idea/validator/LayoutValidatorTests.java b/bridge/tests/src/com/android/tools/idea/validator/LayoutValidatorTests.java
index 723a2c046b..fd5e7f1780 100644
--- a/bridge/tests/src/com/android/tools/idea/validator/LayoutValidatorTests.java
+++ b/bridge/tests/src/com/android/tools/idea/validator/LayoutValidatorTests.java
@@ -17,15 +17,14 @@
package com.android.tools.idea.validator;
import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.intensive.RenderTestBase;
+import com.android.layoutlib.bridge.android.RenderTestBase;
+import com.android.layoutlib.bridge.intensive.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.tools.idea.validator.ValidatorData.CompoundFix;
import com.android.tools.idea.validator.ValidatorData.Issue;
import com.android.tools.idea.validator.ValidatorData.Level;
import com.android.tools.idea.validator.ValidatorData.SetViewAttributeFix;
-
import com.android.tools.idea.validator.ValidatorData.Type;
import org.junit.Test;
@@ -56,7 +55,7 @@ public class LayoutValidatorTests extends RenderTestBase {
@Test
public void testEnsureObtainCharacterLocation() {
- assertFalse(LayoutValidator.obtainCharacterLocations());
+ assertTrue(LayoutValidator.obtainCharacterLocations());
}
@Test
@@ -84,7 +83,7 @@ public class LayoutValidatorTests extends RenderTestBase {
null,
SCALE_X_FOR_NEXUS_5,
SCALE_Y_FOR_NEXUS_5);
- assertEquals(30, result.getIssues().size());
+ assertEquals(31, result.getIssues().size());
ArrayList<Issue> errorIssues = new ArrayList<>();
for (Issue issue : result.getIssues()) {
assertEquals(Type.ACCESSIBILITY, issue.mType);
@@ -172,7 +171,7 @@ public class LayoutValidatorTests extends RenderTestBase {
null,
SCALE_X_FOR_NEXUS_5,
SCALE_Y_FOR_NEXUS_5);
- assertEquals(27, result.getIssues().size());
+ assertEquals(26, result.getIssues().size());
result.getIssues().forEach(issue ->assertEquals(Level.VERBOSE, issue.mLevel));
});
} finally {
diff --git a/common/src/com/android/tools/layoutlib/create/NativeConfig.java b/common/src/com/android/tools/layoutlib/create/NativeConfig.java
index 9c05df2ab2..60a65efd95 100644
--- a/common/src/com/android/tools/layoutlib/create/NativeConfig.java
+++ b/common/src/com/android/tools/layoutlib/create/NativeConfig.java
@@ -38,13 +38,14 @@ public class NativeConfig {
};
public static final String[] DELEGATE_METHODS = new String[] {
+ "android.app.ActivityManager#getService",
"android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
"android.content.res.AssetManager#createSystemAssetsInZygoteLocked",
"android.content.res.AssetManager#getAssignedPackageIdentifiers",
"android.content.res.AssetManager#nativeCreate",
"android.content.res.AssetManager#nativeDestroy",
- "android.content.res.AssetManager#nativeThemeCreate",
"android.content.res.AssetManager#nativeGetThemeFreeFunction",
+ "android.content.res.AssetManager#nativeThemeCreate",
"android.content.res.Resources#getAnimation",
"android.content.res.Resources#getAttributeSetSourceResId",
"android.content.res.Resources#getBoolean",
@@ -75,9 +76,9 @@ public class NativeConfig {
"android.content.res.Resources#getXml",
"android.content.res.Resources#loadXmlResourceParser",
"android.content.res.Resources#obtainAttributes",
+ "android.content.res.Resources#obtainTypedArray",
"android.content.res.Resources#openRawResource",
"android.content.res.Resources#openRawResourceFd",
- "android.content.res.Resources#obtainTypedArray",
"android.content.res.Resources$Theme#obtainStyledAttributes",
"android.content.res.Resources$Theme#resolveAttribute",
"android.content.res.Resources$Theme#resolveAttributes",
@@ -86,10 +87,9 @@ public class NativeConfig {
"android.graphics.Canvas#getClipBounds",
"android.graphics.ImageDecoder#decodeBitmapImpl",
"android.graphics.Typeface#create",
- "android.graphics.Typeface$Builder#createAssetUid",
- "android.graphics.drawable.AdaptiveIconDrawable#<init>",
- "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI#onDraw",
+ "android.graphics.drawable.AdaptiveIconDrawable#draw",
"android.graphics.drawable.AnimatedVectorDrawable#draw",
+ "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI#onDraw",
"android.graphics.drawable.DrawableInflater#inflateFromClass",
"android.graphics.drawable.NinePatchDrawable#getOpacity",
"android.graphics.fonts.Font$Builder#createBuffer",
@@ -100,11 +100,14 @@ public class NativeConfig {
"android.os.Handler#sendMessageAtFrontOfQueue",
"android.os.Handler#sendMessageAtTime",
"android.os.HandlerThread#run",
+ "android.os.SystemProperties#find",
+ "android.permission.PermissionManager#checkPermission",
"android.preference.Preference#getView",
"android.provider.DeviceConfig#getBoolean",
"android.provider.DeviceConfig#getFloat",
"android.provider.DeviceConfig#getInt",
"android.provider.DeviceConfig#getLong",
+ "android.provider.DeviceConfig#getProperty",
"android.provider.DeviceConfig#getString",
"android.text.format.DateFormat#is24HourFormat",
"android.util.Xml#newPullParser",
@@ -114,6 +117,8 @@ public class NativeConfig {
"android.view.Choreographer#removeCallbacksInternal",
"android.view.Display#getWindowManager",
"android.view.Display#updateDisplayInfoLocked",
+ "android.view.DisplayEventReceiver#nativeGetDisplayEventReceiverFinalizer",
+ "android.view.DisplayEventReceiver#nativeInit",
"android.view.HandlerActionQueue#postDelayed",
"android.view.LayoutInflater#initPrecompiledViews",
"android.view.LayoutInflater#parseInclude",
@@ -123,16 +128,20 @@ public class NativeConfig {
"android.view.PointerIcon#registerDisplayListener",
"android.view.SurfaceControl#nativeCreateTransaction",
"android.view.SurfaceControl#nativeGetNativeTransactionFinalizer",
- "android.view.TextureView#getTextureLayer",
- "android.view.View#draw",
+ "android.view.VelocityTracker#obtain",
"android.view.View#dispatchDetachedFromWindow",
+ "android.view.View#draw",
"android.view.View#getWindowToken",
"android.view.View#isInEditMode",
"android.view.View#layout",
"android.view.View#measure",
- "android.view.ViewRootImpl#isInTouchMode",
+ "android.view.ViewRootImpl#performHapticFeedback",
"android.view.WindowManagerGlobal#getWindowManagerService",
+ "android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow",
"android.view.inputmethod.InputMethodManager#isInEditMode",
+ "android.view.inputmethod.InputMethodManager#showSoftInput",
+ "android.widget.AbsListView#setupDeviceConfigProperties",
+ "android.widget.Magnifier#show",
"android.widget.RemoteViews#getApplicationInfo",
"com.android.internal.util.XmlUtils#convertValueToInt",
"com.android.internal.view.menu.MenuBuilder#createNewMenuItem",
@@ -157,14 +166,11 @@ public class NativeConfig {
"android.animation.PropertyValuesHolder",
"android.content.res.StringBlock",
"android.content.res.XmlBlock",
- "android.media.ImageReader",
- "android.media.PublicFormatUtils",
"android.os.SystemProperties",
"android.os.Trace",
"android.text.AndroidCharacter",
"android.util.Log",
"android.view.MotionEvent",
- "android.view.Surface",
"com.android.internal.util.VirtualRefBasePtr",
"libcore.util.NativeAllocationRegistry_Delegate",
};
@@ -185,7 +191,6 @@ public class NativeConfig {
"android.graphics.DrawFilter",
"android.graphics.FontFamily",
"android.graphics.Graphics",
- "android.graphics.HardwareRenderer",
"android.graphics.ImageDecoder",
"android.graphics.Interpolator",
"android.graphics.MaskFilter",
diff --git a/create/Android.bp b/create/Android.bp
index 96622e958e..13a00a878f 100644
--- a/create/Android.bp
+++ b/create/Android.bp
@@ -25,11 +25,12 @@ java_binary_host {
main_class: "com.android.tools.layoutlib.create.Main",
static_libs: [
- "asm-9.2",
- "asm-commons-9.2",
+ "ow2-asm",
+ "ow2-asm-commons",
"guava",
"layoutlib-common",
"layoutlib_create-classpath",
- "atf-prebuilt-371374941",
+ "atf-prebuilt-502584086",
+ "libprotobuf-java-lite",
],
}
diff --git a/create/create.iml b/create/create.iml
index 00abf5dc6e..2f520c9199 100644
--- a/create/create.iml
+++ b/create/create.iml
@@ -11,25 +11,21 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
- <library name="asm-7.0">
+ <library name="asm-9.2">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/asm/asm-7.0/linux_glibc_common/combined/asm-7.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/asm/asm-9.2/linux_glibc_common/combined/asm-9.2.jar!/" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/asm/src-7.0.zip!/" />
- </SOURCES>
+ <SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library">
- <library name="asm-commons-7.0">
+ <library name="asm-commons-9.2">
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/asm/asm-commons-7.0/linux_glibc_common/combined/asm-commons-7.0.jar!/" />
+ <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/asm/asm-commons-9.2/linux_glibc_common/combined/asm-commons-9.2.jar!/" />
</CLASSES>
<JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/asm/src-7.0.zip!/" />
- </SOURCES>
+ <SOURCES />
</library>
</orderEntry>
<orderEntry type="library" scope="TEST" name="junit" level="project" />
@@ -84,11 +80,12 @@
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
- <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/atf/atf-prebuilt-jars-371374941/linux_glibc_common/combined/atf-prebuilt-jars-371374941.jar!/" />
+ <root url="jar://$MODULE_DIR$/../../../out/soong/.intermediates/prebuilts/misc/common/atf/atf-prebuilt-jars-502584086/linux_glibc_common/combined/atf-prebuilt-jars-502584086.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="library" scope="RUNTIME" name="libprotobuf-java-lite" level="project" />
</component>
-</module>
+</module> \ No newline at end of file
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 66a22d1fa5..fb50c46ff1 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -18,7 +18,6 @@ package com.android.tools.layoutlib.create;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.android.tools.layoutlib.java.LinkedHashMap_Delegate;
-import com.android.tools.layoutlib.java.NioUtils_Delegate;
import com.android.tools.layoutlib.java.Reference_Delegate;
import org.objectweb.asm.Opcodes;
@@ -26,15 +25,12 @@ import org.objectweb.asm.Type;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
-import java.text.DateFormat;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import java.util.zip.ZipEntry;
/**
* Describes the work to be done by {@link AsmGenerator}.
@@ -139,18 +135,17 @@ public final class CreateInfo implements ICreateInfo {
new SystemLoadLibraryReplacer(),
new SystemArrayCopyReplacer(),
new LocaleGetDefaultReplacer(),
- new LocaleAdjustLanguageCodeReplacer(),
new SystemLogReplacer(),
new SystemNanoTimeReplacer(),
new SystemCurrentTimeMillisReplacer(),
new LinkedHashMapEldestReplacer(),
new ContextGetClassLoaderReplacer(),
new ImageReaderNativeInitReplacer(),
- new NioUtilsFreeBufferReplacer(),
- new ProcessInitializerInitSchedReplacer(),
new NativeInitPathReplacer(),
+ new AdaptiveIconMaskReplacer(),
new ActivityThreadInAnimationReplacer(),
new ReferenceRefersToReplacer(),
+ new HtmlApplicationResourceReplacer(),
};
/**
@@ -167,7 +162,6 @@ public final class CreateInfo implements ICreateInfo {
InjectMethodRunnables.class,
/* Java package classes */
LinkedHashMap_Delegate.class,
- NioUtils_Delegate.class,
Reference_Delegate.class,
};
@@ -213,7 +207,6 @@ public final class CreateInfo implements ICreateInfo {
"android.graphics.DrawFilter",
"android.graphics.EmbossMaskFilter",
"android.graphics.FontFamily",
- "android.graphics.HardwareRenderer",
"android.graphics.ImageDecoder",
"android.graphics.Interpolator",
"android.graphics.LightingColorFilter",
@@ -257,9 +250,6 @@ public final class CreateInfo implements ICreateInfo {
"android.graphics.text.MeasuredText",
"android.graphics.text.MeasuredText$Builder",
"android.graphics.text.TextRunShaper",
- "android.media.ImageReader",
- "android.media.ImageReader$SurfaceImage",
- "android.media.PublicFormatUtils",
"android.os.SystemProperties",
"android.os.Trace",
"android.text.AndroidCharacter",
@@ -280,8 +270,6 @@ public final class CreateInfo implements ICreateInfo {
"android.view.textservice.TextServicesManager", "android.view.textservice._Original_TextServicesManager",
"android.view.SurfaceView", "android.view._Original_SurfaceView",
"android.view.WindowManagerImpl", "android.view._Original_WindowManagerImpl",
- "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
- "android.view.accessibility.AccessibilityNodeIdManager", "android.view.accessibility._Original_AccessibilityNodeIdManager",
"android.webkit.WebView", "android.webkit._Original_WebView",
};
@@ -311,6 +299,7 @@ public final class CreateInfo implements ICreateInfo {
new String[] {
"android.preference.PreferenceActivity",
"java.**",
+ "kotlin.**",
"org.kxml2.io.KXmlParser",
"org.xmlpull.**",
"sun.**",
@@ -337,10 +326,11 @@ public final class CreateInfo implements ICreateInfo {
"android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI#mSet",
"android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#mPendingAnimationActions",
"android.graphics.drawable.AnimatedVectorDrawable#mAnimatorSet",
- "android.graphics.drawable.AdaptiveIconDrawable#sMask",
"android.graphics.drawable.DrawableInflater#mRes",
+ "android.hardware.input.InputManagerGlobal#sInstance",
"android.view.Choreographer#mCallbackQueues", // required for tests only
"android.view.Choreographer$CallbackQueue#mHead", // required for tests only
+ "android.view.ViewRootImpl#mTmpFrames",
"com.android.internal.util.ArrayUtils#sCache",
};
@@ -353,6 +343,8 @@ public final class CreateInfo implements ICreateInfo {
"android.content.res.StringBlock#getColor",
"android.graphics.Bitmap#setNinePatchChunk",
"android.graphics.Path#nInit",
+ "android.graphics.Typeface$Builder#createAssetUid",
+ "android.hardware.input.InputManagerGlobal#<init>",
"android.media.ImageReader#nativeClassInit",
"android.view.Choreographer#doFrame",
"android.view.Choreographer#postCallbackDelayedInternal",
@@ -367,6 +359,7 @@ public final class CreateInfo implements ICreateInfo {
private final static String[] PROMOTED_CLASSES = new String[] {
"android.content.res.StringBlock$Height",
"android.graphics.ImageDecoder$InputStreamSource",
+ "android.graphics.ImageDecoder$ResourceSource",
"android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI",
"android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator",
"android.view.Choreographer$CallbackQueue", // required for tests only
@@ -385,11 +378,8 @@ public final class CreateInfo implements ICreateInfo {
private final static String[] DEFERRED_STATIC_INITIALIZER_CLASSES =
NativeConfig.DEFERRED_STATIC_INITIALIZER_CLASSES;
- private final static Map<String, InjectMethodRunnable> INJECTED_METHODS =
- new HashMap<String, InjectMethodRunnable>(1) {{
- put("android.content.Context",
- InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
- }};
+ private final static Map<String, InjectMethodRunnable> INJECTED_METHODS = Map.of(
+ "android.content.Context", InjectMethodRunnables.CONTEXT_GET_FRAMEWORK_CLASS_LOADER);
public static class LinkedHashMapEldestReplacer implements MethodReplacer {
@@ -529,21 +519,6 @@ public final class CreateInfo implements ICreateInfo {
}
}
- public static class LocaleAdjustLanguageCodeReplacer implements MethodReplacer {
-
- @Override
- public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return Type.getInternalName(java.util.Locale.class).equals(owner)
- && ("adjustLanguageCode".equals(name)
- && desc.equals(Type.getMethodDescriptor(Type.getType(String.class), Type.getType(String.class))));
- }
-
- @Override
- public void replace(MethodInformation mi) {
- mi.owner = "com/android/tools/layoutlib/java/util/LocaleAdjustLanguageCodeReplacement";
- }
- }
-
private static class SystemArrayCopyReplacer implements MethodReplacer {
/**
* Descriptors for specialized versions {@link System#arraycopy} that are not present on the
@@ -565,78 +540,34 @@ public final class CreateInfo implements ICreateInfo {
}
}
- public static class DateFormatSet24HourTimePrefReplacer implements MethodReplacer {
-
- @Override
- public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return Type.getInternalName(DateFormat.class).equals(owner) &&
- "set24HourTimePref".equals(name);
- }
-
- @Override
- public void replace(MethodInformation mi) {
- mi.owner = "com/android/tools/layoutlib/java/text/DateFormat_Delegate";
- }
- }
-
- /**
- * Replace references to ZipEntry.getDataOffset with a delegate, since it does not exist in the JDK.
- * @see {@link com.android.tools.layoutlib.java.util.zip.ZipEntry_Delegate#getDataOffset(ZipEntry)}
- */
- public static class ZipEntryGetDataOffsetReplacer implements MethodReplacer {
- @Override
- public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return Type.getInternalName(ZipEntry.class).equals(owner)
- && "getDataOffset".equals(name);
- }
-
- @Override
- public void replace(MethodInformation mi) {
- mi.opcode = Opcodes.INVOKESTATIC;
- mi.owner = "com/android/tools/layoutlib/java/util/zip/ZipEntry_Delegate";
- mi.desc = Type.getMethodDescriptor(
- Type.getType(long.class), Type.getType(ZipEntry.class));
- }
- }
-
- public static class NioUtilsFreeBufferReplacer implements MethodReplacer {
- @Override
- public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return "java/nio/NioUtils".equals(owner) && name.equals("freeDirectBuffer");
- }
-
- @Override
- public void replace(MethodInformation mi) {
- mi.owner = Type.getInternalName(NioUtils_Delegate.class);
- }
- }
-
- public static class ProcessInitializerInitSchedReplacer implements MethodReplacer {
+ public static class NativeInitPathReplacer implements MethodReplacer {
@Override
public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return "android/graphics/HardwareRenderer$ProcessInitializer".equals(owner) &&
- name.equals("initSched");
+ return "android/graphics/Path".equals(owner) &&
+ "nInit".equals(name) && "(J)J".equals(desc);
}
@Override
public void replace(MethodInformation mi) {
- mi.owner = "android/graphics/HardwareRenderer_ProcessInitializer_Delegate";
+ mi.owner = "android/graphics/Path_Delegate";
mi.opcode = Opcodes.INVOKESTATIC;
- mi.desc = "(J)V";
}
}
- public static class NativeInitPathReplacer implements MethodReplacer {
+ public static class AdaptiveIconMaskReplacer implements MethodReplacer {
@Override
public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
- return "android/graphics/Path".equals(owner) &&
- "nInit".equals(name) && "(J)J".equals(desc);
+ return "android/graphics/drawable/AdaptiveIconDrawable".equals(sourceClass) &&
+ "android/content/res/Resources".equals(owner) &&
+ name.equals("getString");
}
@Override
public void replace(MethodInformation mi) {
- mi.owner = "android/graphics/Path_Delegate";
+ mi.owner = "android/graphics/drawable/AdaptiveIconDrawable_Delegate";
+ mi.name = "getResourceString";
mi.opcode = Opcodes.INVOKESTATIC;
+ mi.desc = "(Landroid/content/res/Resources;I)Ljava/lang/String;";
}
}
@@ -671,4 +602,22 @@ public final class CreateInfo implements ICreateInfo {
Type.getType(Object.class));
}
}
+
+ public static class HtmlApplicationResourceReplacer implements MethodReplacer {
+ @Override
+ public boolean isNeeded(String owner, String name, String desc, String sourceClass) {
+ return ("android/text/Html".equals(sourceClass) ||
+ "android/text/HtmlToSpannedConverter".equals(sourceClass)) &&
+ "android/app/Application".equals(owner) &&
+ name.equals("getResources");
+ }
+
+ @Override
+ public void replace(MethodInformation mi) {
+ mi.owner = "android/app/Application_Delegate";
+ mi.name = "getResources";
+ mi.opcode = Opcodes.INVOKESTATIC;
+ mi.desc = "(Landroid/app/Application;)Landroid/content/res/Resources;";
+ }
+ }
}
diff --git a/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java b/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
index 630550031d..859578e601 100644
--- a/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
+++ b/create/src/com/android/tools/layoutlib/create/DelegateMethodAdapter.java
@@ -22,10 +22,12 @@ import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
import java.util.ArrayList;
@@ -480,4 +482,74 @@ class DelegateMethodAdapter extends MethodVisitor {
}
}
+ @Override
+ public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle,
+ Object... bootstrapMethodArguments) {
+ if (mOrgWriter != null) {
+ mOrgWriter.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle,
+ bootstrapMethodArguments);
+ }
+ }
+
+ @Override
+ public void visitParameter(String name, int access) {
+ if (mOrgWriter != null) {
+ mOrgWriter.visitParameter(name, access);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String descriptor,
+ boolean visible) {
+ if (mOrgWriter != null) {
+ return mOrgWriter.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void visitAnnotableParameterCount(int parameterCount, boolean visible) {
+ if (mOrgWriter != null) {
+ mOrgWriter.visitAnnotableParameterCount(parameterCount, visible);
+ }
+ }
+
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String descriptor) {
+ if (mOrgWriter != null) {
+ mOrgWriter.visitMethodInsn(opcode, owner, name, descriptor);
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor,
+ boolean visible) {
+ if (mOrgWriter != null) {
+ return mOrgWriter.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath,
+ String descriptor, boolean visible) {
+ if (mOrgWriter != null) {
+ return mOrgWriter.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath,
+ Label[] start, Label[] end, int[] index, String descriptor, boolean visible) {
+ if (mOrgWriter != null) {
+ return mOrgWriter.visitLocalVariableAnnotation(typeRef, typePath, start, end, index,
+ descriptor, visible);
+ } else {
+ return null;
+ }
+ }
}
diff --git a/create/src/com/android/tools/layoutlib/create/Main.java b/create/src/com/android/tools/layoutlib/create/Main.java
index 4d0de146c6..2da8ea6b11 100644
--- a/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/create/src/com/android/tools/layoutlib/create/Main.java
@@ -59,10 +59,9 @@ public class Main {
private boolean listAllDeps = false;
private boolean listOnlyMissingDeps = false;
private boolean createStubLib = false;
- private boolean createNativeOnlyDelegates = false;
}
- public static final int ASM_VERSION = Opcodes.ASM7;
+ public static final int ASM_VERSION = Opcodes.ASM9;
private static final Options sOptions = new Options();
@@ -74,7 +73,7 @@ public class Main {
String[] osDestJar = { null };
if (!processArgs(log, args, osJarPath, osDestJar)) {
- log.error("Usage: layoutlib_create [-v] [--create-stub] [--create-native-only-delegates] output.jar input.jar ...");
+ log.error("Usage: layoutlib_create [-v] [--create-stub] output.jar input.jar ...");
log.error("Usage: layoutlib_create [-v] [--list-deps|--missing-deps] input.jar ...");
System.exit(1);
}
@@ -102,41 +101,44 @@ public class Main {
AsmAnalyzer aa = new AsmAnalyzer(log, osJarPath,
new String[] { // derived from
+ "android.app.Fragment",
"android.view.View",
- "android.app.Fragment"
},
new String[] { // include classes
"android.*", // for android.R
- "android.util.*",
- "com.android.internal.util.*",
- "android.view.*",
- "android.widget.*",
- "com.android.internal.widget.*",
- "android.text.**",
- "android.graphics.*",
- "android.graphics.drawable.**",
+ "android.annotation.NonNull", // annotations
+ "android.annotation.Nullable", // annotations
+ "android.app.ApplicationErrorReport", // needed for Glance LazyList
+ "android.app.DatePickerDialog", // b.android.com/28318
+ "android.app.TimePickerDialog", // b.android.com/61515
"android.content.*",
"android.content.res.*",
- "android.preference.*",
- "org.apache.harmony.xml.*",
- "com.android.internal.R**",
- "android.pim.*", // for datepicker
- "android.os.*", // for android.os.Handler
"android.database.ContentObserver", // for Digital clock
- "com.android.i18n.phonenumbers.*", // for TextView with autolink attribute
- "android.app.DatePickerDialog", // b.android.com/28318
- "android.app.TimePickerDialog", // b.android.com/61515
- "com.android.internal.view.menu.ActionMenu",
- "libcore.icu.ICU", // needed by ICU_Delegate in LayoutLib
+ "android.graphics.*",
+ "android.graphics.drawable.**",
"android.icu.**", // needed by LayoutLib
- "libcore.io.*", // needed to load /usr/share/zoneinfo
- "android.annotation.NonNull", // annotations
- "android.annotation.Nullable", // annotations
- "com.android.internal.transition.EpicenterTranslateClipReveal",
+ "android.os.*", // for android.os.Handler
+ "android.os.ext.*", // for android.os.ext.SdkExtensions, needed by Compose
+ "android.pim.*", // for datepicker
+ "android.preference.*",
+ "android.service.wallpaper.*", // needed for Wear OS watch faces
+ "android.text.**",
+ "android.util.*",
+ "android.view.*",
+ "android.widget.*",
+ "com.android.i18n.phonenumbers.*", // for TextView with autolink attribute
+ "com.android.internal.R**",
"com.android.internal.graphics.drawable.AnimationScaleListDrawable",
+ "com.android.internal.transition.EpicenterTranslateClipReveal",
+ "com.android.internal.util.*",
+ "com.android.internal.view.menu.ActionMenu",
+ "com.android.internal.widget.*",
+ "com.android.systemui.monet.*", // needed for dynamic theming
"com.google.android.apps.common.testing.accessibility.**",
"com.google.android.libraries.accessibility.**",
- "android.service.wallpaper.*", // needed for Wear OS watch faces
+ "libcore.icu.ICU", // needed by ICU_Delegate in LayoutLib
+ "libcore.io.*", // needed to load /usr/share/zoneinfo
+ "org.apache.harmony.xml.*",
},
info.getExcludedClasses(),
new String[] {
@@ -165,14 +167,6 @@ public class Main {
log.info("Created stub JAR file %s", stubDestJarFile);
}
- if (sOptions.createNativeOnlyDelegates) {
- File osDestJarFile = new File(osDestJar);
- Map<String, byte[]> nativeDelegateClasses =
- outputClasses.entrySet().stream().filter(entry -> entry.getKey().endsWith("_NativeDelegate.class")).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
- JarUtil.createJar(new FileOutputStream(osDestJarFile), nativeDelegateClasses);
- log.info("Created native delegate JAR file %s", osDestJarFile);
- }
-
// Throw an error if any class failed to get renamed by the generator
//
// IMPORTANT: if you're building the platform and you get this error message,
@@ -240,8 +234,6 @@ public class Main {
needs_dest = false;
} else if (s.equals("--create-stub")) {
sOptions.createStubLib = true;
- } else if (s.equals("--create-native-only-delegates")) {
- sOptions.createNativeOnlyDelegates = true;
} else if (!s.startsWith("-")) {
if (needs_dest && osDestJar[0] == null) {
osDestJar[0] = s;
diff --git a/create/tests/Android.bp b/create/tests/Android.bp
index b5e7033f0d..ffd58d1ba2 100644
--- a/create/tests/Android.bp
+++ b/create/tests/Android.bp
@@ -39,7 +39,7 @@ java_test_host {
"junit",
"hamcrest",
],
- static_libs: ["asm-9.2"],
+ static_libs: ["ow2-asm"],
// Copy the jar to DIST_DIR for sdk builds
dist: {
diff --git a/create/tests/run_tests.sh b/create/tests/run_tests.sh
index 3d5383855a..d0de029ecf 100755
--- a/create/tests/run_tests.sh
+++ b/create/tests/run_tests.sh
@@ -3,7 +3,7 @@
SCRIPT_DIR="$(dirname $0)"
DIST_DIR="$1"
-STUDIO_JDK=${SCRIPT_DIR}"/../../../../prebuilts/jdk/jdk11/linux-x86"
+STUDIO_JDK=${SCRIPT_DIR}"/../../../../prebuilts/jdk/jdk17/linux-x86"
OUT_INTERMEDIATES=${SCRIPT_DIR}"/../../../../out/soong/.intermediates"
${STUDIO_JDK}/bin/java -ea \
diff --git a/create/tests/src/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java b/create/tests/src/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
index 2e6ccd36c7..3655ec23b7 100644
--- a/create/tests/src/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
+++ b/create/tests/src/com/android/tools/layoutlib/create/PromoteClassClassAdapterTest.java
@@ -23,7 +23,7 @@ import org.objectweb.asm.Opcodes;
import java.io.IOException;
import java.util.Arrays;
-import java.util.HashSet;
+import java.util.Set;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;
@@ -122,12 +122,9 @@ public class PromoteClassClassAdapterTest {
LoggingClassVisitor log = new LoggingClassVisitor();
String rootClass = PromoteClassClassAdapterTest.class.getName();
- PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
- {
- add(rootClass + "$PrivateClass");
- add(rootClass + "$ClassWithPrivateInnerClass$InnerPrivateClass");
- }
- });
+ PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, Set.of(
+ rootClass + "$PrivateClass",
+ rootClass + "$ClassWithPrivateInnerClass$InnerPrivateClass"));
reader.accept(adapter, 0);
assertTrue(log.mLog.contains(
"[visitInnerClass] - " +
@@ -155,14 +152,10 @@ public class PromoteClassClassAdapterTest {
ClassReader reader = new ClassReader(PackageProtectedClass.class.getName());
LoggingClassVisitor log = new LoggingClassVisitor();
- PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, new HashSet<String>() {
- {
- add(PackageProtectedClass.class.getName());
- }
- });
-
+ PromoteClassClassAdapter adapter = new PromoteClassClassAdapter(log, Set.of(
+ PackageProtectedClass.class.getName()));
reader.accept(adapter, 0);
- assertTrue(log.mLog.contains("[visit] - version=55, access=[public], " +
+ assertTrue(log.mLog.contains("[visit] - version=61, access=[public], " +
"name=com/android/tools/layoutlib/create/PackageProtectedClass, signature=null, " +
"superName=java/lang/Object, interfaces=[]"));
diff --git a/delegates/Android.bp b/delegates/Android.bp
deleted file mode 100644
index 93bcd6ddb4..0000000000
--- a/delegates/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_library_host {
- name: "layoutlib-common-delegates",
-
- srcs: ["src/**/*.java"],
-
- libs: [
- "temp_layoutlib",
- "layoutlib-common",
- ],
-
-}
diff --git a/delegates/README b/delegates/README
deleted file mode 100644
index 0ef28c61fb..0000000000
--- a/delegates/README
+++ /dev/null
@@ -1 +0,0 @@
-The common set of delegates shared between layoutlib and simulated_device \ No newline at end of file
diff --git a/delegates/delegates.iml b/delegates/delegates.iml
deleted file mode 100644
index 04f8ae4b77..0000000000
--- a/delegates/delegates.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="framework.jar" level="project" />
- <orderEntry type="module" module-name="common" />
- </component>
-</module> \ No newline at end of file
diff --git a/delegates/src/com/android/tools/layoutlib/java/util/LocaleAdjustLanguageCodeReplacement.java b/delegates/src/com/android/tools/layoutlib/java/util/LocaleAdjustLanguageCodeReplacement.java
deleted file mode 100644
index b335e86ef4..0000000000
--- a/delegates/src/com/android/tools/layoutlib/java/util/LocaleAdjustLanguageCodeReplacement.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 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.tools.layoutlib.java.util;
-
-import java.util.Locale;
-
-/**
- * This class provides an alternate implementation for {@code java.util.Locale#adjustLanguageCode}
- * which is not available in openJDK.
- *
- * The create tool re-writes references to the above mentioned method to this one. Hence it's
- * imperative that this class is not deleted unless the create tool is modified.
- */
-public class LocaleAdjustLanguageCodeReplacement {
-
- public static String adjustLanguageCode(String languageCode) {
- String adjusted = languageCode.toLowerCase(Locale.US);
- // Map new language codes to the obsolete language
- // codes so the correct resource bundles will be used.
- if (languageCode.equals("he")) {
- adjusted = "iw";
- } else if (languageCode.equals("id")) {
- adjusted = "in";
- } else if (languageCode.equals("yi")) {
- adjusted = "ji";
- }
-
- return adjusted;
- }
-}
diff --git a/delegates/src/com/android/tools/layoutlib/java/util/zip/ZipEntry_Delegate.java b/delegates/src/com/android/tools/layoutlib/java/util/zip/ZipEntry_Delegate.java
deleted file mode 100644
index 4475fffe8f..0000000000
--- a/delegates/src/com/android/tools/layoutlib/java/util/zip/ZipEntry_Delegate.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 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.tools.layoutlib.java.util.zip;
-
-import java.util.zip.ZipEntry;
-
-/**
- * Wrapper for calls to Android-added API to ZipEntry
- */
-public class ZipEntry_Delegate extends ZipEntry {
-
- private final long mDataOffset;
-
- // Called from StrictJarFile native code.
- public ZipEntry_Delegate(String name, String comment, long crc, long compressedSize, long size,
- int compressionMethod, int xdostime, byte[] extra, long dataOffset) {
- super(name);
- setComment(comment);
- setCrc(crc);
- setCompressedSize(compressedSize);
- setSize(size);
- setMethod(compressionMethod);
- setTime(xdostime);
- setExtra(extra);
- mDataOffset = dataOffset;
- }
-
- /**
- * Handle calls to the Android-added ZipEntry#getDataOffset.
- *
- * Called from StrictJarFile java code.
- */
- public static long getDataOffset(ZipEntry original) {
- return ((ZipEntry_Delegate) original).mDataOffset;
- }
-}
diff --git a/remote/client/remote client.iml b/remote/client/remote client.iml
deleted file mode 100644
index 051a2c1e94..0000000000
--- a/remote/client/remote client.iml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$MODULE_DIR$/../../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module" module-name="remote common" />
- <orderEntry type="module" module-name="common" />
- </component>
-</module> \ No newline at end of file
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java
deleted file mode 100644
index d63c9f6b87..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java
+++ /dev/null
@@ -1,123 +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 com.android.layoutlib.bridge.remote.client;
-
-import com.android.ide.common.rendering.api.Bridge;
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.ILayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layout.remote.api.RemoteBridge;
-import com.android.layout.remote.api.RemoteSessionParams;
-import com.android.layoutlib.bridge.remote.client.adapters.RemoteDrawableParamsAdapter;
-import com.android.layoutlib.bridge.remote.client.adapters.RemoteLayoutLogAdapter;
-import com.android.layoutlib.bridge.remote.client.adapters.RemoteRenderSessionAdapter;
-import com.android.layoutlib.bridge.remote.client.adapters.RemoteSessionParamsAdapter;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.File;
-import java.rmi.NotBoundException;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.util.Map;
-
-public class RemoteBridgeClient extends Bridge {
- private final RemoteBridge mDelegate;
-
- private RemoteBridgeClient(@NotNull RemoteBridge delegate) {
- mDelegate = delegate;
- }
-
- @NotNull
- public static RemoteBridgeClient getRemoteBridge(int registryPort) throws RemoteException,
- NotBoundException {
- Registry registry = LocateRegistry.getRegistry(registryPort);
- RemoteBridge remoteBridge = (RemoteBridge) registry.lookup(RemoteBridge.class.getName());
-
- return new RemoteBridgeClient(remoteBridge);
- }
-
- @Override
- public boolean init(Map<String, String> platformProperties,
- File fontLocation,
- String nativeLibPath,
- String icuDataPath,
- Map<String, Map<String, Integer>> enumValueMap,
- ILayoutLog log) {
- try {
- return mDelegate.init(platformProperties, fontLocation, nativeLibPath, icuDataPath,
- enumValueMap, RemoteLayoutLogAdapter.create(log));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean dispose() {
- try {
- return mDelegate.dispose();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RenderSession createSession(SessionParams params) {
- try {
- RemoteSessionParams remoteParams = RemoteSessionParamsAdapter.create(params);
-
- return new RemoteRenderSessionAdapter(mDelegate.createSession(remoteParams));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Result renderDrawable(DrawableParams params) {
- try {
- return mDelegate.renderDrawable(RemoteDrawableParamsAdapter.create(params));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void clearResourceCaches(Object projectKey) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Result getViewParent(Object viewObject) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Result getViewIndex(Object viewObject) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isRtl(String locale) {
- try {
- return mDelegate.isRtl(locale);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteActionBarCallbackAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteActionBarCallbackAdapter.java
deleted file mode 100644
index 9f3da0c0eb..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteActionBarCallbackAdapter.java
+++ /dev/null
@@ -1,71 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.layout.remote.api.RemoteActionBarCallback;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.List;
-
-class RemoteActionBarCallbackAdapter implements RemoteActionBarCallback {
- private final ActionBarCallback mDelegate;
-
- private RemoteActionBarCallbackAdapter(@NotNull ActionBarCallback delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteActionBarCallback create(@NotNull ActionBarCallback delegate)
- throws RemoteException {
- return (RemoteActionBarCallback) UnicastRemoteObject.exportObject(
- new RemoteActionBarCallbackAdapter(delegate), 0);
- }
-
- @Override
- public List<ResourceReference> getMenuIds() {
- return mDelegate.getMenuIds();
- }
-
- @Override
- public boolean getSplitActionBarWhenNarrow() {
- return mDelegate.getSplitActionBarWhenNarrow();
- }
-
- @Override
- public int getNavigationMode() {
- return mDelegate.getNavigationMode();
- }
-
- @Override
- public String getSubTitle() {
- return mDelegate.getSubTitle();
- }
-
- @Override
- public HomeButtonStyle getHomeButtonStyle() {
- return mDelegate.getHomeButtonStyle();
- }
-
- @Override
- public boolean isOverflowPopupNeeded() {
- return mDelegate.isOverflowPopupNeeded();
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteAssetRepositoryAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteAssetRepositoryAdapter.java
deleted file mode 100644
index 4def7402b1..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteAssetRepositoryAdapter.java
+++ /dev/null
@@ -1,52 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layout.remote.api.RemoteAssetRepository;
-import com.android.layout.remote.util.RemoteInputStream;
-import com.android.layout.remote.util.RemoteInputStreamAdapter;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.IOException;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteAssetRepositoryAdapter implements RemoteAssetRepository {
- private final AssetRepository mDelegate;
-
- private RemoteAssetRepositoryAdapter(@NotNull AssetRepository delegate) {
- mDelegate = delegate;
- }
-
- static RemoteAssetRepository create(@NotNull AssetRepository delegate) throws RemoteException {
- return (RemoteAssetRepository) UnicastRemoteObject.exportObject(
- new RemoteAssetRepositoryAdapter(delegate), 0);
- }
-
- @Override
- public RemoteInputStream openAsset(String path, int mode) throws IOException, RemoteException {
- return RemoteInputStreamAdapter.create(mDelegate.openAsset(path, mode));
- }
-
- @Override
- public RemoteInputStream openNonAsset(int cookie, String path, int mode)
- throws IOException, RemoteException {
- return RemoteInputStreamAdapter.create(mDelegate.openNonAsset(cookie, path, mode));
- }
-
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteDrawableParamsAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteDrawableParamsAdapter.java
deleted file mode 100644
index d2c2cd8486..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteDrawableParamsAdapter.java
+++ /dev/null
@@ -1,48 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layout.remote.api.RemoteDrawableParams;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteDrawableParamsAdapter extends RemoteRenderParamsAdapter implements
- RemoteDrawableParams {
- private final DrawableParams mDelegate;
-
- private RemoteDrawableParamsAdapter(@NotNull DrawableParams drawableParams) {
- super(drawableParams);
- mDelegate = drawableParams;
- }
-
- @NotNull
- public static RemoteDrawableParams create(@NotNull DrawableParams drawableParams)
- throws RemoteException {
- return (RemoteDrawableParams) UnicastRemoteObject.exportObject(
- new RemoteDrawableParamsAdapter(drawableParams), 0);
- }
-
- @NotNull
- @Override
- public ResourceValue getDrawable() throws RemoteException {
- return mDelegate.getDrawable();
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteILayoutPullParserAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteILayoutPullParserAdapter.java
deleted file mode 100644
index 841d71467e..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteILayoutPullParserAdapter.java
+++ /dev/null
@@ -1,48 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.ResourceNamespace;
-import com.android.layout.remote.api.RemoteILayoutPullParser;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-class RemoteILayoutPullParserAdapter extends RemoteXmlPullParserAdapter
- implements RemoteILayoutPullParser {
- private RemoteILayoutPullParserAdapter(@NotNull ILayoutPullParser delegate) {
- super(delegate);
- }
-
- public static RemoteILayoutPullParser create(@NotNull ILayoutPullParser delegate)
- throws RemoteException {
- return (RemoteILayoutPullParser) UnicastRemoteObject.exportObject(
- new RemoteILayoutPullParserAdapter(delegate), 0);
- }
-
- @Override
- public Object getViewCookie() {
- return ((ILayoutPullParser) mDelegate).getViewCookie();
- }
-
- @Override
- public ResourceNamespace getLayoutNamespace() {
- return ((ILayoutPullParser) mDelegate).getLayoutNamespace();
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java
deleted file mode 100644
index 2ea91023e8..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java
+++ /dev/null
@@ -1,64 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.ILayoutLog;
-import com.android.layout.remote.api.RemoteLayoutLog;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.Serializable;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteLayoutLogAdapter implements RemoteLayoutLog {
- private final ILayoutLog mLog;
-
- private RemoteLayoutLogAdapter(@NotNull ILayoutLog log) {
- mLog = log;
- }
-
- public static RemoteLayoutLog create(@NotNull ILayoutLog log) throws RemoteException {
- return (RemoteLayoutLog) UnicastRemoteObject.exportObject(new RemoteLayoutLogAdapter(log),
- 0);
- }
-
- @Override
- public void warning(String tag, String message, Object viewCookie, Serializable data) {
- mLog.warning(tag, message, viewCookie, null);
- }
-
- @Override
- public void fidelityWarning(String tag, String message, Throwable throwable, Object viewCookie,
- Object data) {
- mLog.fidelityWarning(tag, message, throwable, viewCookie, data);
- }
-
- @Override
- public void error(String tag, String message, Object viewCookie, Serializable data) {
- mLog.error(tag, message, viewCookie, null);
- }
-
- @Override
- public void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data) {
- mLog.error(tag, message, throwable, viewCookie, null);
- }
-
- @Override
- public void logAndroidFramework(int priority, String tag, String message) {
- mLog.logAndroidFramework(priority, tag, message);
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutlibCallbackAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutlibCallbackAdapter.java
deleted file mode 100644
index 06fa6b26bf..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutlibCallbackAdapter.java
+++ /dev/null
@@ -1,154 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutlibCallback.ViewAttribute;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.layout.remote.api.RemoteActionBarCallback;
-import com.android.layout.remote.api.RemoteILayoutPullParser;
-import com.android.layout.remote.api.RemoteLayoutlibCallback;
-import com.android.layout.remote.api.RemoteParserFactory;
-import com.android.layout.remote.api.RemoteXmlPullParser;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteLayoutlibCallbackAdapter implements RemoteLayoutlibCallback {
- private final LayoutlibCallback mDelegate;
-
- private RemoteLayoutlibCallbackAdapter(@NotNull LayoutlibCallback delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteLayoutlibCallback create(@NotNull LayoutlibCallback delegate)
- throws RemoteException {
- return (RemoteLayoutlibCallback) UnicastRemoteObject.exportObject(
- new RemoteLayoutlibCallbackAdapter(delegate), 0);
- }
-
- @Override
- public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs) {
- throw new UnsupportedOperationException("Not implemented yet");
- }
-
- @Override
- public ResourceReference resolveResourceId(int id) {
- return mDelegate.resolveResourceId(id);
- }
-
- @Override
- public int getOrGenerateResourceId(ResourceReference resource) {
- return mDelegate.getOrGenerateResourceId(resource);
- }
-
- @Override
- public RemoteILayoutPullParser getParser(ResourceValue layoutResource) {
- try {
- return RemoteILayoutPullParserAdapter.create(mDelegate.getParser(layoutResource));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
- ResourceReference itemRef, int fullPosition, int positionPerType,
- int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
- ViewAttribute viewAttribute, Object defaultValue) {
- throw new UnsupportedOperationException("Not implemented yet");
- }
-
- @Override
- public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
- Object viewObject) {
- throw new UnsupportedOperationException("Not implemented yet");
- }
-
- @Override
- public RemoteActionBarCallback getActionBarCallback() {
- try {
- return RemoteActionBarCallbackAdapter.create(mDelegate.getActionBarCallback());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public <T> T getFlag(Key<T> key) {
- return mDelegate.getFlag(key);
- }
-
- @Override
- public String getResourcePackage() throws RemoteException {
- return mDelegate.getResourcePackage();
- }
-
- @Nullable
- @Override
- public Path findClassPath(String name) {
- try {
- Class<?> clazz = mDelegate.findClass(name);
- URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
- if (url != null) {
- return Paths.get(url.toURI());
- }
- } catch (ClassNotFoundException ignore) {
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
-
- return null;
- }
-
-
- @Override
- public RemoteXmlPullParser createXmlParserForPsiFile(String fileName) {
- try {
- return RemoteXmlPullParserAdapter.create(mDelegate.createXmlParserForPsiFile(fileName));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RemoteXmlPullParser createXmlParserForFile(String fileName) {
- try {
- return RemoteXmlPullParserAdapter.create(mDelegate.createXmlParserForFile(fileName));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RemoteXmlPullParser createXmlParser() {
- try {
- return RemoteXmlPullParserAdapter.create(mDelegate.createXmlParser());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderParamsAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderParamsAdapter.java
deleted file mode 100644
index 8cebdc0880..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderParamsAdapter.java
+++ /dev/null
@@ -1,157 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.layout.remote.api.RemoteAssetRepository;
-import com.android.layout.remote.api.RemoteHardwareConfig;
-import com.android.layout.remote.api.RemoteLayoutLog;
-import com.android.layout.remote.api.RemoteLayoutlibCallback;
-import com.android.layout.remote.api.RemoteRenderParams;
-import com.android.layout.remote.api.RemoteRenderResources;
-import com.android.layout.remote.api.RemoteSessionParams;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteRenderParamsAdapter implements RemoteRenderParams {
- private final RenderParams mDelegate;
-
- protected RemoteRenderParamsAdapter(@NotNull RenderParams params) {
- mDelegate = params;
- }
-
- public static RemoteSessionParams create(@NotNull SessionParams params) throws RemoteException {
- return (RemoteSessionParams) UnicastRemoteObject.exportObject(
- new RemoteRenderParamsAdapter(params), 0);
- }
-
- @Nullable
- @Override
- public String getProjectKey() {
- Object projectKey = mDelegate.getProjectKey();
- // We can not transfer a random object so let's send just a string
- return projectKey != null ? projectKey.toString() : null;
- }
-
- @Override
- public RemoteHardwareConfig getRemoteHardwareConfig() {
- return new RemoteHardwareConfig(mDelegate.getHardwareConfig());
- }
-
- @Override
- public int getMinSdkVersion() {
- return mDelegate.getMinSdkVersion();
- }
-
- @Override
- public int getTargetSdkVersion() {
- return mDelegate.getTargetSdkVersion();
- }
-
- @Override
- public RemoteRenderResources getRemoteResources() {
- try {
- return RemoteRenderResourcesAdapter.create(mDelegate.getResources());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RemoteAssetRepository getAssets() {
- try {
- return RemoteAssetRepositoryAdapter.create(mDelegate.getAssets());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RemoteLayoutlibCallback getRemoteLayoutlibCallback() {
- try {
- return RemoteLayoutlibCallbackAdapter.create(mDelegate.getLayoutlibCallback());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public RemoteLayoutLog getLog() {
- try {
- return RemoteLayoutLogAdapter.create(mDelegate.getLog());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean isTransparentBackground() {
- return mDelegate.isTransparentBackground();
- }
-
- @Override
- public long getTimeout() {
- return mDelegate.getTimeout();
- }
-
- @Override
- public IImageFactory getImageFactory() {
- return mDelegate.getImageFactory();
- }
-
- @Override
- public ResourceValue getAppIcon() {
- return mDelegate.getAppIcon();
- }
-
- @Override
- public String getAppLabel() {
- return mDelegate.getAppLabel();
- }
-
- @Override
- public String getLocale() {
- return mDelegate.getLocale();
- }
-
- @Override
- public String getActivityName() {
- return mDelegate.getActivityName();
- }
-
- @Override
- public boolean isForceNoDecor() {
- return mDelegate.isForceNoDecor();
- }
-
- @Override
- public boolean isRtlSupported() {
- return mDelegate.isRtlSupported();
- }
-
- @Override
- public <T> T getFlag(Key<T> key) {
- return mDelegate.getFlag(key);
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderResourcesAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderResourcesAdapter.java
deleted file mode 100644
index b477eeab07..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderResourcesAdapter.java
+++ /dev/null
@@ -1,116 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layout.remote.api.RemoteRenderResources;
-import com.android.layout.remote.api.RemoteResourceValue;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class RemoteRenderResourcesAdapter implements RemoteRenderResources {
-
- private final RenderResources mDelegate;
-
- private RemoteRenderResourcesAdapter(@NotNull RenderResources delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteRenderResources create(@NotNull RenderResources resources)
- throws RemoteException {
- return (RemoteRenderResources) UnicastRemoteObject.exportObject(
- new RemoteRenderResourcesAdapter(resources), 0);
- }
-
- @Override
- public RemoteResourceValue<StyleResourceValue> getDefaultTheme() {
- return RemoteResourceValue.fromResourceValue(mDelegate.getDefaultTheme());
- }
-
- @Override
- public void applyStyle(RemoteResourceValue<StyleResourceValue> theme, boolean useAsPrimary) {
- mDelegate.applyStyle(theme.toResourceValue(), useAsPrimary);
- }
-
- @Override
- public void clearStyles() {
- mDelegate.clearStyles();
- }
-
- @Override
- public List<RemoteResourceValue<StyleResourceValue>> getAllThemes() {
- return mDelegate.getAllThemes().stream().map(
- RemoteResourceValue::fromResourceValue).collect(Collectors.toList());
- }
-
- @Override
- @Nullable
- public RemoteResourceValue<ResourceValue> getResolvedResource(
- @NotNull ResourceReference reference) {
- return RemoteResourceValue.fromResourceValue(mDelegate.getResolvedResource(reference));
- }
-
- @Override
- public RemoteResourceValue<ResourceValue> findItemInTheme(ResourceReference attr) {
- return RemoteResourceValue.fromResourceValue(mDelegate.findItemInTheme(attr));
- }
-
- @Override
- public RemoteResourceValue<ResourceValue> findItemInStyle(
- RemoteResourceValue<StyleResourceValue> style, ResourceReference attr) {
- return RemoteResourceValue.fromResourceValue(
- mDelegate.findItemInStyle(style.toResourceValue(), attr));
- }
-
- @Override
- public RemoteResourceValue<ResourceValue> resolveValue(
- RemoteResourceValue<ResourceValue> value) {
- return RemoteResourceValue.fromResourceValue(
- mDelegate.resolveResValue(value.toResourceValue()));
- }
-
- @Override
- public RemoteResourceValue<StyleResourceValue> getParent(
- RemoteResourceValue<StyleResourceValue> style) {
- return RemoteResourceValue.fromResourceValue(mDelegate.getParent(style.toResourceValue()));
- }
-
- @Override
- @Nullable
- public RemoteResourceValue<StyleResourceValue> getStyle(@NotNull ResourceReference reference) {
- return RemoteResourceValue.fromResourceValue(mDelegate.getStyle(reference));
- }
-
- @Override
- public RemoteResourceValue<ResourceValue> dereference(
- RemoteResourceValue<ResourceValue> resourceValue) {
- return RemoteResourceValue.fromResourceValue(
- mDelegate.dereference(resourceValue.toResourceValue()));
- }
-
- @Override
- public RemoteResourceValue<ResourceValue> getUnresolvedResource(ResourceReference reference) {
- return RemoteResourceValue.fromResourceValue(mDelegate.getUnresolvedResource(reference));
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderSessionAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderSessionAdapter.java
deleted file mode 100644
index c2c892eaf1..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteRenderSessionAdapter.java
+++ /dev/null
@@ -1,111 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.ViewInfo;
-import com.android.layout.remote.api.RemoteRenderSession;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.awt.image.BufferedImage;
-import java.rmi.RemoteException;
-import java.util.Collections;
-import java.util.List;
-
-public class RemoteRenderSessionAdapter extends RenderSession {
- private final RemoteRenderSession mDelegate;
-
- public RemoteRenderSessionAdapter(@NotNull RemoteRenderSession delegate) {
- mDelegate = delegate;
- }
-
- @Override
- public Result getResult() {
- try {
- return mDelegate.getResult();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public BufferedImage getImage() {
- try {
- return mDelegate.getSerializableImage().getBufferedImage();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setSystemTimeNanos(long nanos) {
- try {
- mDelegate.setSystemTimeNanos(nanos);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setSystemBootTimeNanos(long nanos) {
- try {
- mDelegate.setSystemBootTimeNanos(nanos);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setElapsedFrameTimeNanos(long nanos) {
- try {
- mDelegate.setElapsedFrameTimeNanos(nanos);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Result render(long timeout, boolean forceMeasure) {
- try {
- return mDelegate.render(timeout, forceMeasure);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public List<ViewInfo> getRootViews() {
- // TODO
- return Collections.emptyList();
- }
-
- @Override
- public List<ViewInfo> getSystemRootViews() {
- // TODO
- return Collections.emptyList();
- }
-
- @Override
- public void dispose() {
- try {
- mDelegate.dispose();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteSessionParamsAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteSessionParamsAdapter.java
deleted file mode 100644
index e6ed871c03..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteSessionParamsAdapter.java
+++ /dev/null
@@ -1,80 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-import com.android.layout.remote.api.RemoteAssetRepository;
-import com.android.layout.remote.api.RemoteHardwareConfig;
-import com.android.layout.remote.api.RemoteILayoutPullParser;
-import com.android.layout.remote.api.RemoteLayoutLog;
-import com.android.layout.remote.api.RemoteLayoutlibCallback;
-import com.android.layout.remote.api.RemoteRenderResources;
-import com.android.layout.remote.api.RemoteSessionParams;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.Map;
-
-public class RemoteSessionParamsAdapter extends RemoteRenderParamsAdapter implements RemoteSessionParams {
- private final SessionParams mDelegate;
-
- private RemoteSessionParamsAdapter(@NotNull SessionParams params) {
- super(params);
- mDelegate = params;
- }
-
- public static RemoteSessionParams create(@NotNull SessionParams params) throws RemoteException {
- return (RemoteSessionParams) UnicastRemoteObject.exportObject(
- new RemoteSessionParamsAdapter(params), 0);
- }
-
- @Override
- public RenderingMode getRenderingMode() {
- return mDelegate.getRenderingMode();
- }
-
- @Override
- public boolean isLayoutOnly() {
- return mDelegate.isLayoutOnly();
- }
-
- @Override
- public Map<ResourceReference, AdapterBinding> getAdapterBindings() {
- return mDelegate.getAdapterBindings();
- }
-
- @Override
- public boolean getExtendedViewInfoMode() {
- return mDelegate.getExtendedViewInfoMode();
- }
-
- @Override
- public int getSimulatedPlatformVersion() {
- return mDelegate.getSimulatedPlatformVersion();
- }
-
- @Override
- public RemoteILayoutPullParser getLayoutDescription() throws RemoteException {
- return RemoteILayoutPullParserAdapter.create(mDelegate.getLayoutDescription());
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteXmlPullParserAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteXmlPullParserAdapter.java
deleted file mode 100644
index e646bbc477..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteXmlPullParserAdapter.java
+++ /dev/null
@@ -1,234 +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 com.android.layoutlib.bridge.remote.client.adapters;
-
-import com.android.layout.remote.api.RemoteXmlPullParser;
-import com.android.layout.remote.util.RemoteInputStream;
-import com.android.layout.remote.util.StreamUtil;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteXmlPullParserAdapter implements RemoteXmlPullParser {
- protected XmlPullParser mDelegate;
-
- protected RemoteXmlPullParserAdapter(@NotNull XmlPullParser delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteXmlPullParser create(@NotNull XmlPullParser delegate)
- throws RemoteException {
- return (RemoteXmlPullParser) UnicastRemoteObject.exportObject(
- new RemoteXmlPullParserAdapter(delegate), 0);
- }
-
- @Override
- public void setFeature(String name, boolean state)
- throws XmlPullParserException, RemoteException {
- mDelegate.setFeature(name, state);
- }
-
- @Override
- public boolean getFeature(String name) throws RemoteException {
- return mDelegate.getFeature(name);
- }
-
- @Override
- public void setProperty(String name, Object value)
- throws XmlPullParserException, RemoteException {
- mDelegate.setProperty(name, value);
- }
-
- @Override
- public Object getProperty(String name) throws RemoteException {
- return mDelegate.getProperty(name);
- }
-
- @Override
- public void setInput(Reader in) throws XmlPullParserException, RemoteException {
- mDelegate.setInput(in);
- }
-
- @Override
- public void setInput(RemoteInputStream inputStream, String inputEncoding)
- throws XmlPullParserException, RemoteException {
- mDelegate.setInput(StreamUtil.getInputStream(inputStream), inputEncoding);
- }
-
- @Override
- public String getInputEncoding() throws RemoteException {
- return mDelegate.getInputEncoding();
- }
-
- @Override
- public void defineEntityReplacementText(String entityName, String replacementText)
- throws XmlPullParserException {
-
- }
-
- @Override
- public int getNamespaceCount(int depth) throws XmlPullParserException, RemoteException {
- return mDelegate.getNamespaceCount(depth);
- }
-
- @Override
- public String getNamespacePrefix(int pos) throws XmlPullParserException, RemoteException {
- return mDelegate.getNamespacePrefix(pos);
- }
-
- @Override
- public String getNamespaceUri(int pos) throws XmlPullParserException, RemoteException {
- return mDelegate.getNamespaceUri(pos);
- }
-
- @Override
- public String getNamespace(String prefix) throws RemoteException {
- return mDelegate.getNamespace(prefix);
- }
-
- @Override
- public int getDepth() throws RemoteException {
- return mDelegate.getDepth();
- }
-
- @Override
- public String getPositionDescription() throws RemoteException {
- return mDelegate.getPositionDescription();
- }
-
- @Override
- public int getLineNumber() throws RemoteException {
- return mDelegate.getLineNumber();
- }
-
- @Override
- public int getColumnNumber() throws RemoteException {
- return mDelegate.getColumnNumber();
- }
-
- @Override
- public boolean isWhitespace() throws XmlPullParserException, RemoteException {
- return mDelegate.isWhitespace();
- }
-
- @Override
- public String getText() throws RemoteException {
- return mDelegate.getText();
- }
-
- @Override
- public char[] getTextCharacters(int[] holderForStartAndLength) throws RemoteException {
- return mDelegate.getTextCharacters(holderForStartAndLength);
- }
-
- @Override
- public String getNamespace() throws RemoteException {
- return mDelegate.getNamespace();
- }
-
- @Override
- public String getName() throws RemoteException {
- return mDelegate.getName();
- }
-
- @Override
- public String getPrefix() throws RemoteException {
- return mDelegate.getPrefix();
- }
-
- @Override
- public boolean isEmptyElementTag() throws XmlPullParserException, RemoteException {
- return mDelegate.isEmptyElementTag();
- }
-
- @Override
- public int getAttributeCount() throws RemoteException {
- return mDelegate.getAttributeCount();
- }
-
- @Override
- public String getAttributeNamespace(int index) throws RemoteException {
- return mDelegate.getAttributeNamespace(index);
- }
-
- @Override
- public String getAttributeName(int index) throws RemoteException {
- return mDelegate.getAttributeName(index);
- }
-
- @Override
- public String getAttributePrefix(int index) throws RemoteException {
- return mDelegate.getAttributePrefix(index);
- }
-
- @Override
- public String getAttributeType(int index) throws RemoteException {
- return mDelegate.getAttributeType(index);
- }
-
- @Override
- public boolean isAttributeDefault(int index) throws RemoteException {
- return mDelegate.isAttributeDefault(index);
- }
-
- @Override
- public String getAttributeValue(int index) throws RemoteException {
- return mDelegate.getAttributeValue(index);
- }
-
- @Override
- public String getAttributeValue(String namespace, String name) throws RemoteException {
- return mDelegate.getAttributeValue(namespace, name);
- }
-
- @Override
- public int getEventType() throws XmlPullParserException, RemoteException {
- return mDelegate.getEventType();
- }
-
- @Override
- public int next() throws XmlPullParserException, IOException, RemoteException {
- return mDelegate.next();
- }
-
- @Override
- public int nextToken() throws XmlPullParserException, IOException, RemoteException {
- return mDelegate.nextToken();
- }
-
- @Override
- public void require(int type, String namespace, String name)
- throws XmlPullParserException, IOException, RemoteException {
- mDelegate.require(type, namespace, name);
- }
-
- @Override
- public String nextText() throws XmlPullParserException, IOException, RemoteException {
- return mDelegate.nextText();
- }
-
- @Override
- public int nextTag() throws XmlPullParserException, IOException, RemoteException {
- return mDelegate.nextTag();
- }
-}
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/package-info.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/package-info.java
deleted file mode 100644
index 6edf00dd11..0000000000
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Package containing all the client side adapters. These adapters have the mission of receiving
- * remote calls and translating them into the local API.
- */
-package com.android.layoutlib.bridge.remote.client.adapters; \ No newline at end of file
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteActionBarCallback.java b/remote/common/src/com/android/layout/remote/api/RemoteActionBarCallback.java
deleted file mode 100644
index 988fa98aaf..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteActionBarCallback.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License") throws RemoteException;
- * 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.layout.remote.api;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ActionBarCallback.HomeButtonStyle;
-import com.android.ide.common.rendering.api.ResourceReference;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.util.List;
-
-import android.annotation.NonNull;
-
-/**
- * Remote version of the {@link ActionBarCallback} class.
- */
-public interface RemoteActionBarCallback extends Remote {
- @NonNull
- List<ResourceReference> getMenuIds() throws RemoteException;
-
- boolean getSplitActionBarWhenNarrow() throws RemoteException;
-
- int getNavigationMode() throws RemoteException;
-
- String getSubTitle() throws RemoteException;
-
- HomeButtonStyle getHomeButtonStyle() throws RemoteException;
-
- boolean isOverflowPopupNeeded() throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteAssetRepository.java b/remote/common/src/com/android/layout/remote/api/RemoteAssetRepository.java
deleted file mode 100644
index 5b4d4123a2..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteAssetRepository.java
+++ /dev/null
@@ -1,36 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layout.remote.util.RemoteInputStream;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.IOException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link AssetRepository} class
- */
-public interface RemoteAssetRepository extends Remote {
- @NotNull
- RemoteInputStream openAsset(String path, int mode) throws IOException;
-
- @NotNull
- RemoteInputStream openNonAsset(int cookie, String path, int mode) throws IOException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java b/remote/common/src/com/android/layout/remote/api/RemoteBridge.java
deleted file mode 100644
index 4ef9d9751a..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java
+++ /dev/null
@@ -1,104 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.Bridge;
-import com.android.ide.common.rendering.api.ILayoutLog;
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.io.File;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.util.Map;
-
-/**
- * Interface that defines the operations available in the remote bridge. This is a remote version of
- * the local {@link Bridge} API. Most of the methods are mapped 1:1 with the {@link Bridge} API
- * unless there is a need for a method to be adapted for remote use.
- */
-public interface RemoteBridge extends Remote {
- /**
- * Initializes the Bridge object.
- *
- * @param platformProperties The build properties for the platform.
- * @param fontLocation the location of the fonts.
- * @param nativeLibPath the absolute path of the JNI library for layoutlib.
- * @param icuDataPath the location of the ICU data used natively.
- * @param enumValueMap map attrName ⇒ { map enumFlagName ⇒ Integer value }. This is typically
- * read from attrs.xml in the SDK target.
- * @param log a {@link ILayoutLog} object. Can be null.
- *
- * @return true if success.
- */
- boolean init(@NotNull Map<String, String> platformProperties, File fontLocation,
- @Nullable String nativeLibPath, @Nullable String icuDataPath,
- @NotNull Map<String, Map<String, Integer>> enumValueMap,
- @Nullable RemoteLayoutLog log) throws RemoteException;
-
- /**
- * Prepares the layoutlib to be unloaded.
- */
- boolean dispose() throws RemoteException;
-
- /**
- * Starts a layout session by inflating and rendering it. The method returns a {@link
- * RenderSession} on which further actions can be taken.
- *
- * @return a new {@link RenderSession} object that contains the result of the scene creation and
- * first rendering.
- */
- @NotNull
- RemoteRenderSession createSession(@NotNull RemoteSessionParams params) throws RemoteException;
-
- /**
- * Renders a Drawable. If the rendering is successful, the result image is accessible through
- * {@link Result#getData()}. It is of type {@link BufferedImage}
- *
- * @param params the rendering parameters.
- *
- * @return the result of the action.
- */
- @NotNull
- Result renderDrawable(@NotNull RemoteDrawableParams params) throws RemoteException;
-
- /**
- * Clears the resource cache for a specific project.
- *
- * <p>This cache contains bitmaps and nine patches that are loaded from the disk and reused
- * until this method is called.
- *
- * <p>The cache is not configuration dependent and should only be cleared when a resource
- * changes (at this time only bitmaps and 9 patches go into the cache).
- *
- * <p>The project key provided must be similar to the one passed in {@link RenderParams}.
- *
- * @param projectKey the key for the project.
- */
- void clearResourceCaches(String projectKey) throws RemoteException;
-
- /**
- * Returns true if the character orientation of the locale is right to left.
- *
- * @param locale The locale formatted as language-region
- *
- * @return true if the locale is right to left.
- */
- boolean isRtl(String locale) throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteDrawableParams.java b/remote/common/src/com/android/layout/remote/api/RemoteDrawableParams.java
deleted file mode 100644
index 9ef1e9e6de..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteDrawableParams.java
+++ /dev/null
@@ -1,31 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link DrawableParams} class
- */
-public interface RemoteDrawableParams extends RemoteRenderParams {
- @NotNull
- ResourceValue getDrawable() throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteHardwareConfig.java b/remote/common/src/com/android/layout/remote/api/RemoteHardwareConfig.java
deleted file mode 100644
index 191cca71b5..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteHardwareConfig.java
+++ /dev/null
@@ -1,71 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.resources.Density;
-import com.android.resources.ScreenOrientation;
-import com.android.resources.ScreenRound;
-import com.android.resources.ScreenSize;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.Serializable;
-
-/**
- * Remote version of the {@link HardwareConfig} class
- */
-// TODO: Just make HardwareConfig serializable
-public class RemoteHardwareConfig implements Serializable {
- private int mScreenWidth;
- private int mScreenHeight;
- private Density mDensity;
- private float mXdpi;
- private float mYdpi;
- private ScreenSize mScreenSize;
- private ScreenOrientation mOrientation;
- private ScreenRound mScreenRoundness;
- private boolean mHasSoftwareButtons;
-
- public RemoteHardwareConfig() {
- }
-
- public RemoteHardwareConfig(@NotNull HardwareConfig config) {
- this(config.getScreenWidth(), config.getScreenHeight(), config.getDensity(),
- config.getXdpi(), config.getYdpi(), config.getScreenSize(), config.getOrientation(),
- config.getScreenRoundness(), config.hasSoftwareButtons());
- }
-
- private RemoteHardwareConfig(int screenWidth, int screenHeight, Density density, float xdpi,
- float ydpi, ScreenSize screenSize, ScreenOrientation orientation,
- ScreenRound screenRoundness, boolean hasSoftwareButtons) {
- mScreenWidth = screenWidth;
- mScreenHeight = screenHeight;
- mDensity = density;
- mXdpi = xdpi;
- mYdpi = ydpi;
- mScreenSize = screenSize;
- mOrientation = orientation;
- mScreenRoundness = screenRoundness;
- mHasSoftwareButtons = hasSoftwareButtons;
- }
-
- @NotNull
- public HardwareConfig getHardwareConfig() {
- return new HardwareConfig(mScreenWidth, mScreenHeight, mDensity, mXdpi, mYdpi, mScreenSize,
- mOrientation, mScreenRoundness, mHasSoftwareButtons);
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteILayoutPullParser.java b/remote/common/src/com/android/layout/remote/api/RemoteILayoutPullParser.java
deleted file mode 100644
index 9f8ef8bd4f..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteILayoutPullParser.java
+++ /dev/null
@@ -1,31 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.ResourceNamespace;
-
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link ILayoutPullParser} interface
- */
-public interface RemoteILayoutPullParser extends RemoteXmlPullParser {
- Object getViewCookie() throws RemoteException;
-
- ResourceNamespace getLayoutNamespace() throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java b/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java
deleted file mode 100644
index 8e09ece5c4..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java
+++ /dev/null
@@ -1,84 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.ILayoutLog;
-
-import java.io.Serializable;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link ILayoutLog} class
- */
-public interface RemoteLayoutLog extends Remote {
- /**
- * Logs a warning.
- *
- * @param tag a tag describing the type of the warning
- * @param message the message of the warning
- * @param viewCookie optional cookie of the view associated to this error
- * @param data an optional data bundle that the client can use to improve the warning display.
- */
- void warning(String tag, String message, Object viewCookie, Serializable data) throws RemoteException;
-
- /**
- * Logs a fidelity warning.
- * <p>
- * This type of warning indicates that the render will not be the same as the rendering on a
- * device due to limitation of the Java rendering API.
- *
- * @param tag a tag describing the type of the warning
- * @param message the message of the warning
- * @param throwable an optional Throwable that triggered the warning
- * @param viewCookie optional cookie of the view associated to this error
- * @param data an optional data bundle that the client can use to improve the warning display.
- */
- void fidelityWarning(String tag, String message, Throwable throwable, Object viewCookie,
- Object data) throws RemoteException;
-
- /**
- * Logs an error.
- *
- * @param tag a tag describing the type of the error
- * @param message the message of the error
- * @param viewCookie optional cookie of the view associated to this error
- * @param data an optional data bundle that the client can use to improve the error display.
- */
- void error(String tag, String message, Object viewCookie, Serializable data) throws RemoteException;
-
- /**
- * Logs an error, and the {@link Throwable} that triggered it.
- *
- * @param tag a tag describing the type of the error
- * @param message the message of the error
- * @param throwable the Throwable that triggered the error
- * @param viewCookie optional cookie of the view associated to this error
- * @param data an optional data bundle that the client can use to improve the error display.
- */
- void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data)
- throws RemoteException;
-
- /**
- * Logs messages coming from the Android Framework.
- *
- * @param priority the priority level of the message
- * @param tag a tag describing the type of the error
- * @param message the message of the error
- */
- void logAndroidFramework(int priority, String tag, String message) throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteLayoutlibCallback.java b/remote/common/src/com/android/layout/remote/api/RemoteLayoutlibCallback.java
deleted file mode 100644
index ccf1feeb4e..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteLayoutlibCallback.java
+++ /dev/null
@@ -1,64 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutlibCallback.ViewAttribute;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-
-import java.nio.file.Path;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link LayoutlibCallback} class
- */
-public interface RemoteLayoutlibCallback extends Remote {
- Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
- throws Exception;
-
- ResourceReference resolveResourceId(int id) throws RemoteException;
-
- int getOrGenerateResourceId(ResourceReference resource) throws RemoteException;
-
- RemoteILayoutPullParser getParser(ResourceValue layoutResource) throws RemoteException;
-
- Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
- ResourceReference itemRef, int fullPosition, int positionPerType,
- int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
- ViewAttribute viewAttribute, Object defaultValue) throws RemoteException;
-
- AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
- Object viewObject) throws RemoteException;
-
- RemoteActionBarCallback getActionBarCallback() throws RemoteException;
-
- <T> T getFlag(Key<T> key) throws RemoteException;
-
- String getResourcePackage() throws RemoteException;
-
- Path findClassPath(String name) throws RemoteException;
-
- RemoteXmlPullParser createXmlParserForPsiFile(String fileName) throws RemoteException;
-
- RemoteXmlPullParser createXmlParserForFile(String fileName) throws RemoteException;
-
- RemoteXmlPullParser createXmlParser() throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteNamespaceResolver.java b/remote/common/src/com/android/layout/remote/api/RemoteNamespaceResolver.java
deleted file mode 100644
index 2adf016ff5..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteNamespaceResolver.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.layout.remote.api;
-
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.io.Serializable;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface RemoteNamespaceResolver extends Remote {
- static final RemoteNamespaceResolver EMPTY_RESOLVER = new EmptyResolver();
-
- /** Returns the full URI of an XML namespace for a given prefix, if defined. */
- @Nullable
- String remotePrefixToUri(@NotNull String namespacePrefix) throws RemoteException;
-
- @Nullable
- String remoteUriToPrefix(@NotNull String namespaceUri) throws RemoteException;
-
- class EmptyResolver implements Serializable, RemoteNamespaceResolver {
- private EmptyResolver() {
- }
-
- @Override
- public String remotePrefixToUri(String namespacePrefix) {
- return null;
- }
-
- @Override
- public String remoteUriToPrefix(String namespaceUri) {
- return null;
- }
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteRenderParams.java b/remote/common/src/com/android/layout/remote/api/RemoteRenderParams.java
deleted file mode 100644
index d245f2b36b..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteRenderParams.java
+++ /dev/null
@@ -1,64 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface RemoteRenderParams extends Remote {
- @Nullable
- String getProjectKey() throws RemoteException;
-
- RemoteHardwareConfig getRemoteHardwareConfig() throws RemoteException;
-
- int getMinSdkVersion() throws RemoteException;
-
- int getTargetSdkVersion() throws RemoteException;
-
- RemoteRenderResources getRemoteResources() throws RemoteException;
-
- RemoteAssetRepository getAssets() throws RemoteException;
-
- RemoteLayoutlibCallback getRemoteLayoutlibCallback() throws RemoteException;
-
- RemoteLayoutLog getLog() throws RemoteException;
-
- boolean isTransparentBackground() throws RemoteException;
-
- long getTimeout() throws RemoteException;
-
- IImageFactory getImageFactory() throws RemoteException;
-
- ResourceValue getAppIcon() throws RemoteException;
-
- String getAppLabel() throws RemoteException;
-
- String getLocale() throws RemoteException;
-
- String getActivityName() throws RemoteException;
-
- boolean isForceNoDecor() throws RemoteException;
-
- boolean isRtlSupported() throws RemoteException;
-
- <T> T getFlag(Key<T> key) throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteRenderResources.java b/remote/common/src/com/android/layout/remote/api/RemoteRenderResources.java
deleted file mode 100644
index 530b19e251..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteRenderResources.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License") throws RemoteException;
- * 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.layout.remote.api;
-
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.util.List;
-
-/**
- * Remote version of the {@link RenderResources} class
- */
-public interface RemoteRenderResources extends Remote {
- RemoteResourceValue<StyleResourceValue> getDefaultTheme() throws RemoteException;
-
- void applyStyle(RemoteResourceValue<StyleResourceValue> theme, boolean useAsPrimary) throws RemoteException;
-
- void clearStyles() throws RemoteException;
-
- List<RemoteResourceValue<StyleResourceValue>> getAllThemes() throws RemoteException;
-
- @Nullable
- RemoteResourceValue<ResourceValue> getResolvedResource(@NotNull ResourceReference reference) throws RemoteException;
-
- RemoteResourceValue<ResourceValue> findItemInTheme(ResourceReference attr) throws RemoteException;
-
- RemoteResourceValue<ResourceValue> findItemInStyle(RemoteResourceValue<StyleResourceValue> style,
- ResourceReference attr)
- throws RemoteException;
-
- RemoteResourceValue<ResourceValue> resolveValue(RemoteResourceValue<ResourceValue> value) throws RemoteException;
-
- RemoteResourceValue<StyleResourceValue> getParent(RemoteResourceValue<StyleResourceValue> style) throws RemoteException;
-
- @Nullable
- RemoteResourceValue<StyleResourceValue> getStyle(@NotNull ResourceReference reference) throws RemoteException;
-
- RemoteResourceValue<ResourceValue> dereference(RemoteResourceValue<ResourceValue> resourceValue) throws RemoteException;
-
- RemoteResourceValue<ResourceValue> getUnresolvedResource(ResourceReference reference) throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteRenderSession.java b/remote/common/src/com/android/layout/remote/api/RemoteRenderSession.java
deleted file mode 100644
index 648186f7d7..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteRenderSession.java
+++ /dev/null
@@ -1,48 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layout.remote.util.SerializableImage;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-
-/**
- * Remote version of the {@link RenderSession} class
- */
-public interface RemoteRenderSession extends Remote {
- @NotNull
- Result getResult() throws RemoteException;
-
- @NotNull
- SerializableImage getSerializableImage() throws RemoteException;
-
- void setSystemTimeNanos(long nanos) throws RemoteException;
-
- void setSystemBootTimeNanos(long nanos) throws RemoteException;
-
- void setElapsedFrameTimeNanos(long nanos) throws RemoteException;
-
- void dispose() throws RemoteException;
-
- @NotNull
- Result render(long timeout, boolean forceMeasure) throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteResourceValue.java b/remote/common/src/com/android/layout/remote/api/RemoteResourceValue.java
deleted file mode 100644
index fc19e4ffc4..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteResourceValue.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.ResourceNamespace.Resolver;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.layout.remote.util.RemoteResolverAdapter;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import java.io.Serializable;
-import java.rmi.RemoteException;
-
-/**
- * Wrapper for {@link ResourceValue} that can be transferred to a different VM.
- *
- * @param <T> the ResourceValue instance type
- */
-public class RemoteResourceValue<T extends ResourceValue> implements Serializable {
- private static final RemoteResourceValue<ResourceValue> NULL_INSTANCE =
- new RemoteResourceValue<>(null, null);
-
- private final T mResourceValue;
- private final RemoteNamespaceResolver mRemoteResolver;
-
- private RemoteResourceValue(@Nullable T resourceValue,
- @Nullable RemoteNamespaceResolver remoteResolver) {
- mResourceValue = resourceValue;
- mRemoteResolver = remoteResolver;
- }
-
- /**
- * Returns a RemoteResourceValue that wraps the given {@link ResourceValue} instance. The passed
- * resource value can be null.
- */
- @NotNull
- public static <T extends ResourceValue> RemoteResourceValue<T> fromResourceValue(
- T resourceValue) {
- if (resourceValue == null) {
- //noinspection unchecked
- return (RemoteResourceValue<T>) NULL_INSTANCE;
- }
- try {
- return new RemoteResourceValue<>(resourceValue,
- RemoteResolverAdapter.create(resourceValue.getNamespaceResolver()));
-
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns the {@link ResourceValue} wrapped by a remote wrapper
- */
- @NotNull
- private static <T extends ResourceValue> T toResourceValue(
- @NotNull RemoteResourceValue<T> remoteResourceValue) {
- T remoteValue = remoteResourceValue.mResourceValue;
- if (remoteValue == null) {
- return null;
- }
-
- // The Resolver is not transferred in the ResourceValue (it's transient) so we use the
- // information in the wrapper to reconstruct it.
- RemoteNamespaceResolver remoteResolver = remoteResourceValue.mRemoteResolver;
-
-// TODO: Rethink this as setNamespaceResolver is not available in prebuilts any more
-// if (remoteResolver != null) {
-// remoteValue.setNamespaceResolver(new Resolver() {
-// @Override
-// public String prefixToUri(String namespacePrefix) {
-// try {
-// return remoteResolver.remotePrefixToUri(namespacePrefix);
-// } catch (RemoteException e) {
-// throw new RuntimeException(e);
-// }
-// }
-//
-// @Override
-// public String uriToPrefix(String namespaceUri) {
-// try {
-// return remoteResolver.remoteUriToPrefix(namespaceUri);
-// } catch (RemoteException e) {
-// throw new RuntimeException(e);
-// }
-// }
-// });
-// }
-// else {
-// remoteValue.setNamespaceResolver(Resolver.EMPTY_RESOLVER);
-// }
-
- return remoteValue;
- }
-
- /**
- * Returns the {@link ResourceValue} wrapped by this remote wrapper
- */
- @NotNull
- public T toResourceValue() {
- return RemoteResourceValue.toResourceValue(this);
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteSessionParams.java b/remote/common/src/com/android/layout/remote/api/RemoteSessionParams.java
deleted file mode 100644
index 52a2a0938a..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteSessionParams.java
+++ /dev/null
@@ -1,45 +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 com.android.layout.remote.api;
-
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
-
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.util.Map;
-
-/**
- * Remote version of the {@link SessionParams} class
- */
-public interface RemoteSessionParams extends RemoteRenderParams {
- RenderingMode getRenderingMode() throws RemoteException;
-
- boolean isLayoutOnly() throws RemoteException;
-
- Map<ResourceReference, AdapterBinding> getAdapterBindings() throws RemoteException;
-
- boolean getExtendedViewInfoMode() throws RemoteException;
-
- int getSimulatedPlatformVersion() throws RemoteException;
-
- RemoteILayoutPullParser getLayoutDescription() throws RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteXmlPullParser.java b/remote/common/src/com/android/layout/remote/api/RemoteXmlPullParser.java
deleted file mode 100644
index e3e05d3192..0000000000
--- a/remote/common/src/com/android/layout/remote/api/RemoteXmlPullParser.java
+++ /dev/null
@@ -1,109 +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 com.android.layout.remote.api;
-
-import com.android.layout.remote.util.RemoteInputStream;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * Remote version of the {@link XmlPullParser} interface
- */
-public interface RemoteXmlPullParser extends Remote {
- void setFeature(String name, boolean state) throws XmlPullParserException, RemoteException;
-
- boolean getFeature(String name) throws RemoteException;
-
- void setProperty(String name, Object value) throws XmlPullParserException, RemoteException;
-
- Object getProperty(String name) throws RemoteException;
-
- void setInput(Reader in) throws XmlPullParserException, RemoteException;
-
- void setInput(RemoteInputStream inputStream, String inputEncoding)
- throws XmlPullParserException, RemoteException;
-
- String getInputEncoding() throws RemoteException;
-
- void defineEntityReplacementText(String entityName, String replacementText)
- throws XmlPullParserException, RemoteException;
-
- int getNamespaceCount(int depth) throws XmlPullParserException, RemoteException;
-
- String getNamespacePrefix(int pos) throws XmlPullParserException, RemoteException;
-
- String getNamespaceUri(int pos) throws XmlPullParserException, RemoteException;
-
- String getNamespace(String prefix) throws RemoteException;
-
- int getDepth() throws RemoteException;
-
- String getPositionDescription() throws RemoteException;
-
- int getLineNumber() throws RemoteException;
-
- int getColumnNumber() throws RemoteException;
-
- boolean isWhitespace() throws XmlPullParserException, RemoteException;
-
- String getText() throws RemoteException;
-
- char[] getTextCharacters(int[] holderForStartAndLength) throws RemoteException;
-
- String getNamespace() throws RemoteException;
-
- String getName() throws RemoteException;
-
- String getPrefix() throws RemoteException;
-
- boolean isEmptyElementTag() throws XmlPullParserException, RemoteException;
-
- int getAttributeCount() throws RemoteException;
-
- String getAttributeNamespace(int index) throws RemoteException;
-
- String getAttributeName(int index) throws RemoteException;
-
- String getAttributePrefix(int index) throws RemoteException;
-
- String getAttributeType(int index) throws RemoteException;
-
- boolean isAttributeDefault(int index) throws RemoteException;
-
- String getAttributeValue(int index) throws RemoteException;
-
- String getAttributeValue(String namespace, String name) throws RemoteException;
-
- int getEventType() throws XmlPullParserException, RemoteException;
-
- int next() throws XmlPullParserException, IOException, RemoteException;
-
- int nextToken() throws XmlPullParserException, IOException, RemoteException;
-
- void require(int type, String namespace, String name)
- throws XmlPullParserException, IOException, RemoteException;
-
- String nextText() throws XmlPullParserException, IOException, RemoteException;
-
- int nextTag() throws XmlPullParserException, IOException, RemoteException;
-}
diff --git a/remote/common/src/com/android/layout/remote/api/package-info.java b/remote/common/src/com/android/layout/remote/api/package-info.java
deleted file mode 100644
index c7591c605e..0000000000
--- a/remote/common/src/com/android/layout/remote/api/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Package containing all the interfaces that define the remote version of the Layoutlib API. This
- * interface matches the local layout API closely. In some cases where special capabilities to
- * support the remote calls are needed, the API will be different.
- */
-package com.android.layout.remote.api; \ No newline at end of file
diff --git a/remote/common/src/com/android/layout/remote/util/RemoteInputStream.java b/remote/common/src/com/android/layout/remote/util/RemoteInputStream.java
deleted file mode 100644
index f3b16119cd..0000000000
--- a/remote/common/src/com/android/layout/remote/util/RemoteInputStream.java
+++ /dev/null
@@ -1,42 +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 com.android.layout.remote.util;
-
-import java.io.IOException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface RemoteInputStream extends Remote {
- int read() throws IOException;
-
- byte[] read(int off, int len) throws IOException;
-
- long skip(long n) throws IOException;
-
- int available() throws IOException;
-
- void close() throws IOException;
-
- void mark(int readlimit) throws RemoteException;
-
- void reset() throws IOException;
-
- boolean markSupported() throws RemoteException;
-
- class EndOfStreamException extends IOException {
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/util/RemoteInputStreamAdapter.java b/remote/common/src/com/android/layout/remote/util/RemoteInputStreamAdapter.java
deleted file mode 100644
index e983202b3f..0000000000
--- a/remote/common/src/com/android/layout/remote/util/RemoteInputStreamAdapter.java
+++ /dev/null
@@ -1,82 +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 com.android.layout.remote.util;
-
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteInputStreamAdapter implements RemoteInputStream {
-
- private InputStream mDelegate;
-
- private RemoteInputStreamAdapter(@NotNull InputStream delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteInputStream create(@NotNull InputStream is) throws RemoteException {
- return (RemoteInputStream) UnicastRemoteObject.exportObject(
- new RemoteInputStreamAdapter(is), 0);
- }
-
- @Override
- public int read() throws IOException {
- return mDelegate.read();
- }
-
- @Override
- public byte[] read(int off, int len) throws IOException, RemoteException {
- byte[] buffer = new byte[len];
- if (mDelegate.read(buffer, off, len) == -1) {
- throw new EndOfStreamException();
- }
- return buffer;
- }
-
- @Override
- public long skip(long n) throws IOException {
- return mDelegate.skip(n);
- }
-
- @Override
- public int available() throws IOException {
- return mDelegate.available();
- }
-
- @Override
- public void close() throws IOException {
- mDelegate.close();
- }
-
- @Override
- public void mark(int readlimit) {
- mDelegate.mark(readlimit);
- }
-
- @Override
- public void reset() throws IOException {
- mDelegate.reset();
- }
-
- @Override
- public boolean markSupported() {
- return mDelegate.markSupported();
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/util/RemoteResolverAdapter.java b/remote/common/src/com/android/layout/remote/util/RemoteResolverAdapter.java
deleted file mode 100644
index f575b95726..0000000000
--- a/remote/common/src/com/android/layout/remote/util/RemoteResolverAdapter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.layout.remote.util;
-
-import com.android.ide.common.rendering.api.ResourceNamespace;
-import com.android.ide.common.rendering.api.ResourceNamespace.Resolver;
-import com.android.layout.remote.api.RemoteNamespaceResolver;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteResolverAdapter implements RemoteNamespaceResolver {
- private final Resolver mDelegate;
-
- private RemoteResolverAdapter(Resolver delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteNamespaceResolver create(@NotNull ResourceNamespace.Resolver delegate)
- throws RemoteException {
- assert !(delegate instanceof RemoteResolverAdapter);
-
- return (RemoteNamespaceResolver) UnicastRemoteObject.exportObject(
- new RemoteResolverAdapter(delegate), 0);
- }
-
- @Override
- public String remotePrefixToUri(String namespacePrefix) {
- return mDelegate.prefixToUri(namespacePrefix);
- }
-
- @Override
- public String remoteUriToPrefix(String namespaceUri) {
- return mDelegate.uriToPrefix(namespaceUri);
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/util/SerializableImageImpl.java b/remote/common/src/com/android/layout/remote/util/SerializableImageImpl.java
deleted file mode 100644
index 59c8c3f277..0000000000
--- a/remote/common/src/com/android/layout/remote/util/SerializableImageImpl.java
+++ /dev/null
@@ -1,55 +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 com.android.layout.remote.util;
-
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-import javax.imageio.ImageIO;
-
-/**
- * Naive implementation of {@link SerializableImage} using {@link ImageIO} and PNG format as
- * transport.
- */
-public class SerializableImageImpl implements SerializableImage {
- @NotNull
- transient private BufferedImage mBufferedImage;
-
- public SerializableImageImpl(@NotNull BufferedImage delegate) {
- mBufferedImage = delegate;
- }
-
- private void writeObject(ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- ImageIO.write(mBufferedImage, "png", out);
- }
-
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
- in.defaultReadObject();
- mBufferedImage = ImageIO.read(in);
- }
-
- @Override
- @NotNull
- public BufferedImage getBufferedImage() {
- return mBufferedImage;
- }
-}
diff --git a/remote/common/src/com/android/layout/remote/util/StreamUtil.java b/remote/common/src/com/android/layout/remote/util/StreamUtil.java
deleted file mode 100644
index e05b5de8a7..0000000000
--- a/remote/common/src/com/android/layout/remote/util/StreamUtil.java
+++ /dev/null
@@ -1,96 +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 com.android.layout.remote.util;
-
-import com.android.layout.remote.util.RemoteInputStream.EndOfStreamException;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.RemoteException;
-
-public class StreamUtil {
- /**
- * Returns a local {@link InputStream} from a {@link RemoteInputStream}
- */
- @NotNull
- public static InputStream getInputStream(@NotNull RemoteInputStream is) {
- return new InputStream() {
- @Override
- public int read() throws IOException {
- return is.read();
- }
-
- @SuppressWarnings("NullableProblems")
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- @SuppressWarnings("NullableProblems")
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- try {
- byte[] read = is.read(off, len);
- int actualLength = Math.min(len, read.length);
- System.arraycopy(read, 0, b, off, actualLength);
- return actualLength;
- } catch (EndOfStreamException e) {
- return -1;
- }
- }
-
- @Override
- public long skip(long n) throws IOException {
- return is.skip(n);
- }
-
- @Override
- public int available() throws IOException {
- return is.available();
- }
-
- @Override
- public void close() throws IOException {
- is.close();
- }
-
- @Override
- public synchronized void mark(int readlimit) {
- try {
- is.mark(readlimit);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public synchronized void reset() throws IOException {
- is.reset();
- }
-
- @Override
- public boolean markSupported() {
- try {
- return is.markSupported();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
- };
- }
-}
diff --git a/remote/server/remote server.iml b/remote/server/remote server.iml
deleted file mode 100644
index 9fc0852bbe..0000000000
--- a/remote/server/remote server.iml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="bridge" />
- <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$MODULE_DIR$/../../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module" module-name="remote common" />
- <orderEntry type="module" module-name="common" />
- </component>
-</module> \ No newline at end of file
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/RemoteBridgeImpl.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/RemoteBridgeImpl.java
deleted file mode 100644
index ef242c1f7e..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/RemoteBridgeImpl.java
+++ /dev/null
@@ -1,149 +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 com.android.layoutlib.bridge.remote.server;
-
-import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.RenderParams;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layout.remote.api.RemoteBridge;
-import com.android.layout.remote.api.RemoteDrawableParams;
-import com.android.layout.remote.api.RemoteLayoutLog;
-import com.android.layout.remote.api.RemoteRenderParams;
-import com.android.layout.remote.api.RemoteRenderSession;
-import com.android.layout.remote.api.RemoteSessionParams;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteAssetRepositoryAdapter;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteILayoutPullParserAdapter;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteLayoutLogAdapter;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteLayoutlibCallbackAdapter;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteRenderResourcesAdapter;
-import com.android.layoutlib.bridge.remote.server.adapters.RemoteRenderSessionAdapter;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.File;
-import java.rmi.RemoteException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Remote {@link Bridge} implementation. This class is the remote entry point for the server. Its
- * responsibility is to receive the remote calls and apply the required transformations to convert
- * it into a regular call to the {@link Bridge} class.
- */
-public class RemoteBridgeImpl implements RemoteBridge {
- private Bridge mBridge = new Bridge();
-
- /**
- * The project keys are used as key for some caches. They are usually expected to remain in
- * memory so WeakReferences are used in the caches.
- * Because in the remote bridge we do not have a real pointer to the object, we keep the strings
- * in memory until they are cleared.
- */
- private Map<String, String> mCachedProjectKeys = new HashMap<>();
-
- @Override
- public boolean init(Map<String, String> platformProperties, File fontLocation,
- String nativeLibPath, String icuDataPath,
- Map<String, Map<String, Integer>> enumValueMap, RemoteLayoutLog log) {
- return mBridge.init(platformProperties, fontLocation, nativeLibPath, icuDataPath,
- enumValueMap, log != null ? new RemoteLayoutLogAdapter(log) : null);
- }
-
- @Override
- public boolean dispose() {
- return mBridge.dispose();
- }
-
- private static void setupRenderParams(@NotNull RenderParams params,
- @NotNull RemoteRenderParams remoteParams) throws RemoteException {
- params.setAssetRepository(new RemoteAssetRepositoryAdapter(remoteParams.getAssets()));
- params.setActivityName(remoteParams.getActivityName());
- params.setAppIcon(remoteParams.getAppIcon());
- params.setAppLabel(remoteParams.getAppLabel());
- params.setTimeout(remoteParams.getTimeout());
- params.setLocale(remoteParams.getLocale());
- if (remoteParams.isForceNoDecor()) {
- params.setForceNoDecor();
- }
- params.setRtlSupport(remoteParams.isRtlSupported());
- if (remoteParams.isTransparentBackground()) {
- params.setTransparentBackground();
- }
- params.setImageFactory(remoteParams.getImageFactory());
- // TODO: Also unpack remote flags and pass them to RenderParams
- }
-
- @NotNull
- @Override
- public RemoteRenderSession createSession(@NotNull RemoteSessionParams remoteParams) {
- try {
- String projectKey = mCachedProjectKeys.putIfAbsent(remoteParams.getProjectKey(),
- remoteParams.getProjectKey());
-
- // Unpack the remote params and convert it into the local SessionParams.
- SessionParams params = new SessionParams(
- new RemoteILayoutPullParserAdapter(remoteParams.getLayoutDescription()),
- remoteParams.getRenderingMode(), projectKey,
- remoteParams.getRemoteHardwareConfig().getHardwareConfig(),
- new RemoteRenderResourcesAdapter(remoteParams.getRemoteResources()),
- new RemoteLayoutlibCallbackAdapter(remoteParams.getRemoteLayoutlibCallback()),
- remoteParams.getMinSdkVersion(), remoteParams.getTargetSdkVersion(),
- new RemoteLayoutLogAdapter(remoteParams.getLog()));
- setupRenderParams(params, remoteParams);
- return RemoteRenderSessionAdapter.create(mBridge.createSession(params));
-
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @NotNull
- @Override
- public Result renderDrawable(@NotNull RemoteDrawableParams remoteParams) {
- try {
- String projectKey = mCachedProjectKeys.putIfAbsent(remoteParams.getProjectKey(),
- remoteParams.getProjectKey());
-
- DrawableParams params = new DrawableParams(
- remoteParams.getDrawable(),
- projectKey,
- remoteParams.getRemoteHardwareConfig().getHardwareConfig(),
- new RemoteRenderResourcesAdapter(remoteParams.getRemoteResources()),
- new RemoteLayoutlibCallbackAdapter(remoteParams.getRemoteLayoutlibCallback()),
- remoteParams.getMinSdkVersion(), remoteParams.getTargetSdkVersion(),
- new RemoteLayoutLogAdapter(remoteParams.getLog()));
- setupRenderParams(params, remoteParams);
- return mBridge.renderDrawable(params);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void clearResourceCaches(String projectKey) {
- mCachedProjectKeys.remove(projectKey);
- mBridge.clearResourceCaches(projectKey);
- }
-
- @Override
- public boolean isRtl(String locale) {
- return mBridge.isRtl(locale);
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/ServerMain.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/ServerMain.java
deleted file mode 100644
index 4c23afc209..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/ServerMain.java
+++ /dev/null
@@ -1,213 +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 com.android.layoutlib.bridge.remote.server;
-
-import com.android.layout.remote.api.RemoteBridge;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-/**
- * Main server class. The main method will start an RMI server for the {@link RemoteBridgeImpl}
- * class.
- */
-public class ServerMain {
- private static final String RUNNING_SERVER_STR = "Server is running on port ";
- public static int REGISTRY_BASE_PORT = 9000;
-
- private final int mPort;
- private final Registry mRegistry;
-
- private ServerMain(int port, @NotNull Registry registry) {
- mPort = port;
- mRegistry = registry;
- }
-
- public int getPort() {
- return mPort;
- }
-
- public void stop() {
- try {
- UnicastRemoteObject.unexportObject(mRegistry, true);
- } catch (NoSuchObjectException ignored) {
- }
- }
-
- private static Thread createOutputProcessor(String outputProcessorName,
- InputStream inputStream,
- Consumer<String> consumer) {
- BufferedReader inputReader = new BufferedReader(new InputStreamReader(inputStream));
- Thread thread = new Thread(() -> inputReader.lines().forEach(consumer));
- thread.setName(outputProcessorName);
- thread.start();
- return thread;
- }
-
- /**
- * This will start a new JVM and connect to the new JVM RMI registry.
- * <p/>
- * The server will start looking for ports available for the {@link Registry} until a free one
- * is found. The port number will be returned.
- * If no ports are available, a {@link RemoteException} will be thrown.
- * @param basePort port number to start looking for available ports
- * @param limit number of ports to check. The last port to be checked will be (basePort + limit)
- */
- public static ServerMain forkAndStartServer(int basePort, int limit)
- throws IOException, InterruptedException {
- // We start a new VM by copying all the parameter that we received in the current VM.
- // We only remove the agentlib parameter since that could cause a port collision and avoid
- // the new VM from starting.
- RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
- List<String> arguments = runtimeMxBean.getInputArguments().stream()
- .filter(arg -> !arg.contains("-agentlib")) // Filter agentlib to avoid conflicts
- .collect(Collectors.toList());
-
- Path javaPath = Paths.get(System.getProperty("java.home"), "bin", "java");
- String thisClassName = ServerMain.class.getName()
- .replace('.','/');
-
- List<String> cmd = new ArrayList<>();
- cmd.add(javaPath.toString());
-
- // Inherited arguments
- cmd.addAll(arguments);
-
- // Classpath
- cmd.add("-cp");
- cmd.add(System.getProperty("java.class.path"));
-
- // Class name and path
- cmd.add(thisClassName);
-
- // ServerMain parameters [basePort. limit]
- cmd.add(Integer.toString(basePort));
- cmd.add(Integer.toString(limit));
-
- Process process = new ProcessBuilder()
- .command(cmd)
- .start();
-
- BlockingQueue<String> outputQueue = new ArrayBlockingQueue<>(10);
- Thread outputThread = createOutputProcessor("output", process.getInputStream(),
- outputQueue::offer);
- Thread errorThread = createOutputProcessor("error", process.getErrorStream(),
- System.err::println);
-
- Runnable killServer = () -> {
- process.destroyForcibly();
- outputThread.interrupt();
- errorThread.interrupt();
- try {
- outputThread.join();
- } catch (InterruptedException ignore) {
- }
-
- try {
- errorThread.join();
- } catch (InterruptedException ignore) {
- }
- };
-
- // Try to read the "Running on port" line in 10 lines. If it's not there just fail.
- for (int i = 0; i < 10; i++) {
- String line = outputQueue.poll(5, TimeUnit.SECONDS);
-
- if (line != null && line.startsWith(RUNNING_SERVER_STR)) {
- int runningPort = Integer.parseInt(line.substring(RUNNING_SERVER_STR.length()));
- System.out.println("Running on port " + runningPort);
-
- // We already know where the server is running so we just need to get the registry
- // and return our own instance of ServerMain
- Registry registry = LocateRegistry.getRegistry(runningPort);
- return new ServerMain(runningPort, registry) {
- @Override
- public void stop() {
- killServer.run();
- }
- };
- }
- }
-
- killServer.run();
- throw new IOException("Unable to find start string");
- }
-
- /**
- * The server will start looking for ports available for the {@link Registry} until a free one
- * is found. The port number will be returned.
- * If no ports are available, a {@link RemoteException} will be thrown.
- * @param basePort port number to start looking for available ports
- * @param limit number of ports to check. The last port to be checked will be (basePort + limit)
- */
- private static ServerMain startServer(int basePort, int limit) throws RemoteException {
- RemoteBridgeImpl remoteBridge = new RemoteBridgeImpl();
- RemoteBridge stub = (RemoteBridge) UnicastRemoteObject.exportObject(remoteBridge, 0);
-
- RemoteException lastException = null;
- for (int port = basePort; port <= basePort + limit; port++) {
- try {
- Registry registry = LocateRegistry.createRegistry(port);
- registry.rebind(RemoteBridge.class.getName(), stub);
- return new ServerMain(port, registry);
- } catch (RemoteException e) {
- lastException = e;
- }
- }
-
- if (lastException == null) {
- lastException = new RemoteException("Unable to start server");
- }
-
- throw lastException;
- }
-
- /**
- * Starts an RMI server that runs in the current JVM. Only for debugging.
- */
- public static ServerMain startLocalJvmServer() throws RemoteException {
- System.err.println("Starting server in the local JVM");
- return startServer(REGISTRY_BASE_PORT, 10);
- }
-
- public static void main(String[] args) throws RemoteException {
- int basePort = args.length > 0 ? Integer.parseInt(args[0]) : REGISTRY_BASE_PORT;
- int limit = args.length > 1 ? Integer.parseInt(args[1]) : 10;
-
- ServerMain server = startServer(basePort, limit);
- System.out.println(RUNNING_SERVER_STR + server.getPort());
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteActionBarCallbackAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteActionBarCallbackAdapter.java
deleted file mode 100644
index d87a94fe30..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteActionBarCallbackAdapter.java
+++ /dev/null
@@ -1,87 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.layout.remote.api.RemoteActionBarCallback;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.util.List;
-
-public class RemoteActionBarCallbackAdapter extends ActionBarCallback {
- private final RemoteActionBarCallback mDelegate;
-
- public RemoteActionBarCallbackAdapter(@NotNull RemoteActionBarCallback remote) {
- mDelegate = remote;
- }
-
- @Override
- public List<ResourceReference> getMenuIds() {
- try {
- return mDelegate.getMenuIds();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean getSplitActionBarWhenNarrow() {
- try {
- return mDelegate.getSplitActionBarWhenNarrow();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getNavigationMode() {
- try {
- return mDelegate.getNavigationMode();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getSubTitle() {
- try {
- return mDelegate.getSubTitle();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public HomeButtonStyle getHomeButtonStyle() {
- try {
- return mDelegate.getHomeButtonStyle();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean isOverflowPopupNeeded() {
- try {
- return mDelegate.isOverflowPopupNeeded();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteAssetRepositoryAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteAssetRepositoryAdapter.java
deleted file mode 100644
index 490f8297cf..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteAssetRepositoryAdapter.java
+++ /dev/null
@@ -1,50 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.layout.remote.api.RemoteAssetRepository;
-import com.android.layout.remote.util.StreamUtil;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.RemoteException;
-
-public class RemoteAssetRepositoryAdapter extends AssetRepository {
- private final RemoteAssetRepository mDelgate;
-
- public RemoteAssetRepositoryAdapter(@NotNull RemoteAssetRepository remote) {
- mDelgate = remote;
- }
-
- @Override
- public boolean isSupported() {
- return true;
- }
-
- @Override
- public InputStream openAsset(String path, int mode) throws IOException, RemoteException {
- return StreamUtil.getInputStream(mDelgate.openAsset(path, mode));
- }
-
- @Override
- public InputStream openNonAsset(int cookie, String path, int mode)
- throws IOException, RemoteException {
- return StreamUtil.getInputStream(mDelgate.openNonAsset(cookie, path, mode));
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteILayoutPullParserAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteILayoutPullParserAdapter.java
deleted file mode 100644
index 3ca0176c8f..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteILayoutPullParserAdapter.java
+++ /dev/null
@@ -1,49 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.ResourceNamespace;
-import com.android.layout.remote.api.RemoteILayoutPullParser;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-
-public class RemoteILayoutPullParserAdapter extends RemoteXmlPullParserAdapter
- implements ILayoutPullParser {
- public RemoteILayoutPullParserAdapter(@NotNull RemoteILayoutPullParser delegate) {
- super(delegate);
- }
-
- @Override
- public Object getViewCookie() {
- try {
- return ((RemoteILayoutPullParser) mDelegate).getViewCookie();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ResourceNamespace getLayoutNamespace() {
- try {
- return ((RemoteILayoutPullParser) mDelegate).getLayoutNamespace();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java
deleted file mode 100644
index 5c48aef252..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java
+++ /dev/null
@@ -1,78 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.ILayoutLog;
-import com.android.layout.remote.api.RemoteLayoutLog;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-
-public class RemoteLayoutLogAdapter implements ILayoutLog {
- private final RemoteLayoutLog mLog;
-
- public RemoteLayoutLogAdapter(@NotNull RemoteLayoutLog log) {
- mLog = log;
- }
-
- @Override
- public void warning(String tag, String message, Object viewCookie, Object data) {
- try {
- mLog.warning(tag, message, viewCookie, null);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void fidelityWarning(String tag, String message, Throwable throwable, Object viewCookie,
- Object data) {
- try {
- mLog.fidelityWarning(tag, message, throwable, viewCookie, data);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void error(String tag, String message, Object viewCookie, Object data) {
- try {
- mLog.error(tag, message, viewCookie, null);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void error(String tag, String message, Throwable throwable, Object viewCookie,
- Object data) {
- try {
- mLog.error(tag, message, throwable, viewCookie, null);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void logAndroidFramework(int priority, String tag, String message) {
- try {
- mLog.logAndroidFramework(priority, tag, message);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutlibCallbackAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutlibCallbackAdapter.java
deleted file mode 100644
index cba8a472ef..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutlibCallbackAdapter.java
+++ /dev/null
@@ -1,286 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.ActionBarCallback;
-import com.android.ide.common.rendering.api.AdapterBinding;
-import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.SessionParams.Key;
-import com.android.layout.remote.api.RemoteLayoutlibCallback;
-import com.android.layoutlib.bridge.MockView;
-import com.android.tools.layoutlib.annotations.NotNull;
-import com.android.tools.layoutlib.annotations.Nullable;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.rmi.RemoteException;
-import java.util.HashMap;
-import java.util.function.Function;
-
-public class RemoteLayoutlibCallbackAdapter extends LayoutlibCallback {
- private final RemoteLayoutlibCallback mDelegate;
- private final PathClassLoader mPathClassLoader;
-
- public RemoteLayoutlibCallbackAdapter(@NotNull RemoteLayoutlibCallback remote) {
- mDelegate = remote;
-
- // Views requested to this callback need to be brought from the "client" side.
- // We transform any loadView into two operations:
- // - First we ask to where the class is located on disk via findClassPath
- // - Second, we instantiate the class in the "server" side
- HashMap<String, Path> nameToPathCache = new HashMap<>();
- Function<String, Path> getPathFromName = cacheName -> nameToPathCache.computeIfAbsent(
- cacheName,
- name -> {
- try {
- return mDelegate.findClassPath(name);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- });
-
- mPathClassLoader = new PathClassLoader(getPathFromName);
- }
-
- @NotNull
- private Object createNewInstance(@NotNull Class<?> clazz,
- @Nullable Class<?>[] constructorSignature, @Nullable Object[] constructorParameters,
- boolean isView)
- throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException,
- IllegalAccessException, InstantiationException {
- Constructor<?> constructor = null;
-
- try {
- constructor = clazz.getConstructor(constructorSignature);
- } catch (NoSuchMethodException e) {
- if (!isView) {
- throw e;
- }
-
- // View class has 1-parameter, 2-parameter and 3-parameter constructors
-
- final int paramsCount = constructorSignature != null ? constructorSignature.length : 0;
- if (paramsCount == 0) {
- throw e;
- }
- assert constructorParameters != null;
-
- for (int i = 3; i >= 1; i--) {
- if (i == paramsCount) {
- continue;
- }
-
- final int k = paramsCount < i ? paramsCount : i;
-
- final Class[] sig = new Class[i];
- System.arraycopy(constructorSignature, 0, sig, 0, k);
-
- final Object[] params = new Object[i];
- System.arraycopy(constructorParameters, 0, params, 0, k);
-
- for (int j = k + 1; j <= i; j++) {
- if (j == 2) {
- sig[j - 1] = findClass("android.util.AttributeSet");
- params[j - 1] = null;
- } else if (j == 3) {
- // parameter 3: int defstyle
- sig[j - 1] = int.class;
- params[j - 1] = 0;
- }
- }
-
- constructorSignature = sig;
- constructorParameters = params;
-
- try {
- constructor = clazz.getConstructor(constructorSignature);
- if (constructor != null) {
- if (constructorSignature.length < 2) {
- // TODO: Convert this to remote
-// LOG.info("wrong_constructor: Custom view " +
-// clazz.getSimpleName() +
-// " is not using the 2- or 3-argument " +
-// "View constructors; XML attributes will not work");
-// mDelegate.warning("wrongconstructor", //$NON-NLS-1$
-// String.format(
-// "Custom view %1$s is not using the 2- or 3-argument
-// View constructors; XML attributes will not work",
-// clazz.getSimpleName()), null, null);
- }
- break;
- }
- } catch (NoSuchMethodException ignored) {
- }
- }
-
- if (constructor == null) {
- throw e;
- }
- }
-
- constructor.setAccessible(true);
- return constructor.newInstance(constructorParameters);
- }
-
- @Override
- public Object loadView(String name, Class[] constructorSignature, Object[] constructorArgs)
- throws Exception {
- Class<?> viewClass = MockView.class;
- try {
- viewClass = findClass(name);
- } catch (ClassNotFoundException ignore) {
- // MockView will be used instead
- }
- return createNewInstance(viewClass, constructorSignature, constructorArgs, true);
- }
-
- @Override
- public ResourceReference resolveResourceId(int id) {
- try {
- return mDelegate.resolveResourceId(id);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getOrGenerateResourceId(ResourceReference resource) {
- try {
- return mDelegate.getOrGenerateResourceId(resource);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ILayoutPullParser getParser(ResourceValue layoutResource) {
- try {
- return new RemoteILayoutPullParserAdapter(mDelegate.getParser(layoutResource));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Object getAdapterItemValue(ResourceReference adapterView, Object adapterCookie,
- ResourceReference itemRef, int fullPosition, int positionPerType,
- int fullParentPosition, int parentPositionPerType, ResourceReference viewRef,
- ViewAttribute viewAttribute, Object defaultValue) {
- return null;
- }
-
- @Override
- public AdapterBinding getAdapterBinding(ResourceReference adapterViewRef, Object adapterCookie,
- Object viewObject) {
- return null;
- }
-
- @Override
- public ActionBarCallback getActionBarCallback() {
- try {
- return new RemoteActionBarCallbackAdapter(mDelegate.getActionBarCallback());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Object loadClass(String name, Class[] constructorSignature, Object[] constructorArgs)
- throws ClassNotFoundException {
- return super.loadClass(name, constructorSignature, constructorArgs);
- }
-
- @Override
- public <T> T getFlag(Key<T> key) {
- return super.getFlag(key);
- }
-
- @Override
- public String getResourcePackage() {
- try {
- return mDelegate.getResourcePackage();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Class<?> findClass(String name) throws ClassNotFoundException {
- return mPathClassLoader.loadClass(name);
- }
-
- @Override
- public XmlPullParser createXmlParserForPsiFile(String fileName) {
- try {
- return new RemoteXmlPullParserAdapter(mDelegate.createXmlParserForPsiFile(fileName));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public XmlPullParser createXmlParserForFile(String fileName) {
- try {
- return new RemoteXmlPullParserAdapter(mDelegate.createXmlParserForFile(fileName));
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public XmlPullParser createXmlParser() {
- try {
- return new RemoteXmlPullParserAdapter(mDelegate.createXmlParser());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Simple class loaders that loads classes from Paths
- */
- private static class PathClassLoader extends ClassLoader {
- private final Function<String, Path> mGetPath;
-
- private PathClassLoader(@NotNull Function<String, Path> getUrl) {
- mGetPath = getUrl;
- }
-
- @Override
- protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {
- Path path = mGetPath.apply(name);
-
- if (path != null) {
- try {
- byte[] content = Files.readAllBytes(path);
- return defineClass(name, content, 0, content.length);
- } catch (IOException ignore) {
- }
- }
-
- throw new ClassNotFoundException(name);
- }
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java
deleted file mode 100644
index 0b9797a770..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java
+++ /dev/null
@@ -1,149 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.ILayoutLog;
-import com.android.ide.common.rendering.api.RenderResources;
-import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.ide.common.rendering.api.ResourceValue;
-import com.android.ide.common.rendering.api.StyleResourceValue;
-import com.android.layout.remote.api.RemoteRenderResources;
-import com.android.layout.remote.api.RemoteResourceValue;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class RemoteRenderResourcesAdapter extends RenderResources {
- private final RemoteRenderResources mDelegate;
-
- public RemoteRenderResourcesAdapter(@NotNull RemoteRenderResources remoteRenderResources) {
- mDelegate = remoteRenderResources;
- }
-
- @Override
- public void setLogger(ILayoutLog logger) {
- // Ignored for remote operations.
- }
-
- @Override
- public StyleResourceValue getDefaultTheme() {
- try {
- return mDelegate.getDefaultTheme().toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void applyStyle(StyleResourceValue theme, boolean useAsPrimary) {
- try {
- mDelegate.applyStyle(RemoteResourceValue.fromResourceValue(theme), useAsPrimary);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void clearStyles() {
- try {
- mDelegate.clearStyles();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public List<StyleResourceValue> getAllThemes() {
- try {
- return mDelegate.getAllThemes().stream()
- .map(RemoteResourceValue::toResourceValue)
- .collect(Collectors.toList());
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ResourceValue findItemInTheme(ResourceReference attr) {
- try {
- return mDelegate.findItemInTheme(attr).toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ResourceValue findItemInStyle(StyleResourceValue style, ResourceReference attr) {
- try {
- return mDelegate.findItemInStyle(RemoteResourceValue.fromResourceValue(style), attr)
- .toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ResourceValue dereference(ResourceValue resourceValue) {
- try {
- return mDelegate.dereference(RemoteResourceValue.fromResourceValue(resourceValue))
- .toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /** Returns a resource by namespace, type and name. The returned resource is unresolved. */
- @Override
- public ResourceValue getUnresolvedResource(ResourceReference reference) {
- try {
- return mDelegate.getUnresolvedResource(reference).toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public ResourceValue resolveResValue(ResourceValue value) {
- try {
- return mDelegate.resolveValue(RemoteResourceValue.fromResourceValue(value))
- .toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public StyleResourceValue getParent(StyleResourceValue style) {
- try {
- return mDelegate.getParent(RemoteResourceValue.fromResourceValue(style))
- .toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public StyleResourceValue getStyle(ResourceReference reference) {
- try {
- return mDelegate.getStyle(reference).toResourceValue();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderSessionAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderSessionAdapter.java
deleted file mode 100644
index 9d292e7199..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderSessionAdapter.java
+++ /dev/null
@@ -1,78 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.ide.common.rendering.api.RenderSession;
-import com.android.ide.common.rendering.api.Result;
-import com.android.layout.remote.api.RemoteRenderSession;
-import com.android.layout.remote.util.SerializableImage;
-import com.android.layout.remote.util.SerializableImageImpl;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-public class RemoteRenderSessionAdapter implements RemoteRenderSession {
- private final RenderSession mDelegate;
-
- private RemoteRenderSessionAdapter(@NotNull RenderSession delegate) {
- mDelegate = delegate;
- }
-
- public static RemoteRenderSession create(@NotNull RenderSession delegate)
- throws RemoteException {
- return (RemoteRenderSession) UnicastRemoteObject.exportObject(
- new RemoteRenderSessionAdapter(delegate), 0);
- }
-
- @NotNull
- @Override
- public Result getResult() throws RemoteException {
- return mDelegate.getResult();
- }
-
- @Override
- public Result render(long timeout, boolean forceMeasure) {
- return mDelegate.render(timeout, forceMeasure);
- }
-
- @NotNull
- @Override
- public SerializableImage getSerializableImage() throws RemoteException {
- return new SerializableImageImpl(mDelegate.getImage());
- }
-
- @Override
- public void setSystemTimeNanos(long nanos) {
- mDelegate.setSystemTimeNanos(nanos);
- }
-
- @Override
- public void setSystemBootTimeNanos(long nanos) {
- mDelegate.setSystemBootTimeNanos(nanos);
- }
-
- @Override
- public void setElapsedFrameTimeNanos(long nanos) {
- mDelegate.setElapsedFrameTimeNanos(nanos);
- }
-
- @Override
- public void dispose() {
- mDelegate.dispose();
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteXmlPullParserAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteXmlPullParserAdapter.java
deleted file mode 100644
index 6de03bb28d..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteXmlPullParserAdapter.java
+++ /dev/null
@@ -1,353 +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 com.android.layoutlib.bridge.remote.server.adapters;
-
-import com.android.layout.remote.api.RemoteXmlPullParser;
-import com.android.layout.remote.util.RemoteInputStreamAdapter;
-import com.android.tools.layoutlib.annotations.NotNull;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.rmi.RemoteException;
-
-class RemoteXmlPullParserAdapter implements XmlPullParser {
- protected RemoteXmlPullParser mDelegate;
-
- RemoteXmlPullParserAdapter(@NotNull RemoteXmlPullParser remote) {
- mDelegate = remote;
- }
-
- @Override
- public void setFeature(String name, boolean state) throws XmlPullParserException {
- try {
- mDelegate.setFeature(name, state);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean getFeature(String name) {
- try {
- return mDelegate.getFeature(name);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setProperty(String name, Object value) throws XmlPullParserException {
- try {
- mDelegate.setProperty(name, value);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Object getProperty(String name) {
- try {
- return mDelegate.getProperty(name);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setInput(Reader in) throws XmlPullParserException {
- try {
- mDelegate.setInput(in);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void setInput(InputStream inputStream, String inputEncoding)
- throws XmlPullParserException {
- try {
- mDelegate.setInput(RemoteInputStreamAdapter.create(inputStream), inputEncoding);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getInputEncoding() {
- try {
- return mDelegate.getInputEncoding();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void defineEntityReplacementText(String entityName, String replacementText)
- throws XmlPullParserException {
- try {
- mDelegate.defineEntityReplacementText(entityName, replacementText);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getNamespaceCount(int depth) throws XmlPullParserException {
- try {
- return mDelegate.getNamespaceCount(depth);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getNamespacePrefix(int pos) throws XmlPullParserException {
- try {
- return mDelegate.getNamespacePrefix(pos);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getNamespaceUri(int pos) throws XmlPullParserException {
- try {
- return mDelegate.getNamespaceUri(pos);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getNamespace(String prefix) {
- try {
- return mDelegate.getNamespace(prefix);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getDepth() {
- try {
- return mDelegate.getDepth();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getPositionDescription() {
- try {
- return mDelegate.getPositionDescription();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getLineNumber() {
- try {
- return mDelegate.getLineNumber();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getColumnNumber() {
- try {
- return mDelegate.getColumnNumber();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean isWhitespace() throws XmlPullParserException {
- try {
- return mDelegate.isWhitespace();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getText() {
- try {
- return mDelegate.getText();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public char[] getTextCharacters(int[] holderForStartAndLength) {
- try {
- return mDelegate.getTextCharacters(holderForStartAndLength);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getNamespace() {
- try {
- return mDelegate.getNamespace();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getName() {
- try {
- return mDelegate.getName();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getPrefix() {
- try {
- return mDelegate.getPrefix();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean isEmptyElementTag() throws XmlPullParserException {
- try {
- return mDelegate.isEmptyElementTag();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getAttributeCount() {
- try {
- return mDelegate.getAttributeCount();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributeNamespace(int index) {
- try {
- return mDelegate.getAttributeNamespace(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributeName(int index) {
- try {
- return mDelegate.getAttributeName(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributePrefix(int index) {
- try {
- return mDelegate.getAttributePrefix(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributeType(int index) {
- try {
- return mDelegate.getAttributeType(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public boolean isAttributeDefault(int index) {
- try {
- return mDelegate.isAttributeDefault(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributeValue(int index) {
- try {
- return mDelegate.getAttributeValue(index);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public String getAttributeValue(String namespace, String name) {
- try {
- return mDelegate.getAttributeValue(namespace, name);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int getEventType() throws XmlPullParserException {
- try {
- return mDelegate.getEventType();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public int next() throws XmlPullParserException, IOException {
- return mDelegate.next();
- }
-
- @Override
- public int nextToken() throws XmlPullParserException, IOException {
- return mDelegate.nextToken();
- }
-
- @Override
- public void require(int type, String namespace, String name)
- throws XmlPullParserException, IOException {
- mDelegate.require(type, namespace, name);
- }
-
- @Override
- public String nextText() throws XmlPullParserException, IOException {
- return mDelegate.nextText();
- }
-
- @Override
- public int nextTag() throws XmlPullParserException, IOException {
- return mDelegate.nextTag();
- }
-}
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/package-info.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/package-info.java
deleted file mode 100644
index 24917597a5..0000000000
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Package containing all the server side adapters. These adapters have the mission of receiving
- * local calls and translating them into the remote API.
- */
-package com.android.layoutlib.bridge.remote.server.adapters; \ No newline at end of file
diff --git a/remote/tests/remote tests.iml b/remote/tests/remote tests.iml
deleted file mode 100644
index de0a53a0db..0000000000
--- a/remote/tests/remote tests.iml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="true" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="remote client" scope="TEST" />
- <orderEntry type="module" module-name="bridge" scope="TEST" />
- <orderEntry type="library" scope="TEST" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="module-library" scope="TEST">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module-library" scope="TEST">
- <library>
- <ANNOTATIONS>
- <root url="file://$MODULE_DIR$/../.." />
- </ANNOTATIONS>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module-library" scope="TEST">
- <library>
- <ANNOTATIONS>
- <root url="file://$MODULE_DIR$/../.." />
- </ANNOTATIONS>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="module-library" scope="TEST">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="library" scope="TEST" name="framework.jar" level="project" />
- <orderEntry type="module-library" scope="TEST">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$MODULE_DIR$/../../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
- </orderEntry>
- <orderEntry type="library" scope="TEST" name="junit" level="project" />
- <orderEntry type="module" module-name="remote server" scope="TEST" />
- <orderEntry type="module" module-name="remote common" scope="TEST" />
- </component>
-</module> \ No newline at end of file
diff --git a/remote/tests/src/RemoteBridgeTest.java b/remote/tests/src/RemoteBridgeTest.java
deleted file mode 100644
index 5dd3b4fe77..0000000000
--- a/remote/tests/src/RemoteBridgeTest.java
+++ /dev/null
@@ -1,146 +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.
- */
-
-import com.android.ide.common.rendering.api.Bridge;
-import com.android.ide.common.rendering.api.Result;
-import com.android.ide.common.rendering.api.SessionParams;
-import com.android.layoutlib.bridge.intensive.RenderResult;
-import com.android.layoutlib.bridge.intensive.RenderTestBase;
-import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
-import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
-import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
-import com.android.layoutlib.bridge.intensive.util.ImageUtils;
-import com.android.layoutlib.bridge.remote.client.RemoteBridgeClient;
-import com.android.layoutlib.bridge.remote.server.ServerMain;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.rmi.NotBoundException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-
-public class RemoteBridgeTest extends RenderTestBase {
- private ServerMain mServerMain;
- private RemoteBridgeClient mClient;
-
- /**
- * Copy of RenderTestBase.renderAndVerify that allows using a different Bridge. TODO: Merge back
- * into RenderTestBase
- */
- protected static RenderResult renderAndVerify(Bridge bridge, SessionParams params,
- String goldenFileName, long frameTimeNanos) throws ClassNotFoundException {
- RenderResult result = RenderTestBase.render(bridge, params, frameTimeNanos);
- try {
- String goldenImagePath = APP_TEST_DIR + "/golden/" + goldenFileName;
- assertNotNull(result.getImage());
- ImageUtils.requireSimilar(goldenImagePath, result.getImage());
- } catch (IOException e) {
- getLogger().error(e, e.getMessage());
- }
-
- return result;
- }
-
- @Before
- public void setupServer() throws IOException, NotBoundException, InterruptedException {
- long startTime = System.currentTimeMillis();
- mServerMain = ServerMain.forkAndStartServer(ServerMain.REGISTRY_BASE_PORT, 10);
- mClient = RemoteBridgeClient.getRemoteBridge(mServerMain.getPort());
- System.out.printf("Server started in %dms\n", System.currentTimeMillis() - startTime);
- startTime = System.currentTimeMillis();
-
- File data_dir = new File(PLATFORM_DIR, "data");
- File res = new File(data_dir, "res");
- File fontLocation = new File(data_dir, "fonts");
- File buildProp = new File(PLATFORM_DIR, "build.prop");
- File attrs = new File(res, "values" + File.separator + "attrs.xml");
-
- mClient.init(ConfigGenerator.loadProperties(buildProp), fontLocation, null, null,
- ConfigGenerator.getEnumMap(attrs), getLayoutLog());
- System.out.printf("Remote client init took %dms\n",
- System.currentTimeMillis() - startTime);
- }
-
- @After
- public void stopServer() {
- mClient.dispose();
- mServerMain.stop();
- }
-
- /**
- * Same test as RenderTest#testActivity but using the remote bridge
- */
- @Test
- public void testActivity() throws IOException, ClassNotFoundException {
- SessionParams params = createSessionParams("activity.xml", ConfigGenerator.NEXUS_5);
- RenderResult result = renderAndVerify(mClient, params, "activity.png", 250);
- assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
- if (result.getResult().getException() != null) {
- result.getResult().getException().printStackTrace();
- fail("Unexpected exception");
- }
- }
-
- /**
- * Same test as RenderTest#testActivity but using the remote bridge
- */
- @Test
- public void testCustomClassLoading() throws ClassNotFoundException {
- LayoutLibTestCallback layoutLibCallback =
- new LayoutLibTestCallback(getLogger(), mDefaultClassLoader);
- layoutLibCallback.initResources();
-
- LayoutPullParser parser = LayoutPullParser.createFromString(
- "<CustomComponent xmlns:android=\"http://schemas" +
- ".android.com/apk/res/android\"\n" +
- " android:layout_width=\"match_parent\"\n" +
- " android:layout_height=\"match_parent\"\n>" +
- "</CustomComponent>");
- SessionParams params =
- getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
- "Theme.NoTitleBar", false).build();
-
- RenderResult result = renderAndVerify(mClient, params, "remote_component_load.png", 250);
- assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
- if (result.getResult().getException() != null) {
- result.getResult().getException().printStackTrace();
- fail("Unexpected exception");
- }
-
- parser = LayoutPullParser.createFromString(
- "<MissingCustomComponent xmlns:android=\"http://schemas" +
- ".android.com/apk/res/android\"\n" +
- " android:layout_width=\"match_parent\"\n" +
- " android:layout_height=\"match_parent\"\n>" +
- "</MissingCustomComponent>");
- params =
- getSessionParamsBuilder().setParser(parser).setCallback(layoutLibCallback).setTheme(
- "Theme.NoTitleBar", false).build();
- result = renderAndVerify(mClient, params, "remote_component_load_fail.png", 250);
- assertEquals(Result.Status.SUCCESS, result.getResult().getStatus());
- if (result.getResult().getException() != null) {
- result.getResult().getException().printStackTrace();
- fail("Unexpected exception");
- }
- }
-} \ No newline at end of file
diff --git a/validator/Android.bp b/validator/Android.bp
index 2ca1f21aba..1581c96515 100644
--- a/validator/Android.bp
+++ b/validator/Android.bp
@@ -34,6 +34,6 @@ java_library_host {
static_libs: [
"hamcrest",
"jsoup-1.6.3",
- "protobuf-lite",
+ "libprotobuf-java-lite",
],
}
diff --git a/validator/resources/strings.properties b/validator/resources/strings.properties
index 7b324b94ca..27f310cfa3 100644
--- a/validator/resources/strings.properties
+++ b/validator/resources/strings.properties
@@ -24,10 +24,6 @@ result_message_view_not_within_screencapture = This item\'s on-screen location (
result_message_screencapture_data_hidden = Screen capture information for this item was hidden.
result_message_screencapture_uniform_color = Screen capture has a uniform color.
clickable = clickable
-non_clickable = non-clickable
-long_clickable = long clickable
-clickable_and_long_clickable = clickable and long clickable
-actionable = actionable
result_message_sdk_version_not_applicable = This check is not applicable on devices running Android %1$s and above.
result_message_addendum_view_potentially_obscured = This item may be obscured by other on-screen content. Consider manually testing this item\'s contrast.
check_title_clickablespan = Link
@@ -38,6 +34,10 @@ check_title_duplicate_clickable_bounds = Clickable items
result_message_brief_same_view_bounds = Multiple %1$s items share this location on the screen.
result_message_same_view_bounds = This %1$s item has the same on-screen location (<tt>%2$s</tt>) as %3$d other item(s) with those properties.
result_message_view_bounds = This %1$s item also has an on-screen location of <tt>%2$s</tt>.
+non_clickable = non-clickable
+long_clickable = long clickable
+clickable_and_long_clickable = clickable and long clickable
+actionable = actionable
check_title_duplicate_speakable_text = Item descriptions
result_message_brief_same_speakable_text = Multiple items have the same description.
result_message_same_speakable_text = This %1$s item\'s speakable text: \"<tt>%2$s</tt>\" is identical to that of %3$d other item(s).
@@ -48,10 +48,10 @@ result_message_not_editable_textview = This item is not an editable <tt>TextView
check_title_image_contrast = Image contrast
result_message_not_imageview = This item is not an <tt>ImageView</tt>.
result_message_brief_image_contrast_not_sufficient = Consider increasing the contrast ratio between this image\'s foreground and background.
-result_message_image_contrast_not_sufficient = The image\'s contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%3$06X</tt> and an estimated background color of <tt>#%4$06X</tt>. Consider increasing this ratio to %2$.2f or greater.
-result_message_image_contrast_not_sufficient_confirmed = The image\'s contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%3$06X</tt> and provided background color of <tt>#%4$06X</tt>. Consider increasing this ratio to %2$.2f or greater.
-result_message_image_customized_contrast_not_sufficient = The image\'s contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%3$06X</tt> and an estimated background color of <tt>#%4$06X</tt>. Consider increasing this ratio to the modified ratio of %2$.2f or greater.
-result_message_image_customized_contrast_not_sufficient_confirmed = The image\'s contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%3$06X</tt> and provided background color of <tt>#%4$06X</tt>. Consider increasing this ratio to the modified ratio of %2$.2f or greater.
+result_message_image_contrast_not_sufficient = The image\'s contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>%3$s</tt> and an estimated background color of <tt>%4$s</tt>. Consider increasing this ratio to %2$.2f or greater.
+result_message_image_contrast_not_sufficient_confirmed = The image\'s contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>%3$s</tt> and provided background color of <tt>%4$s</tt>. Consider increasing this ratio to %2$.2f or greater.
+result_message_image_customized_contrast_not_sufficient = The image\'s contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>%3$s</tt> and an estimated background color of <tt>%4$s</tt>. Consider increasing this ratio to the modified ratio of %2$.2f or greater.
+result_message_image_customized_contrast_not_sufficient_confirmed = The image\'s contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>%3$s</tt> and provided background color of <tt>%4$s</tt>. Consider increasing this ratio to the modified ratio of %2$.2f or greater.
check_title_redundant_description = Item type label
result_message_english_locale_only = This check only runs on devices with locales set to English.
result_message_brief_content_desc_contains_redundant_word = This item\'s <tt>android:contentDescription</tt> might contain unnecessary text.
@@ -72,6 +72,7 @@ tap_action = tap
check_title_speakable_text_present = Item label
result_message_should_not_focus = This item would not be focused by a screen reader.
result_message_web_content = Web content is not evaluated.
+result_message_unsupported_compose_content = Composable content is not evaluated in this environment.
result_message_missing_speakable_text = This item may not have a label readable by screen readers.
check_title_text_contrast = Text contrast
result_message_textview_empty = This <tt>TextView</tt> is empty.
@@ -81,14 +82,18 @@ result_message_text_must_be_opaque = This item\'s text color is not opaque.
result_message_background_must_be_opaque = This items\'s background color is not opaque.
result_message_addendum_opacity_description = Its actual opacity is %1$.2f%%.
result_message_brief_text_contrast_not_sufficient = Consider increasing this item\'s text foreground to background contrast ratio.
-result_message_textview_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on a text color of <tt>#%2$06X</tt> and background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
-result_message_customized_textview_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on a text color of <tt>#%2$06X</tt> and background color of <tt>#%3$06X</tt>. Consider using colors that result in a contrast ratio greater than the modified ratio of %4$.2f.
-result_message_textview_heuristic_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%2$06X</tt> and an estimated background color of <tt>#%3$06X</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text.
-result_message_textview_heuristic_contrast_not_sufficient_when_text_size_available = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%2$06X</tt> and an estimated background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
-result_message_textview_heuristic_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text.
-result_message_textview_heuristic_contrast_not_sufficient_when_text_size_available_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
-result_message_textview_heuristic_customized_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%2$06X</tt> and an estimated background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the modified ratio of %4$.2f or greater.
-result_message_textview_heuristic_customized_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the modified ratio of %4$.2f or greater.
+result_message_textview_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on a text color of <tt>%2$s</tt> and background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
+result_message_customized_textview_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on a text color of <tt>%2$s</tt> and background color of <tt>%3$s</tt>. Consider using colors that result in a contrast ratio greater than the modified ratio of %4$.2f.
+result_message_textview_upper_bound_contrast_not_sufficient = The item\'s maximum possible text contrast ratio is %1$.2f, based on a text color of <tt>%2$s</tt> and non-opaque background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
+result_message_customized_textview_upper_bound_contrast_not_sufficient = The item\'s maximum possible text contrast ratio is %1$.2f, based on a text color of <tt>%2$s</tt> and non-opaque background color of <tt>%3$s</tt>. Consider using colors that result in a contrast ratio greater than the modified ratio of %4$.2f.
+result_message_textview_lower_bound_contrast_not_sufficient = The item\'s minimum possible text contrast ratio is %1$.2f, based on a text color of <tt>%2$s</tt> and non-opaque background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
+result_message_customized_textview_lower_bound_contrast_not_sufficient = The item\'s minimum possible text contrast ratio is %1$.2f, based on a text color of <tt>%2$s</tt> and non-opaque background color of <tt>%3$s</tt>. Consider using colors that result in a contrast ratio greater than the modified ratio of %4$.2f.
+result_message_textview_heuristic_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>%2$s</tt> and an estimated background color of <tt>%3$s</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text.
+result_message_textview_heuristic_contrast_not_sufficient_when_text_size_available = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>%2$s</tt> and an estimated background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
+result_message_textview_heuristic_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>%2$s</tt> and provided background color of <tt>%3$s</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text.
+result_message_textview_heuristic_contrast_not_sufficient_when_text_size_available_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>%2$s</tt> and provided background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to %4$.2f or greater.
+result_message_textview_heuristic_customized_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>%2$s</tt> and an estimated background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to the modified ratio of %4$.2f or greater.
+result_message_textview_heuristic_customized_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>%2$s</tt> and provided background color of <tt>%3$s</tt>. Consider increasing this item\'s text contrast ratio to the modified ratio of %4$.2f or greater.
result_message_contrast_sufficient_confirmed = This item\'s foreground and background colors meet the suggested contrast ratio.
result_message_customized_contrast_sufficient_confirmed = This item\'s foreground and background colors meet the modified contrast ratio.
question_id_message_confirm_foreground_background_colors = Are the detected foreground and background colors correct?
@@ -113,6 +118,7 @@ result_message_addendum_touch_delegate_with_hit_rect = A <tt>TouchDelegate</tt>
result_message_addendum_clickable_ancestor = A parent container may be handling touch events for this item. If selecting the larger container performs the same action as selecting this item, consider defining this item as not clickable. If a different action is performed, consider increasing the size of this item.
result_message_addendum_clipped_by_ancestor = A parent container may be clipping the size of this item, which has a drawing area of <tt>%1$ddp</tt> x <tt>%2$ddp</tt>. Consider increasing the size of this item\'s clipping ancestor, or allowing a larger parent container to handle actions on behalf of this item.
result_message_addendum_against_scrollable_edge = This item may be only partially visible within a scrollable container.
+result_message_addendum_web_touch_target_size = This item originates from web content, and additional verification of touch target size is recommended.
check_title_class_name_not_supported = Unsupported item type
result_message_class_name_not_supported_brief = This item\'s type may not be supported.
result_message_class_name_not_supported_detail = This item\'s type <tt>%1$s</tt> may not be resolvable by accessibility services. Consider using a type defined by the Android SDK.
@@ -145,9 +151,40 @@ result_message_has_unexposed_items = This screen may have items that are not exp
result_message_is_unexposed_item_screen_region = The region with on-screen location <tt>%1$s</tt> contains at least one item that is not exposed to accessibility services.
check_title_item_exposed = Exposed items
result_message_brief_is_unexposed_item_screen_region = Consider exposing items in this region to accessibility services.
-check_title_text_size = Text Size
+check_title_text_size = Text Scaling
+result_message_no_text_size_unit = Text size unit could not be obtained.
+result_message_brief_text_size_unit = This item\'s text size unit is <tt>%1$s</tt>.
+result_message_item_type_with_text_size_unit = <tt>%1$s</tt> with text size unit of <tt>%2$s</tt>.
+result_message_small_fixed_text_size = This text is small and may be difficult for some users to read. Consider using a larger size or specifying the text size in scaled pixels (<tt>sp</tt>).
+result_message_fixed_text_size = Consider specifying the text size in scaled pixels (<tt>sp</tt>).
+result_message_brief_fixed_width_text_view_with_scaled_text = This <tt>TextView</tt> has a fixed width and scalable text.
+result_message_brief_fixed_height_text_view_with_scaled_text = This <tt>TextView</tt> has a fixed height and scalable text.
+result_message_brief_fixed_size_text_view_with_scaled_text = This <tt>TextView</tt> has a fixed size and scalable text.
+result_message_brief_fixed_width_view_group_with_scaled_text = This <tt>ViewGroup</tt> has a fixed width and contains a <tt>TextView</tt> with scalable text.
+result_message_brief_fixed_height_view_group_with_scaled_text = This <tt>ViewGroup</tt> has a fixed height and contains a <tt>TextView</tt> with scalable text.
+result_message_brief_fixed_size_view_group_with_scaled_text = This <tt>ViewGroup</tt> has a fixed size and contains a <tt>TextView</tt> with scalable text.
+result_message_fixed_size_text_view_with_scaled_text = Consider modifying the <tt>LayoutParams</tt> to allow for text expansion.
+check_title_unexposed_text = Unexposed Text
+result_message_unexposed_text = Ensure this item's accessibility label includes its visible text.
+result_message_text_detected_in_image_view = OCR results were detected inside this ImageView.
+result_message_brief_unexposed_text = Unexposed text detected: %1$s
+result_message_brief_text_detected_in_image_view = Text detected: %1$s
+result_message_text_detected_in_surface_view = This <tt>SurfaceView</tt> may not be exposing its content to accessibility services.
+result_message_brief_multiple_unexposed_texts = Multiple unexposed texts detected, including "%1$s".
+result_message_multiple_unexposed_texts = This item may not be exposing its content to accessibility services.
+result_message_ocr_result_not_available = OCR results are not available.
+result_message_no_matching_ocr_results = No OCR results were detected inside this item.
+result_message_multiple_best_match_views = One OCR result was detected inside multiple focusable items.
+result_message_single_ocr_character_without_text = An OCR result with a single character was detected, but no text exists at that location.
question_message_screen_has_unexposed_items = Does this screen contain important items that are not outlined?
question_message_identify_unexposed_items = Select regions of the screen with unidentified items.
suggestion_remove_view_attribute = Remove this item\'s <tt>%1$s</tt>.
suggestion_set_view_attribute = Set this item\'s <tt>%1$s</tt> to <tt>%2$s</tt>.
suggestion_set_view_attribute_with_an_non_empty_string = Set this item\'s <tt>%1$s</tt> to a meaningful non-empty string or resource reference.
+value_checked = checked
+value_not_checked = not checked
+value_on = on
+value_off = off
+template_containers_quantity_other = %1$s showing %2$d items.
+template_labeled_item = %1$s for %2$s
+value_listview = List
diff --git a/validator/src/com/android/tools/idea/validator/LayoutValidator.java b/validator/src/com/android/tools/idea/validator/LayoutValidator.java
index 03f080ca40..3a5067c94f 100644
--- a/validator/src/com/android/tools/idea/validator/LayoutValidator.java
+++ b/validator/src/com/android/tools/idea/validator/LayoutValidator.java
@@ -43,7 +43,7 @@ public class LayoutValidator {
private static boolean sSaveCroppedImages = false;
- private static boolean sObtainCharacterLocations = false;
+ private static boolean sObtainCharacterLocations = true;
/**
* @return true if validator is paused. False otherwise.
diff --git a/validator/src/com/android/tools/idea/validator/ValidatorUtil.java b/validator/src/com/android/tools/idea/validator/ValidatorUtil.java
index 0e944f14f5..6078046de5 100644
--- a/validator/src/com/android/tools/idea/validator/ValidatorUtil.java
+++ b/validator/src/com/android/tools/idea/validator/ValidatorUtil.java
@@ -83,6 +83,8 @@ public class ValidatorUtil {
* uses be redirected.
*/
StringManager.setResourceBundleProvider(locale -> ResourceBundle.getBundle("strings"));
+ // Enable using AccessibilityNodeInfo in addition to View for accessibility testing
+ AccessibilityHierarchyAndroid.viewOverlayEnabled = true;
}
// Visible for testing.
@@ -98,6 +100,12 @@ public class ValidatorUtil {
TextContrastCheck.class, TouchTargetSizeCheck.class, EditableContentDescCheck.class);
/**
+ * The maximum allowed length of the requested text location data is used to avoid the
+ * performance issue caused by obtaining character location data for a view with a long text.
+ */
+ public static final int CHARACTER_LOCATION_ARG_MAX_LENGTH = 100;
+
+ /**
* @param policy policy to apply for the hierarchy
* @param view root view to build hierarchy from
* @param image screenshot image that matches the view
@@ -124,6 +132,7 @@ public class ValidatorUtil {
.newBuilder(view)
.setViewOriginMap(builder.mSrcMap)
.setObtainCharacterLocations(LayoutValidator.obtainCharacterLocations())
+ .setCharacterLocationArgMaxLength(CHARACTER_LOCATION_ARG_MAX_LENGTH)
.setCustomViewBuilder(new CustomViewBuilderAndroid() {
@Override
public Class<?> getClassByName(
diff --git a/validator/validator.iml b/validator/validator.iml
index 6d92c11dfd..094889e942 100644
--- a/validator/validator.iml
+++ b/validator/validator.iml
@@ -9,38 +9,11 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="framework.jar" level="project" />
- <orderEntry type="module-library">
- <library name="guava">
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/22.0/guava-22.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/22.0/guava-22.0-sources.jar!/" />
- </SOURCES>
- </library>
- </orderEntry>
+ <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
<orderEntry type="module" module-name="common" />
- <orderEntry type="library" name="framework.jar" level="project" />
+ <orderEntry type="library" name="guava" level="project" />
<orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/com/google/protobuf/protobuf-lite/3.0.1/protobuf-lite-3.0.1.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/m2/repository/org/jsoup/jsoup/1.6.3/jsoup-1.6.3.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
- <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
+ <orderEntry type="library" name="jsoup" level="project" />
+ <orderEntry type="library" name="libprotobuf-java-lite" level="project" />
</component>
</module> \ No newline at end of file