Skip to content

Commit 763ccab

Browse files
committed
Working android impl
1 parent 74fd3b4 commit 763ccab

File tree

8 files changed

+201
-12
lines changed

8 files changed

+201
-12
lines changed

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,3 @@ lib/
8282
ios/generated
8383
android/generated
8484

85-
# React Native Nitro Modules
86-
nitrogen/

android/CMakeLists.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
project(OPServer)
2+
cmake_minimum_required(VERSION 3.9.0)
3+
4+
set (PACKAGE_NAME "op-server")
5+
6+
file(GLOB_RECURSE shared_files RELATIVE ${CMAKE_SOURCE_DIR}
7+
"../cpp/**.cpp"
8+
)
9+
file(GLOB_RECURSE android_files RELATIVE ${CMAKE_SOURCE_DIR}
10+
"src/main/cpp/**.cpp"
11+
)
12+
13+
add_library(
14+
${PACKAGE_NAME}
15+
SHARED
16+
${shared_files}
17+
${android_files}
18+
)
19+
20+
include_directories(
21+
../cpp
22+
# Android-specific C++ includes
23+
src/main/cpp/core
24+
src/main/cpp/registry
25+
src/main/cpp/turbomodule
26+
src/main/cpp/platform
27+
src/main/cpp/utils
28+
src/main/cpp/views
29+
)
30+
31+
find_package(ReactAndroid REQUIRED CONFIG)
32+
find_package(fbjni REQUIRED CONFIG)
33+
find_library(LOG_LIB log)
34+
35+
target_link_libraries(
36+
${PACKAGE_NAME}
37+
${LOG_LIB}
38+
ReactAndroid::reactnative
39+
ReactAndroid::jsi
40+
fbjni::fbjni
41+
)

