From b92a281b5e62de98192524e6b6bba7b8a6de5a43 Mon Sep 17 00:00:00 2001 From: Nabil Hachicha Date: Thu, 28 Jan 2016 15:11:33 +0000 Subject: [PATCH] add missing refactored files --- .../io/realm/react/example/MainActivity.java | 113 ++++++++++++++++ .../io/realm/react/RealmReactAndroid.java | 126 ++++++++++++++++++ .../io_realm_react_RealmReactAndroid.cpp | 98 ++++++++++++++ .../io_realm_react_RealmReactAndroid.h | 36 +++++ 4 files changed, 373 insertions(+) create mode 100644 examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainActivity.java create mode 100644 react-native/android/app/src/main/java/io/realm/react/RealmReactAndroid.java create mode 100644 src/android/io_realm_react_RealmReactAndroid.cpp create mode 100644 src/android/io_realm_react_RealmReactAndroid.h diff --git a/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainActivity.java b/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainActivity.java new file mode 100644 index 00000000..2f65d0b6 --- /dev/null +++ b/examples/ReactExample/android/app/src/main/java/io/realm/react/example/MainActivity.java @@ -0,0 +1,113 @@ +package io.realm.react.example; + +import android.app.Activity; +import android.os.Bundle; +import android.view.KeyEvent; + +import com.facebook.react.LifecycleState; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactPackage; +import com.facebook.react.ReactRootView; +import com.facebook.react.bridge.JavaScriptModule; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.shell.MainReactPackage; +import com.facebook.react.uimanager.ViewManager; +import com.facebook.soloader.SoLoader; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import io.realm.react.RealmReactAndroid; + +public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler { + + private ReactInstanceManager mReactInstanceManager; + private ReactRootView mReactRootView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mReactRootView = new ReactRootView(this); + + mReactInstanceManager = ReactInstanceManager.builder() + .setApplication(getApplication()) + .setBundleAssetName("index.android.bundle") + .setJSMainModuleName("index.android") + .addPackage(new MainReactPackage()) + .addPackage(new AnExampleReactPackage()) + .setUseDeveloperSupport(BuildConfig.DEBUG) + .setInitialLifecycleState(LifecycleState.RESUMED) + .build(); + + mReactRootView.startReactApplication(mReactInstanceManager, "ReactExample", null); + + setContentView(mReactRootView); + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) { + mReactInstanceManager.showDevOptionsDialog(); + return true; + } + return super.onKeyUp(keyCode, event); + } + + @Override + public void onBackPressed() { + if (mReactInstanceManager != null) { + mReactInstanceManager.onBackPressed(); + } else { + super.onBackPressed(); + } + } + + @Override + public void invokeDefaultOnBackPressed() { + super.onBackPressed(); + } + + @Override + protected void onPause() { + super.onPause(); + + if (mReactInstanceManager != null) { + mReactInstanceManager.onPause(); + } + } + + @Override + protected void onResume() { + super.onResume(); + + if (mReactInstanceManager != null) { + mReactInstanceManager.onResume(this, this); + } + } + + + class AnExampleReactPackage implements ReactPackage { + @Override + public List createNativeModules( + ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + + modules.add(new RealmReactAndroid(reactContext)); + + return modules; + } + + @Override + public List> createJSModules() { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + } +} diff --git a/react-native/android/app/src/main/java/io/realm/react/RealmReactAndroid.java b/react-native/android/app/src/main/java/io/realm/react/RealmReactAndroid.java new file mode 100644 index 00000000..3c3285ba --- /dev/null +++ b/react-native/android/app/src/main/java/io/realm/react/RealmReactAndroid.java @@ -0,0 +1,126 @@ +package io.realm.react; + +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import java.util.Map; +import java.util.HashMap; +import android.widget.Toast; +import com.facebook.react.bridge.Callback; +import android.util.Log; +import java.io.IOException; +import java.util.Map; +import fi.iki.elonen.NanoHTTPD; +import android.os.Handler; +import android.os.Looper; +import java.util.concurrent.CountDownLatch; +import com.facebook.soloader.SoLoader; + +public class RealmReactAndroid extends ReactContextBaseJavaModule { + private static final String DURATION_SHORT_KEY = "SHORT"; + private static final String DURATION_LONG_KEY = "LONG"; + private String filesDirPath; + + private static final int DEFAULT_PORT = 8082; + private AndroidWebServer webServer; + private long rpcServerPtr; + private Handler handler = new Handler(Looper.getMainLooper()); + + public RealmReactAndroid(ReactApplicationContext reactContext) { + super(reactContext); + try { + filesDirPath = getReactApplicationContext().getFilesDir().getCanonicalPath(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + SoLoader.loadLibrary("realmreact"); + } + + @Override + public String getName() { + return "RealmReactAndroid"; + } + + @Override + public Map getConstants() { + long contexts = injectRealmJsContext(filesDirPath); + Log.i("RealmReactAndroid", "Initialized " + contexts + " contexts"); + if (contexts == 0) {// we're running in Chrome debug mode + startWebServer(); + } + return new HashMap<>(); + } + + @Override + public void onCatalystInstanceDestroy() { + if (webServer != null) { + Log.i("RealmReactAndroid", "Stopping the webserver"); + webServer.stop(); + } + } + private void startWebServer() { + rpcServerPtr = setupChromeDebugModeRealmJsContext(); + webServer = new AndroidWebServer(DEFAULT_PORT); + try { + webServer.start(); + Log.i("RealmReactAndroid", "Starting WebServer, Host: " + webServer.getHostname() + " Port: " + webServer.getListeningPort()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + // WebServer + class AndroidWebServer extends NanoHTTPD { + public AndroidWebServer(int port) { + super(port); + } + + public AndroidWebServer(String hostname, int port) { + super(hostname, port); + } + + @Override + public Response serve(IHTTPSession session) { + final String cmdUri = session.getUri(); + Log.v("AndroidWebServer", "Session Uri: " + cmdUri + " Mehtod: " + session.getMethod().name()); + final HashMap map = new HashMap(); + try { + session.parseBody(map); + } catch (IOException e) { + e.printStackTrace(); + } catch (ResponseException e) { + e.printStackTrace(); + } + final String json = map.get("postData"); + Log.v("AndroidWebServer", "Post Data: \n" + json + "\n Thread id: " + Thread.currentThread().getName()); + final String[] jsonResponse = new String[1]; + final CountDownLatch latch = new CountDownLatch(1); + // Process the command on the UI thread + handler.post(new Runnable() { + @Override + public void run() { + jsonResponse[0] = processChromeDebugCommand(rpcServerPtr, cmdUri, json); + latch.countDown(); + } + }); + try { + latch.await(); + Response response = newFixedLengthResponse(jsonResponse[0]); + response.addHeader("Access-Control-Allow-Origin", "http://localhost:8081"); + return response; + } catch (InterruptedException e) { + e.printStackTrace(); + return null; + } + } + } + + // fileDir: path of the internal storage of the application + private native long injectRealmJsContext(String fileDir); + // responsible for creating the rpcServer that will accept thw chrome Websocket command + private native long setupChromeDebugModeRealmJsContext(); + // this receives one command from Chrome debug, & return the processing we should post back + private native String processChromeDebugCommand(long rpcServerPointer, String cmd, String args); +} diff --git a/src/android/io_realm_react_RealmReactAndroid.cpp b/src/android/io_realm_react_RealmReactAndroid.cpp new file mode 100644 index 00000000..62126a56 --- /dev/null +++ b/src/android/io_realm_react_RealmReactAndroid.cpp @@ -0,0 +1,98 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class io_realm_react_RealmReactAndroid */ +#include +#include +#include + +#include "io_realm_react_RealmReactAndroid.h" +#include "js_init.h" +#include "rpc.hpp" +#include "platform.hpp" +#include "shared_realm.hpp" +#include +#include + +namespace facebook { + namespace react { + class JSCExecutor; + } +} + +/* + * Class: io_realm_react_RealmReactAndroid + * Method: injectRealmJsContext + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactAndroid_injectRealmJsContext + (JNIEnv *env, jclass, jstring fileDir) + { + __android_log_print(ANDROID_LOG_DEBUG, "JSRealm", "Java_io_realm_react_RealmReactAndroid_injectRealmJsContext"); + void* handle = dlopen ("libreactnativejni.so", RTLD_LAZY); + if (!handle) { + return 0; + //return env->NewStringUTF("Cannot open library"); + } + + // Getting the internal storage path for the application + const char* strFileDir = env->GetStringUTFChars(fileDir , NULL); + realm::set_default_realm_file_directory(strFileDir); + env->ReleaseStringUTFChars(fileDir , strFileDir); + + __android_log_print(ANDROID_LOG_DEBUG, "JSRealm", "Absolute path %s", realm::default_realm_file_directory().c_str()); + + // load the symbol + typedef std::unordered_map (*get_jsc_context_t)(); + + get_jsc_context_t get_jsc_context = (get_jsc_context_t) dlsym(handle, "get_jsc_context"); + + if (get_jsc_context != NULL) { + // clearing previous instances + realm::Realm::s_global_cache.clear(); + std::unordered_map s_globalContextRefToJSCExecutor = get_jsc_context(); + for (auto pair : s_globalContextRefToJSCExecutor) { + RJSInitializeInContext(pair.first); + } + return s_globalContextRefToJSCExecutor.size(); + //std::stringstream msg; + //msg << "Got the globalContext map, size=" << s_globalContextRefToJSCExecutor.size(); + //return env->NewStringUTF(msg.str().c_str()); + } else { + return 0; + // return env->NewStringUTF("Cannot find symbol get_jsc_context"); + } + } + +/* + * Class: io_realm_react_RealmReactAndroid + * Method: setupChromeDebugModeRealmJsContext + */ + static realm_js::RPCServer *s_rpc_server; + JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactAndroid_setupChromeDebugModeRealmJsContext + (JNIEnv *, jclass) + { + __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Java_com_reacttests_RealmReactAndroid_setupChromeDebugModeRealmJsContext"); + if (s_rpc_server) { + delete s_rpc_server; + } + s_rpc_server = new realm_js::RPCServer(); + return (jlong)s_rpc_server; + } + +/* + * Class: io_realm_react_RealmReactAndroid + * Method: processChromeDebugCommand + */ + + JNIEXPORT jstring JNICALL Java_io_realm_react_RealmReactAndroid_processChromeDebugCommand + (JNIEnv *env, jclass, jlong rpc_server_ptr, jstring chrome_cmd, jstring chrome_args) + { + __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Java_io_realm_react_RealmReactAndroid_processChromeDebugCommand"); + const char* cmd = env->GetStringUTFChars(chrome_cmd, NULL); + const char* args = env->GetStringUTFChars(chrome_args, NULL); + realm_js::json json = realm_js::json::parse(args); + realm_js::json response = s_rpc_server->perform_request(cmd, json); + env->ReleaseStringUTFChars(chrome_cmd, cmd); + env->ReleaseStringUTFChars(chrome_args, args); + return env->NewStringUTF(response.dump().c_str()); + } diff --git a/src/android/io_realm_react_RealmReactAndroid.h b/src/android/io_realm_react_RealmReactAndroid.h new file mode 100644 index 00000000..33f11ef7 --- /dev/null +++ b/src/android/io_realm_react_RealmReactAndroid.h @@ -0,0 +1,36 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class io_realm_react_RealmReactAndroid */ + +#ifndef _Included_io_realm_react_RealmReactAndroid +#define _Included_io_realm_react_RealmReactAndroid +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: io_realm_react_RealmReactAndroid + * Method: injectRealmJsContext + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactAndroid_injectRealmJsContext + (JNIEnv *, jclass, jstring); + +/* + * Class: io_realm_react_RealmReactAndroid + * Method: setupChromeDebugModeRealmJsContext + */ +JNIEXPORT jlong JNICALL Java_io_realm_react_RealmReactAndroid_setupChromeDebugModeRealmJsContext + (JNIEnv *, jclass); + +/* + * Class: io_realm_react_RealmReactAndroid + * Method: processsetupChromeDebugCommand + */ +JNIEXPORT jstring JNICALL Java_io_realm_react_RealmReactAndroid_processChromeDebugCommand + (JNIEnv *, jclass, jlong, jstring, jstring); + + +#ifdef __cplusplus +} +#endif +#endif