chore: update

This commit is contained in:
2026-02-18 21:52:32 +01:00
parent aed786cf2c
commit 1f2e4e96dd
399 changed files with 4173 additions and 10273 deletions
+29 -13
View File
@@ -15,9 +15,8 @@ string(
APPEND
CMAKE_CXX_FLAGS
" -DREACT_NATIVE_MINOR_VERSION=${REACT_NATIVE_MINOR_VERSION}\
-DWORKLETS_VERSION=${WORKLETS_VERSION}\
-DWORKLETS_FEATURE_FLAGS=\"${WORKLETS_FEATURE_FLAGS}\"\
-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}")
-DWORKLETS_VERSION=${WORKLETS_VERSION}\
-DWORKLETS_FEATURE_FLAGS=\"${WORKLETS_FEATURE_FLAGS}\"")
string(APPEND CMAKE_CXX_FLAGS " -fno-omit-frame-pointer -fstack-protector-all")
@@ -85,24 +84,41 @@ target_include_directories(
"${REACT_NATIVE_DIR}/ReactCommon/react/renderer/graphics/platform/cxx"
)
if(ReactAndroid_VERSION_MINOR LESS 76)
target_link_libraries(
worklets ReactAndroid::fabricjni ReactAndroid::react_debug
ReactAndroid::react_render_core
ReactAndroid::react_render_componentregistry ReactAndroid::rrc_view)
endif()
# build shared lib
set_target_properties(worklets PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(worklets log ReactAndroid::reactnative ReactAndroid::jsi
fbjni::fbjni)
target_link_libraries(worklets log ReactAndroid::jsi fbjni::fbjni)
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
target_link_libraries(worklets ReactAndroid::reactnative)
else()
target_link_libraries(
worklets ReactAndroid::react_nativemodule_core ReactAndroid::folly_runtime
ReactAndroid::glog ReactAndroid::reactnativejni)
endif()
if(${JS_RUNTIME} STREQUAL "hermes")
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 82)
target_link_libraries(worklets hermes-engine::hermesvm)
else()
target_link_libraries(worklets hermes-engine::libhermes)
endif()
target_link_libraries(worklets hermes-engine::libhermes)
if(${HERMES_ENABLE_DEBUGGER})
string(APPEND CMAKE_CXX_FLAGS " -DHERMES_ENABLE_DEBUGGER=1")
target_link_libraries(worklets ReactAndroid::hermestooling)
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
target_link_libraries(worklets ReactAndroid::hermestooling)
else()
target_link_libraries(worklets ReactAndroid::hermes_executor)
endif()
endif()
elseif(${JS_RUNTIME} STREQUAL "jsc")
target_link_libraries(worklets ReactAndroid::jsctooling)
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
target_link_libraries(worklets ReactAndroid::jsctooling)
else()
target_link_libraries(worklets ReactAndroid::jscexecutor)
endif()
endif()
+11 -6
View File
@@ -102,7 +102,6 @@ def IS_NEW_ARCHITECTURE_ENABLED = isNewArchitectureEnabled()
def IS_REANIMATED_EXAMPLE_APP = safeAppExtGet("isReanimatedExampleApp", false)
def BUNDLE_MODE = safeAppExtGet("workletsBundleMode", false)
def WORKLETS_FEATURE_FLAGS = getStaticFeatureFlags()
def HERMES_V1_ENABLED = safeAppExtGet("hermesV1Enabled", false)
// Set version for prefab
version WORKLETS_VERSION
@@ -150,8 +149,6 @@ apply plugin: "com.android.library"
apply plugin: "maven-publish"
apply plugin: "de.undercouch.download"
apply from: "./fix-prefab.gradle"
android {
compileSdkVersion safeExtGet("compileSdkVersion", 34)
@@ -199,8 +196,7 @@ android {
"-DWORKLETS_BUNDLE_MODE=${BUNDLE_MODE}",
"-DWORKLETS_VERSION=${WORKLETS_VERSION}",
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON",
"-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}",
"-DHERMES_V1_ENABLED=${HERMES_V1_ENABLED}"
"-DWORKLETS_FEATURE_FLAGS=${WORKLETS_FEATURE_FLAGS}"
abiFilters (*reactNativeArchitectures())
targets("worklets")
}
@@ -248,10 +244,19 @@ android {
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libfolly_json.so",
"**/libfolly_runtime.so",
"**/libglog.so",
"**/libhermes.so",
"**/libhermesvm.so",
"**/libhermes-executor-debug.so",
"**/libhermes_executor.so",
"**/libhermestooling.so",
"**/libreactnativejni.so",
"**/libturbomodulejsijni.so",
"**/libreactnative.so",
"**/libreact_nativemodule_core.so",
"**/libreact_render*.so",
"**/librrc_root.so",
"**/libjscexecutor.so",
]
}
@@ -1,53 +0,0 @@
tasks.configureEach { task ->
// Make sure that we generate our prefab publication file only after having built the native library
// so that not a header publication file, but a full configuration publication will be generated, which
// will include the .so file
def prefabConfigurePattern = ~/^prefab(.+)ConfigurePackage$/
def matcher = task.name =~ prefabConfigurePattern
if (matcher.matches()) {
def variantName = matcher[0][1]
task.outputs.upToDateWhen { false }
task.dependsOn("externalNativeBuild${variantName}")
}
}
afterEvaluate {
def abis = reactNativeArchitectures()
rootProject.allprojects.each { proj ->
if (proj === rootProject) return
def dependsOnThisLib = proj.configurations.any { config ->
config.dependencies.any { dep ->
dep.group == project.group && dep.name == project.name
}
}
if (!dependsOnThisLib && proj != project) return
if (!proj.plugins.hasPlugin('com.android.application') && !proj.plugins.hasPlugin('com.android.library')) {
return
}
def variants = proj.android.hasProperty('applicationVariants') ? proj.android.applicationVariants : proj.android.libraryVariants
// Touch the prefab_config.json files to ensure that in ExternalNativeJsonGenerator.kt we will re-trigger the prefab CLI to
// generate a libnameConfig.cmake file that will contain our native library (.so).
// See this condition: https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ExternalNativeJsonGenerator.kt;l=207-219?q=createPrefabBuildSystemGlue
variants.all { variant ->
def variantName = variant.name
abis.each { abi ->
def searchDir = new File(proj.projectDir, ".cxx/${variantName}")
if (!searchDir.exists()) return
def matches = []
searchDir.eachDir { randomDir ->
def prefabFile = new File(randomDir, "${abi}/prefab_config.json")
if (prefabFile.exists()) matches << prefabFile
}
matches.each { prefabConfig ->
prefabConfig.setLastModified(System.currentTimeMillis())
}
}
}
}
}
@@ -3,12 +3,13 @@ package com.swmansion.worklets;
import androidx.annotation.OptIn;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.BundleConsumer;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.common.annotations.FrameworkAPI;
import com.facebook.react.fabric.BundleWrapper;
import com.facebook.react.fabric.BigStringBufferWrapper;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
import com.facebook.soloader.SoLoader;
@@ -19,7 +20,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
@SuppressWarnings("JavaJniMissingFunction")
@ReactModule(name = WorkletsModule.NAME)
public class WorkletsModule extends NativeWorkletsModuleSpec implements LifecycleEventListener {
public class WorkletsModule extends NativeWorkletsModuleSpec
implements LifecycleEventListener, BundleConsumer {
static {
SoLoader.loadLibrary("worklets");
}
@@ -37,9 +39,19 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
private final AndroidUIScheduler mAndroidUIScheduler;
private final AnimationFrameQueue mAnimationFrameQueue;
private boolean mSlowAnimationsEnabled;
private BundleWrapper mBundleWrapper = null;
private BigStringBufferWrapper mScriptWrapper = null;
private String mSourceURL = null;
@Override
public void setScriptWrapper(BigStringBufferWrapper scriptWrapper) {
mScriptWrapper = scriptWrapper;
}
@Override
public void setSourceURL(String sourceURL) {
mSourceURL = sourceURL;
}
/**
* Invalidating concurrently could be fatal. It shouldn't happen in a normal flow, but it doesn't
* cost us much to add synchronization for extra safety.
@@ -52,7 +64,7 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
MessageQueueThread messageQueueThread,
CallInvokerHolderImpl jsCallInvokerHolder,
AndroidUIScheduler androidUIScheduler,
BundleWrapper bundleWrapper,
BigStringBufferWrapper scriptWrapper,
String sourceURL);
public WorkletsModule(ReactApplicationContext reactContext) {
@@ -78,16 +90,13 @@ public class WorkletsModule extends NativeWorkletsModuleSpec implements Lifecycl
var jsContext = Objects.requireNonNull(context.getJavaScriptContextHolder()).get();
var jsCallInvokerHolder = JSCallInvokerResolver.getJSCallInvokerHolder(context);
mSourceURL = context.getSourceURL();
mBundleWrapper = context.getBundle();
mHybridData =
initHybrid(
jsContext,
mMessageQueueThread,
jsCallInvokerHolder,
mAndroidUIScheduler,
mBundleWrapper,
mScriptWrapper,
mSourceURL);
return true;
}
@@ -10,7 +10,8 @@ class UISchedulerWrapper : public UIScheduler {
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler_;
public:
explicit UISchedulerWrapper(jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
explicit UISchedulerWrapper(
jni::global_ref<AndroidUIScheduler::javaobject> androidUiScheduler)
: androidUiScheduler_(androidUiScheduler) {}
void scheduleOnUI(std::function<void()> job) override {
@@ -22,10 +23,14 @@ class UISchedulerWrapper : public UIScheduler {
}
};
AndroidUIScheduler::AndroidUIScheduler(jni::alias_ref<AndroidUIScheduler::javaobject> jThis)
: javaPart_(jni::make_global(jThis)), uiScheduler_(std::make_shared<UISchedulerWrapper>(jni::make_global(jThis))) {}
AndroidUIScheduler::AndroidUIScheduler(
jni::alias_ref<AndroidUIScheduler::javaobject> jThis)
: javaPart_(jni::make_global(jThis)),
uiScheduler_(
std::make_shared<UISchedulerWrapper>(jni::make_global(jThis))) {}
jni::local_ref<AndroidUIScheduler::jhybriddata> AndroidUIScheduler::initHybrid(jni::alias_ref<jhybridobject> jThis) {
jni::local_ref<AndroidUIScheduler::jhybriddata> AndroidUIScheduler::initHybrid(
jni::alias_ref<jhybridobject> jThis) {
return makeCxxInstance(jThis);
}
@@ -37,7 +42,8 @@ void AndroidUIScheduler::triggerUI() {
}
void AndroidUIScheduler::scheduleTriggerOnUI() {
static const auto method = javaPart_->getClass()->getMethod<void()>("scheduleTriggerOnUI");
static const auto method =
javaPart_->getClass()->getMethod<void()>("scheduleTriggerOnUI");
method(javaPart_.get());
}
@@ -14,8 +14,10 @@ using namespace worklets;
class AndroidUIScheduler : public jni::HybridClass<AndroidUIScheduler> {
public:
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/AndroidUIScheduler;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis);
static auto constexpr kJavaDescriptor =
"Lcom/swmansion/worklets/AndroidUIScheduler;";
static jni::local_ref<jhybriddata> initHybrid(
jni::alias_ref<jhybridobject> jThis);
static void registerNatives();
std::shared_ptr<UIScheduler> getUIScheduler() {
@@ -34,7 +36,8 @@ class AndroidUIScheduler : public jni::HybridClass<AndroidUIScheduler> {
jni::global_ref<AndroidUIScheduler::javaobject> javaPart_;
std::shared_ptr<UIScheduler> uiScheduler_;
explicit AndroidUIScheduler(jni::alias_ref<AndroidUIScheduler::jhybridobject> jThis);
explicit AndroidUIScheduler(
jni::alias_ref<AndroidUIScheduler::jhybridobject> jThis);
};
} // namespace worklets
@@ -6,9 +6,11 @@
namespace worklets {
class AnimationFrameCallback : public facebook::jni::HybridClass<AnimationFrameCallback> {
class AnimationFrameCallback
: public facebook::jni::HybridClass<AnimationFrameCallback> {
public:
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/runloop/AnimationFrameCallback;";
static auto constexpr kJavaDescriptor =
"Lcom/swmansion/worklets/runloop/AnimationFrameCallback;";
void onAnimationFrame(double timestampMs) {
callback_(timestampMs);
@@ -16,14 +18,16 @@ class AnimationFrameCallback : public facebook::jni::HybridClass<AnimationFrameC
static void registerNatives() {
javaClassStatic()->registerNatives({
makeNativeMethod("onAnimationFrame", AnimationFrameCallback::onAnimationFrame),
makeNativeMethod(
"onAnimationFrame", AnimationFrameCallback::onAnimationFrame),
});
}
private:
friend HybridBase;
explicit AnimationFrameCallback(std::function<void(const double)> callback) : callback_(std::move(callback)) {}
explicit AnimationFrameCallback(std::function<void(const double)> callback)
: callback_(std::move(callback)) {}
std::function<void(double)> callback_;
};
@@ -2,8 +2,6 @@
#include <worklets/Tools/PlatformLogger.h>
#include <string>
constexpr const auto tag = "Worklets";
namespace worklets {
@@ -5,7 +5,6 @@
#include <worklets/android/WorkletsModule.h>
#include <memory>
#include <string>
#include <utility>
namespace worklets {
@@ -19,7 +18,7 @@ WorkletsModule::WorkletsModule(
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
const std::shared_ptr<UIScheduler> &uiScheduler,
const std::shared_ptr<const JSBigStringBuffer> &script,
const std::shared_ptr<const BigStringBuffer> &script,
const std::string &sourceURL)
: javaPart_(jni::make_global(jThis)),
rnRuntime_(rnRuntime),
@@ -29,25 +28,32 @@ WorkletsModule::WorkletsModule(
jsCallInvoker,
uiScheduler,
getIsOnJSQueueThread(),
RuntimeBindings{.requestAnimationFrame = getRequestAnimationFrame()},
getForwardedRequestAnimationFrame(),
script,
sourceURL)) {
auto jsiWorkletsModuleProxy = workletsModuleProxy_->createJSIWorkletsModuleProxy();
auto jsiWorkletsModuleProxy =
workletsModuleProxy_->createJSIWorkletsModuleProxy();
auto optimizedJsiWorkletsModuleProxy = jsi_utils::optimizedFromHostObject(
*rnRuntime_, std::static_pointer_cast<jsi::HostObject>(std::move(jsiWorkletsModuleProxy)));
*rnRuntime_,
std::static_pointer_cast<jsi::HostObject>(
std::move(jsiWorkletsModuleProxy)));
RNRuntimeWorkletDecorator::decorate(
*rnRuntime_, std::move(optimizedJsiWorkletsModuleProxy), workletsModuleProxy_->getJSLogger());
*rnRuntime_,
std::move(optimizedJsiWorkletsModuleProxy),
workletsModuleProxy_->getJSLogger());
}
jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
jni::alias_ref<jhybridobject> jThis,
jlong jsContext,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
jsCallInvokerHolder,
jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
#ifdef WORKLETS_BUNDLE_MODE
,
jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
jni::alias_ref<facebook::react::BigStringBufferWrapper::javaobject>
scriptWrapper,
const std::string &sourceURL
#endif // WORKLETS_BUNDLE_MODE
) {
@@ -55,27 +61,42 @@ jni::local_ref<WorkletsModule::jhybriddata> WorkletsModule::initHybrid(
auto rnRuntime = reinterpret_cast<jsi::Runtime *>(jsContext);
auto uiScheduler = androidUIScheduler->cthis()->getUIScheduler();
std::shared_ptr<const JSBigStringBuffer> script = nullptr;
std::shared_ptr<const BigStringBuffer> script = nullptr;
#ifdef WORKLETS_BUNDLE_MODE
script = bundleWrapper->cthis()->getBundle();
script = scriptWrapper->cthis()->getScript();
#else
const auto sourceURL = std::string{};
#endif // WORKLETS_BUNDLE_MODE
return makeCxxInstance(jThis, rnRuntime, messageQueueThread, jsCallInvoker, uiScheduler, script, sourceURL);
return makeCxxInstance(
jThis,
rnRuntime,
messageQueueThread,
jsCallInvoker,
uiScheduler,
script,
sourceURL);
}
RuntimeBindings::RequestAnimationFrame WorkletsModule::getRequestAnimationFrame() {
return [javaPart = javaPart_](std::function<void(const double)> &&callback) -> void {
std::function<void(std::function<void(const double)>)>
WorkletsModule::getForwardedRequestAnimationFrame() {
return [javaPart =
javaPart_](std::function<void(const double)> &&callback) -> void {
static const auto jRequestAnimationFrame =
javaPart->getClass()->getMethod<void(AnimationFrameCallback::javaobject)>("requestAnimationFrame");
jRequestAnimationFrame(javaPart.get(), AnimationFrameCallback::newObjectCxxArgs(std::move(callback)).get());
javaPart->getClass()
->getMethod<void(AnimationFrameCallback::javaobject)>(
"requestAnimationFrame");
jRequestAnimationFrame(
javaPart.get(),
AnimationFrameCallback::newObjectCxxArgs(std::move(callback)).get());
};
}
std::function<bool()> WorkletsModule::getIsOnJSQueueThread() {
return [javaPart = javaPart_]() -> bool {
return javaPart->getClass()->getMethod<jboolean()>("isOnJSQueueThread").operator()(javaPart);
return javaPart->getClass()
->getMethod<jboolean()>("isOnJSQueueThread")
.operator()(javaPart);
};
}
@@ -3,14 +3,13 @@
#include <ReactCommon/CallInvokerHolder.h>
#include <fbjni/fbjni.h>
#include <jsi/jsi.h>
#include <jsireact/JSIExecutor.h>
#include <react/jni/JMessageQueueThread.h>
#include <worklets/Tools/Defs.h>
#ifdef WORKLETS_BUNDLE_MODE
#include <react/fabric/BundleWrapper.h>
#include <react/fabric/BigStringBufferWrapper.h>
#endif // WORKLETS_BUNDLE_MODE
#include <worklets/NativeModules/WorkletsModuleProxy.h>
#include <worklets/WorkletRuntime/RuntimeBindings.h>
#include <worklets/android/AndroidUIScheduler.h>
#include <memory>
@@ -23,17 +22,21 @@ using namespace facebook::jni;
class WorkletsModule : public jni::HybridClass<WorkletsModule> {
public:
static auto constexpr kJavaDescriptor = "Lcom/swmansion/worklets/WorkletsModule;";
static auto constexpr kJavaDescriptor =
"Lcom/swmansion/worklets/WorkletsModule;";
static jni::local_ref<jhybriddata> initHybrid(
jni::alias_ref<jhybridobject> jThis,
jlong jsContext,
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject> jsCallInvokerHolder,
jni::alias_ref<worklets::AndroidUIScheduler::javaobject> androidUIScheduler
jni::alias_ref<facebook::react::CallInvokerHolder::javaobject>
jsCallInvokerHolder,
jni::alias_ref<worklets::AndroidUIScheduler::javaobject>
androidUIScheduler
#ifdef WORKLETS_BUNDLE_MODE
,
jni::alias_ref<facebook::react::BundleWrapper::javaobject> bundleWrapper,
jni::alias_ref<facebook::react::BigStringBufferWrapper::javaobject>
scriptWrapper,
const std::string &sourceURL
#endif // WORKLETS_BUNDLE_MODE
);
@@ -51,7 +54,7 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
jni::alias_ref<JavaMessageQueueThread::javaobject> messageQueueThread,
const std::shared_ptr<facebook::react::CallInvoker> &jsCallInvoker,
const std::shared_ptr<UIScheduler> &uiScheduler,
const std::shared_ptr<const JSBigStringBuffer> &bundle,
const std::shared_ptr<const BigStringBuffer> &script,
const std::string &sourceURL);
void invalidateCpp();
@@ -61,7 +64,8 @@ class WorkletsModule : public jni::HybridClass<WorkletsModule> {
return javaPart_->getClass()->getMethod<Signature>(methodName.c_str());
}
RuntimeBindings::RequestAnimationFrame getRequestAnimationFrame();
std::function<void(std::function<void(const double)>)>
getForwardedRequestAnimationFrame();
std::function<bool()> getIsOnJSQueueThread();