android/build.gradle

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,55 @@ android {
3333
defaultConfig {
3434
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
3535
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
36+
37+
externalNativeBuild {
38+
cmake {
39+
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
40+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
41+
42+
buildTypes {
43+
debug {
44+
cppFlags "-O1 -g"
45+
}
46+
release {
47+
cppFlags "-O2"
48+
}
49+
}
50+
}
51+
}
52+
}
53+
54+
externalNativeBuild {
55+
cmake {
56+
path "CMakeLists.txt"
57+
}
3658
}
3759

3860
buildFeatures {
3961
buildConfig true
62+
prefab true
63+
prefabPublishing true
64+
}
65+
66+
packagingOptions {
67+
excludes = [
68+
"META-INF",
69+
"META-INF/**",
70+
"**/libc++_shared.so",
71+
"**/libfbjni.so",
72+
"**/libjsi.so",
73+
"**/libfolly_json.so",
74+
"**/libfolly_runtime.so",
75+
"**/libglog.so",
76+
"**/libhermes.so",
77+
"**/libhermes-executor-debug.so",
78+
"**/libhermes_executor.so",
79+
"**/libreactnative.so",
80+
"**/libreactnativejni.so",
81+
"**/libturbomodulejsijni.so",
82+
"**/libreact_nativemodule_core.so",
83+
"**/libjscexecutor.so"
84+
]
4085
}
4186

4287
buildTypes {

android/src/main/cpp/JNIOnLoad.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "OPServer.hpp"
2+
#include <fbjni/fbjni.h>
3+
#include <jni.h>
4+
5+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
6+
return facebook::jni::initialize(
7+
vm, [] { opserver::JOPServer::registerNatives(); });
8+
}

android/src/main/cpp/OPServer.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "OPServer.hpp"
2+
#include "../cpp/bindings.hpp"
3+
4+
#include <exception>
5+
6+
namespace opserver {
7+
8+
using namespace facebook;
9+
10+
void JOPServer::install(
11+
jni::alias_ref<jni::JClass>, jlong runtimePointer,
12+
jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder) {
13+
auto runtime = reinterpret_cast<jsi::Runtime *>(runtimePointer);
14+
if (runtime == nullptr) {
15+
throw std::invalid_argument("jsi::Runtime was null!");
16+
}
17+
18+
if (callInvokerHolder == nullptr) {
19+
throw std::invalid_argument("CallInvokerHolder was null!");
20+
}
21+
auto callInvoker = callInvokerHolder->cthis()->getCallInvoker();
22+
if (callInvoker == nullptr) {
23+
throw std::invalid_argument("CallInvoker was null!");
24+
}
25+
26+
opserver::install(*runtime, callInvoker);
27+
}
28+
29+
void JOPServer::registerNatives() {
30+
javaClassStatic()->registerNatives({
31+
makeNativeMethod("install", JOPServer::install),
32+
});
33+
}
34+
35+
} // namespace opserver

android/src/main/cpp/OPServer.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include <ReactCommon/CallInvoker.h>
4+
#include <ReactCommon/CallInvokerHolder.h>
5+
#include <fbjni/fbjni.h>
6+
#include <jsi/jsi.h>
7+
8+
namespace opserver {
9+
10+
using namespace facebook;
11+
12+
class JOPServer final : public jni::HybridClass<JOPServer> {
13+
public:
14+
static auto constexpr kJavaDescriptor =
15+
"Lcom/opengineering/opserver/OpServerModule;";
16+
static constexpr auto TAG = "OpServerModule";
17+
18+
static void registerNatives();
19+
20+
static void install(
21+
jni::alias_ref<jni::JClass>, jlong runtimePointer,
22+
jni::alias_ref<react::CallInvokerHolder::javaobject> callInvokerHolder);
23+
24+
private:
25+
explicit JOPServer() = default;
26+
};
27+
28+
} // namespace opserver
Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,57 @@
11
package com.opengineering.opserver
22

3+
import androidx.annotation.Keep
4+
import com.facebook.proguard.annotations.DoNotStrip
35
import com.facebook.react.bridge.ReactApplicationContext
4-
import com.facebook.react.module.annotations.ReactModule
6+
import com.facebook.react.bridge.ReactMethod
7+
import com.facebook.react.common.annotations.FrameworkAPI
8+
import com.facebook.react.turbomodule.core.CallInvokerHolderImpl
9+
import android.util.Log;
510

6-
@ReactModule(name = OpServerModule.NAME)
7-
class OpServerModule(reactContext: ReactApplicationContext) :
8-
NativeOpServerSpec(reactContext) {
11+
@DoNotStrip
12+
@Keep
13+
@OptIn(FrameworkAPI::class)
14+
@Suppress("KotlinJniMissingFunction")
15+
class OpServerModule(val context: ReactApplicationContext) :
16+
NativeOpServerSpec(context) {
917

1018
override fun getName(): String {
1119
return NAME
1220
}
1321

14-
// Example method
15-
// See https://reactnative.dev/docs/native-modules-android
16-
override fun multiply(a: Double, b: Double): Double {
17-
return a * b
22+
@ReactMethod(isBlockingSynchronousMethod = true)
23+
override fun install(): Boolean {
24+
try {
25+
val jsContext =
26+
context.javaScriptContextHolder
27+
?: return false
28+
29+
val callInvokerHolder =
30+
context.jsCallInvokerHolder as? CallInvokerHolderImpl
31+
?: return false
32+
33+
install(jsContext.get(), callInvokerHolder)
34+
35+
return true
36+
} catch (e: Throwable) {
37+
return false
38+
}
1839
}
1940

41+
private external fun install(
42+
jsRuntimePointer: Long,
43+
callInvokerHolder: CallInvokerHolderImpl,
44+
)
45+
2046
companion object {
2147
const val NAME = "OpServer"
48+
49+
@JvmStatic
50+
var applicationContext: ReactApplicationContext? = null
51+
52+
init {
53+
System.loadLibrary("op-server");
54+
Log.i("OPServer", "Successfully loaded C++ library!");
55+
}
2256
}
2357
}

src/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ if (global.__OPServerProxy == null) {
3636
const installed = OpServer.install();
3737
if (!installed) {
3838
throw new Error(
39-
`Failed to install op-sqlite: The native OPSQLite Module could not be installed! Looks like something went wrong when installing JSI bindings, check the native logs for more info`
39+
`Failed to install op-server: The Native Module could not be installed! Looks like something went wrong when installing JSI bindings, check the native logs for more info`
4040
);
4141
}
4242

4343
// Check again if the constructor now exists. If not, throw an error.
4444
if (global.__OPServerProxy == null) {
4545
throw new Error(
46-
'OPSqlite native object is not available. Something is wrong. Check the native logs for more information.'
46+
'OP Server native object is not available. Something is wrong. Check the native logs for more information.'
4747
);
4848
}
4949
}

0 commit comments

Comments
 (0)