This repository has been archived by the owner on Mar 9, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* CouchDB now runs in the same process as the Dalvik VM. * JNI library/NIF added for direct communication from Erlang for: - Collation via java.text.Collator - Notification of CouchDB start, along with URL - Direct logging to logcat (as we no longer capture stdout) * .beam and .app files are now loaded directly from the .APK * Extra files layout has changed. .beam, .app, and .so files are now in overlay.zip, which is extracted over the target project by the couchbase.xml ant script. * .so files now live in libs/armeabi, and get auto-extracted by android Change-Id: I8ad5817a285ad831ca572683a35799ceb36c3ada Reviewed-on: http://review.couchbase.org/9617 Reviewed-by: Aaron Miller <apage43@ninjawhale.com> Tested-by: Aaron Miller <apage43@ninjawhale.com>
- Loading branch information
Showing
22 changed files
with
976 additions
and
381 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,78 @@ | |||
#include "android/log.h" | |||
#include "erl_nif.h" | |||
#include <string.h> | |||
#include <jni.h> | |||
|
|||
#include "com_couchbase_android_ErlangThread.h" | |||
|
|||
#define LOG_TAG "JNINIF" | |||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) | |||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) | |||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) | |||
|
|||
extern JavaVM *jvm; | |||
extern jclass ErlangThread; | |||
extern jmethodID ErlMessageMethod; | |||
|
|||
struct caller_info { | |||
ErlNifPid pid; | |||
ErlNifEnv *env; | |||
}; | |||
|
|||
JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_send_1bin | |||
(JNIEnv *env, jclass cls, jbyteArray jbin, jlong cinfo) { | |||
struct caller_info* inf = (struct caller_info*) cinfo; | |||
ErlNifEnv* msg = enif_alloc_env(); | |||
ERL_NIF_TERM bin_term; | |||
jsize length = env->GetArrayLength(jbin); | |||
jbyte* bindata = (jbyte*) enif_make_new_binary(msg, length, &bin_term); | |||
env->GetByteArrayRegion(jbin, 0, length, bindata); | |||
enif_send(inf->env, &(inf->pid), msg, bin_term); | |||
enif_free_env(msg); | |||
} | |||
|
|||
static ERL_NIF_TERM mkatom(ErlNifEnv* env, const char* name) { | |||
ERL_NIF_TERM atom; | |||
if(enif_make_existing_atom(env, name, &atom, ERL_NIF_LATIN1)) { | |||
return atom; | |||
} else { | |||
return enif_make_atom(env, name); | |||
} | |||
} | |||
|
|||
static ERL_NIF_TERM jninif_send(ErlNifEnv* nif_env, int argc, const ERL_NIF_TERM argv[]) | |||
{ | |||
struct caller_info cinf; | |||
JNIEnv *env = NULL; | |||
char namebuf[512]; | |||
|
|||
cinf.env = nif_env; | |||
enif_self(nif_env, &(cinf.pid)); | |||
|
|||
if(!enif_get_atom(nif_env, argv[0], namebuf, 512, ERL_NIF_LATIN1)) { | |||
return mkatom(nif_env, "name_too_long"); | |||
} | |||
|
|||
jvm->AttachCurrentThread(&env, NULL); | |||
if(env == NULL) { | |||
return mkatom(nif_env, "jni_error"); | |||
} | |||
|
|||
env->PushLocalFrame(2); //We use 2 local JNI refs per invoc. | |||
ErlNifBinary ebin; | |||
jbyteArray jbin; | |||
jstring name = env->NewStringUTF(namebuf); | |||
enif_inspect_binary(nif_env, argv[1], &ebin); | |||
jbin = env->NewByteArray(ebin.size); | |||
env->SetByteArrayRegion(jbin, 0, ebin.size, (jbyte*) ebin.data); | |||
env->CallStaticVoidMethod(ErlangThread, ErlMessageMethod, name, jbin, (jlong) &cinf); | |||
env->PopLocalFrame(NULL); | |||
return mkatom(nif_env, "ok"); | |||
} | |||
|
|||
static ErlNifFunc jninif_funcs[] = | |||
{ | |||
{"send", 2, jninif_send} | |||
}; | |||
|
|||
ERL_NIF_INIT(jninif, jninif_funcs, NULL, NULL, NULL, NULL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,65 @@ | |||
#include "com_couchbase_android_ErlangThread.h" | |||
|
|||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <dlfcn.h> | |||
|
|||
#include "android/log.h" | |||
|
|||
#define LOG_TAG "ErlangThread" | |||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) | |||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) | |||
|
|||
JavaVM *jvm; | |||
jclass ErlangThread; | |||
jmethodID ErlMessageMethod; | |||
|
|||
JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_start_1erlang | |||
(JNIEnv *env, jclass cls, jstring j_bindir, jstring j_sopath, jobjectArray j_args) { | |||
jboolean iscopy; | |||
int i, argc; | |||
char ** argv; | |||
void (*erl_start)(int, char**) = NULL; | |||
|
|||
const char *sopath = env->GetStringUTFChars(j_sopath, &iscopy); | |||
const char *bindir = env->GetStringUTFChars(j_bindir, &iscopy); | |||
|
|||
void* handle = dlopen(sopath, RTLD_LAZY); | |||
|
|||
if(!handle) { | |||
LOGE("Failed to open beam .so: %s", dlerror()); | |||
goto cleanup; | |||
} | |||
*(void **)(&erl_start) = dlsym(handle, "erl_start"); | |||
if(!erl_start) { | |||
LOGE("Failed to find erl_start: %s", dlerror()); | |||
goto cleanup; | |||
} | |||
argc = env->GetArrayLength(j_args); | |||
argv = (char**) malloc(sizeof(char*) * argc); | |||
|
|||
for(i = 0; i < argc; i++) | |||
{ | |||
argv[i] = (char*) env->GetStringUTFChars((jstring) env->GetObjectArrayElement(j_args, i), &iscopy); | |||
} | |||
setenv("BINDIR", bindir, 1); | |||
env->GetJavaVM(&jvm); | |||
ErlMessageMethod = env->GetStaticMethodID(cls, "erl_message", "(Ljava/lang/String;[BJ)V"); | |||
ErlangThread = (jclass) env->NewGlobalRef(cls); | |||
erl_start(argc, argv); | |||
|
|||
cleanup: | |||
env->DeleteGlobalRef(ErlangThread); | |||
env->ReleaseStringUTFChars(j_sopath, sopath); | |||
env->ReleaseStringUTFChars(j_bindir, bindir); | |||
if(handle) dlclose(handle); | |||
if(argv) | |||
{ | |||
for(i = 0; i < argc; i++) | |||
{ | |||
env->ReleaseStringUTFChars((jstring) env->GetObjectArrayElement(j_args, i), argv[i]); | |||
} | |||
free(argv); | |||
} | |||
return; | |||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.