Skip to content

Commit 21045f6

Browse files
feat: android module with new architecture
1 parent 942849d commit 21045f6

18 files changed

+302
-154
lines changed

android/CMakeLists.txt

+43-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,52 @@ cmake_minimum_required(VERSION 3.4.1)
22
project(FastOpencv)
33

44
set (CMAKE_VERBOSE_MAKEFILE ON)
5-
set (CMAKE_CXX_STANDARD 14)
5+
set (CMAKE_CXX_STANDARD 20)
6+
7+
find_package(ReactAndroid REQUIRED CONFIG)
8+
find_package(fbjni REQUIRED CONFIG)
9+
find_package(OpenCV REQUIRED COMPONENTS OpenCV::opencv_java4)
10+
11+
add_library(react-native-fast-opencv
12+
SHARED
13+
../node_modules/react-native/ReactCommon/jsi/jsi/jsi.cpp
14+
../cpp/react-native-fast-opencv.cpp
15+
../cpp/react-native-fast-opencv.h
16+
cpp-adapter.cpp
17+
../cpp/ConvertImage.cpp
18+
../cpp/FOCV_Function.cpp
19+
../cpp/FOCV_FunctionArguments.cpp
20+
../cpp/FOCV_Ids.cpp
21+
../cpp/FOCV_JsiObject.cpp
22+
../cpp/FOCV_Object.cpp
23+
../cpp/FOCV_Storage.cpp
24+
../cpp/FOCV_Storage.hpp
25+
../cpp/UUID.cpp
26+
../cpp/jsi/TypedArray.cpp
27+
../cpp/jsi/Promise.cpp
628

7-
add_library(react-native-fast-opencv SHARED
8-
../cpp/react-native-fast-opencv.cpp
9-
cpp-adapter.cpp
1029
)
1130

1231
# Specifies a path to native header files.
1332
include_directories(
14-
../cpp
33+
../cpp
34+
../cpp/jsi
35+
"${NODE_MODULES_DIR}/react-native/React"
36+
"${NODE_MODULES_DIR}/react-native/React/Base"
37+
"${NODE_MODULES_DIR}/react-native/ReactCommon"
38+
"${NODE_MODULES_DIR}/react-native/ReactCommon/jsi"
39+
"${NODE_MODULES_DIR}/react-native/ReactCommon/callinvoker"
40+
"${NODE_MODULES_DIR}/react-native/ReactAndroid/src/main/jni/react/turbomodule"
41+
)
42+
43+
target_link_libraries(
44+
react-native-fast-opencv
45+
log
46+
android
47+
ReactAndroid::folly_runtime
48+
ReactAndroid::glog
49+
ReactAndroid::jsi
50+
ReactAndroid::reactnativejni
51+
fbjni::fbjni
52+
OpenCV::opencv_java4
1553
)

android/build.gradle

+40
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import java.nio.file.Paths
2+
13
buildscript {
24
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
35
def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["FastOpencv_kotlinVersion"]
@@ -47,6 +49,23 @@ def supportsNamespace() {
4749
return (major == 7 && minor >= 3) || major >= 8
4850
}
4951

52+
static def findNodeModules(baseDir) {
53+
def basePath = baseDir.toPath().normalize()
54+
// Node's module resolution algorithm searches up to the root directory,
55+
// after which the base path will be null
56+
while (basePath) {
57+
def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
58+
def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
59+
if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
60+
return nodeModulesPath.toString()
61+
}
62+
basePath = basePath.getParent()
63+
}
64+
throw new GradleException("react-native-fast-tflite: Failed to find node_modules/ path!")
65+
}
66+
67+
def nodeModules = findNodeModules(projectDir)
68+
5069
android {
5170
if (supportsNamespace()) {
5271
namespace "com.fastopencv"
@@ -66,13 +85,33 @@ android {
6685
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
6786
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
6887

88+
buildFeatures {
89+
prefab=true
90+
}
91+
6992
externalNativeBuild {
7093
cmake {
94+
arguments "-DANDROID_STL=c++_shared",
95+
"-DNODE_MODULES_DIR=${nodeModules}"
7196
cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all"
7297
abiFilters (*reactNativeArchitectures())
7398
}
7499
}
75100
}
101+
packagingOptions {
102+
excludes = [
103+
"META-INF",
104+
"META-INF/**",
105+
"**/libc++_shared.so",
106+
"**/libfbjni.so",
107+
"**/libjsi.so",
108+
"**/libreactnativejni.so",
109+
"**/libturbomodulejsijni.so",
110+
"**/libreact_nativemodule_core.so",
111+
"**/libfolly_runtime.so",
112+
"**/libglog.so"
113+
]
114+
}
76115

77116
externalNativeBuild {
78117
cmake {
@@ -127,6 +166,7 @@ dependencies {
127166
//noinspection GradleDynamicVersion
128167
implementation "com.facebook.react:react-native:+"
129168
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
169+
implementation 'org.opencv:opencv:4.9.0'
130170
}
131171

132172
if (isNewArchitectureEnabled()) {

android/cpp-adapter.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
#include <jni.h>
2+
#include <jsi/jsi.h>
3+
24
#include "react-native-fast-opencv.h"
5+
#include <ReactCommon/CallInvokerHolder.h>
6+
7+
using namespace facebook;
38

49
extern "C"
5-
JNIEXPORT jdouble JNICALL
6-
Java_com_fastopencv_FastOpencvModule_nativeMultiply(JNIEnv *env, jclass type, jdouble a, jdouble b) {
7-
return fastopencv::multiply(a, b);
10+
JNIEXPORT void JNICALL
11+
Java_com_fastopencv_FastOpencvModule_nativeInstall(JNIEnv *env, jobject thiz, jlong jsi_runtime_ref,
12+
jobject js_call_invoker_holder) {
13+
auto jsiRuntime{ reinterpret_cast<jsi::Runtime*>(jsi_runtime_ref) };
14+
auto jsCallInvoker{ jni::alias_ref<react::CallInvokerHolder::javaobject>{reinterpret_cast<react::CallInvokerHolder::javaobject>(js_call_invoker_holder) }->cthis()->getCallInvoker() };
15+
16+
// RNWorklet::JsiWorkletContext::getDefaultInstance()->initialize(
17+
// "default", jsiRuntime, [=](std::function<void()> &&f) {
18+
// jsCallInvoker->invokeAsync(std::move(f));
19+
// });
20+
21+
OpenCVPlugin::installOpenCV(*jsiRuntime, jsCallInvoker);
822
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.fastopencv
22

3+
import android.util.Log
34
import com.facebook.react.bridge.ReactApplicationContext
45
import com.facebook.react.bridge.ReactMethod
5-
import com.facebook.react.bridge.Promise
6+
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
7+
68

79
class FastOpencvModule internal constructor(context: ReactApplicationContext) :
810
FastOpencvSpec(context) {
@@ -11,14 +13,36 @@ class FastOpencvModule internal constructor(context: ReactApplicationContext) :
1113
return NAME
1214
}
1315

14-
// Example method
15-
// See https://reactnative.dev/docs/native-modules-android
16-
@ReactMethod
17-
override fun multiply(a: Double, b: Double, promise: Promise) {
18-
promise.resolve(a * b)
19-
}
20-
2116
companion object {
2217
const val NAME = "FastOpencv"
18+
19+
init {
20+
System.loadLibrary("react-native-fast-opencv")
21+
}
22+
}
23+
24+
private external fun nativeInstall(jsiRuntimeRef: Long, jsCallInvokerHolder: CallInvokerHolder?)
25+
26+
@ReactMethod(isBlockingSynchronousMethod = true)
27+
override fun install(): Boolean {
28+
val jsContext = reactApplicationContext.javaScriptContextHolder
29+
30+
try {
31+
if (jsContext == null) {
32+
Log.e(NAME, "React Application Context was null!")
33+
return false
34+
}
35+
val jsiRuntimeRef = jsContext!!.get()
36+
val jsCallInvokerHolder = reactApplicationContext.catalystInstance.jsCallInvokerHolder
37+
38+
nativeInstall(jsiRuntimeRef, jsCallInvokerHolder)
39+
40+
return true
41+
} catch (exception: Exception) {
42+
Log.e(NAME, "Failed to initialize react-native-worklets-core!", exception)
43+
44+
}
45+
46+
return false
2347
}
2448
}

android/src/oldarch/FastOpencvSpec.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ import com.facebook.react.bridge.Promise
77
abstract class FastOpencvSpec internal constructor(context: ReactApplicationContext) :
88
ReactContextBaseJavaModule(context) {
99

10-
abstract fun multiply(a: Double, b: Double, promise: Promise)
10+
abstract fun install(): Boolean
1111
}

0 commit comments

Comments
 (0)