From cdce14f6701685f4903764a64b5c3f460e2e3e91 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 30 Jul 2021 22:14:41 -0700 Subject: [PATCH] Implement PlatformColor in Fabric Android Summary: This diff implements PlatformColor in Fabric Android changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D29841461 fbshipit-source-id: 63a523626b021c634bc399e749b639b55730391a --- .../react/fabric/FabricUIManager.java | 9 +++ .../react/renderer/graphics/Android.mk | 5 +- ReactCommon/react/renderer/graphics/BUCK | 11 +++ .../react/renderer/graphics/conversions.h | 27 ++++---- .../renderer/graphics/PlatformColorParser.h | 69 +++++++++++++++++++ .../renderer/graphics/PlatformColorParser.h | 29 ++++++++ .../platform/ios/PlatformColorParser.h | 30 ++++++++ packages/react-native-codegen/DEFS.bzl | 5 +- 8 files changed, 169 insertions(+), 16 deletions(-) create mode 100644 ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h create mode 100644 ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h create mode 100644 ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 80dec6b13b2..ea132670201 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -35,6 +35,7 @@ import com.facebook.debug.holder.PrinterHolder; import com.facebook.debug.tags.ReactDebugOverlayTags; import com.facebook.infer.annotation.ThreadConfined; import com.facebook.proguard.annotations.DoNotStripAny; +import com.facebook.react.bridge.ColorPropConverter; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeMap; @@ -458,6 +459,14 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { null); } + @SuppressWarnings("unused") + public int getColor(int surfaceId, ReadableMap platformColor) { + ThemedReactContext context = + mMountingManager.getSurfaceManagerEnforced(surfaceId, "getColor").getContext(); + Integer color = ColorPropConverter.getColor(platformColor, context); + return color != null ? color : 0; + } + @SuppressWarnings("unused") private long measure( int surfaceId, diff --git a/ReactCommon/react/renderer/graphics/Android.mk b/ReactCommon/react/renderer/graphics/Android.mk index 6acf73f28df..c38de58cec3 100644 --- a/ReactCommon/react/renderer/graphics/Android.mk +++ b/ReactCommon/react/renderer/graphics/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_render_graphics LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp $(LOCAL_PATH)/platform/cxx/react/renderer/graphics/*.cpp) -LOCAL_SHARED_LIBRARIES := libfolly_json libreact_debug +LOCAL_SHARED_LIBRARIES := libfolly_json libreact_debug libfb libfbjni libfolly_json glog LOCAL_STATIC_LIBRARIES := @@ -26,5 +26,8 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++17 -Wall include $(BUILD_SHARED_LIBRARY) +$(call import-module,glog) +$(call import-module,fbjni) +$(call import-module,fb) $(call import-module,folly) $(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/graphics/BUCK b/ReactCommon/react/renderer/graphics/BUCK index 7ff757f58fd..818d51faae6 100644 --- a/ReactCommon/react/renderer/graphics/BUCK +++ b/ReactCommon/react/renderer/graphics/BUCK @@ -3,10 +3,12 @@ load( "ANDROID", "APPLE", "CXX", + "FBJNI_TARGET", "fb_xplat_cxx_test", "get_apple_compiler_flags", "get_apple_inspector_flags", "get_preprocessor_flags_for_build_mode", + "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob", @@ -51,16 +53,25 @@ rn_xplat_cxx_library( "platform/cxx/react/renderer/graphics/**/*.cpp", ], ), + fbandroid_allow_jni_merging = True, + fbandroid_deps = [ + FBJNI_TARGET, + react_native_target("jni/react/jni:jni"), + ], fbandroid_exported_headers = subdir_glob( [ + ("platform/android/react/renderer/graphics", "**/*.h"), ("platform/cxx/react/renderer/graphics", "**/*.h"), ], + exclude = ["platform/cxx/react/renderer/graphics/PlatformColorParser.h"], prefix = "react/renderer/graphics", ), fbandroid_srcs = glob( [ "platform/cxx/react/renderer/graphics/**/*.cpp", + "platform/android/react/renderer/graphics/**/*.cpp", ], + exclude = ["platform/cxx/react/renderer/graphics/PlatformColorParser.h"], ), fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), diff --git a/ReactCommon/react/renderer/graphics/conversions.h b/ReactCommon/react/renderer/graphics/conversions.h index dfa06ac0479..a30d03daf64 100644 --- a/ReactCommon/react/renderer/graphics/conversions.h +++ b/ReactCommon/react/renderer/graphics/conversions.h @@ -8,13 +8,13 @@ #pragma once #include -#include #include #include #include #include #include #include +#include namespace facebook { namespace react { @@ -25,29 +25,28 @@ inline void fromRawValue( const PropsParserContext &context, const RawValue &value, SharedColor &result) { - float red = 0; - float green = 0; - float blue = 0; - float alpha = 0; + ColorComponents colorComponents = {0, 0, 0, 0}; if (value.hasType()) { auto argb = (int64_t)value; auto ratio = 255.f; - alpha = ((argb >> 24) & 0xFF) / ratio; - red = ((argb >> 16) & 0xFF) / ratio; - green = ((argb >> 8) & 0xFF) / ratio; - blue = (argb & 0xFF) / ratio; + colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio; + colorComponents.red = ((argb >> 16) & 0xFF) / ratio; + colorComponents.green = ((argb >> 8) & 0xFF) / ratio; + colorComponents.blue = (argb & 0xFF) / ratio; } else if (value.hasType>()) { auto items = (std::vector)value; auto length = items.size(); react_native_assert(length == 3 || length == 4); - red = items.at(0); - green = items.at(1); - blue = items.at(2); - alpha = length == 4 ? items.at(3) : 1.0f; + colorComponents.red = items.at(0); + colorComponents.green = items.at(1); + colorComponents.blue = items.at(2); + colorComponents.alpha = length == 4 ? items.at(3) : 1.0f; + } else { + colorComponents = parsePlatformColor(context, value); } - result = colorFromComponents({red, green, blue, alpha}); + result = colorFromComponents(colorComponents); } #ifdef ANDROID diff --git a/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h b/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h new file mode 100644 index 00000000000..7023aa6f60f --- /dev/null +++ b/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include + +using namespace facebook::jni; + +namespace facebook { +namespace react { + +inline ColorComponents parsePlatformColor( + const PropsParserContext &context, + const RawValue &value) { + ColorComponents colorComponents = {0, 0, 0, 0}; + + if (value.hasType>>()) { + auto map = (better::map>)value; + auto resourcePaths = map["resource_paths"]; + auto dynamicResourcePaths = folly::dynamic::array(); + for (const auto &resourcePath : resourcePaths) { + dynamicResourcePaths.push_back(resourcePath); + } + folly::dynamic dynamicPlatformColor = folly::dynamic::object(); + dynamicPlatformColor["resource_paths"] = dynamicResourcePaths; + + auto fabricUIManager = + context.contextContainer.at>( + "FabricUIManager"); + + static auto getColorFromJava = + facebook::jni::findClassStatic( + "com/facebook/react/fabric/FabricUIManager") + ->getMethod("getColor"); + + local_ref dynamicPlatformColorRNM = + ReadableNativeMap::newObjectCxxArgs(dynamicPlatformColor); + local_ref dynamicPlatformColorRM = + make_local(reinterpret_cast( + dynamicPlatformColorRNM.get())); + + auto color = getColorFromJava( + fabricUIManager, context.surfaceId, dynamicPlatformColorRM.get()); + + dynamicPlatformColorRM.reset(); + dynamicPlatformColorRNM.reset(); + + auto argb = (int64_t)color; + auto ratio = 255.f; + colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio; + colorComponents.red = ((argb >> 16) & 0xFF) / ratio; + colorComponents.green = ((argb >> 8) & 0xFF) / ratio; + colorComponents.blue = (argb & 0xFF) / ratio; + } + + return colorComponents; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h new file mode 100644 index 00000000000..c48403ba22a --- /dev/null +++ b/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +inline ColorComponents parsePlatformColor( + const PropsParserContext &context, + const RawValue &value) { + float alpha = 0; + float red = 0; + float green = 0; + float blue = 0; + + return {red, green, blue, alpha}; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h b/ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h new file mode 100644 index 00000000000..ad512693369 --- /dev/null +++ b/ReactCommon/react/renderer/graphics/platform/ios/PlatformColorParser.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +inline ColorComponents parsePlatformColor( + const PropsParserContext &context, + const RawValue &value) { + // TODO T87791134: implement parsing of PlatformColor for iOS + float alpha = 0; + float red = 0; + float green = 0; + float blue = 0; + + return {red, green, blue, alpha}; +} + +} // namespace react +} // namespace facebook diff --git a/packages/react-native-codegen/DEFS.bzl b/packages/react-native-codegen/DEFS.bzl index ef16354ad7f..7a445b4b9a6 100644 --- a/packages/react-native-codegen/DEFS.bzl +++ b/packages/react-native-codegen/DEFS.bzl @@ -457,10 +457,11 @@ def rn_codegen_components( # Tests fb_xplat_cxx_test( name = "generated_tests-{}".format(name), - srcs = [ + srcs = [] if ANDROID else [ ":{}".format(generate_tests_cpp_name), ], apple_sdks = (IOS, MACOSX), + fbandroid_use_instrumentation_test = True, compiler_flags = [ "-fexceptions", "-frtti", @@ -471,6 +472,8 @@ def rn_codegen_components( labels = library_labels + ["codegen_rule"], platforms = (ANDROID, APPLE, CXX), deps = [ + YOGA_CXX_TARGET, + react_native_xplat_target("react/renderer/core:core"), "//xplat/third-party/gmock:gtest", ":generated_components-{}".format(name), ],