This reverts commit 27e432a5b1
.
This commit is contained in:
parent
7c70ce02bc
commit
f26e849fb2
12
Makefile
12
Makefile
|
@ -97,32 +97,32 @@ statusgo-cross: statusgo-android statusgo-ios
|
||||||
|
|
||||||
statusgo-linux: xgo ##@cross-compile Build status-go for Linux
|
statusgo-linux: xgo ##@cross-compile Build status-go for Linux
|
||||||
./_assets/patches/patcher -b . -p geth-xgo
|
./_assets/patches/patcher -b . -p geth-xgo
|
||||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=linux/amd64 -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/statusd
|
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=linux/amd64 -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/statusd
|
||||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||||
@echo "Android cross compilation done."
|
@echo "Android cross compilation done."
|
||||||
|
|
||||||
statusgo-android: xgo ##@cross-compile Build status-go for Android
|
statusgo-android: xgo ##@cross-compile Build status-go for Android
|
||||||
./_assets/patches/patcher -b . -p geth-xgo
|
./_assets/patches/patcher -b . -p geth-xgo
|
||||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||||
@echo "Android cross compilation done."
|
@echo "Android cross compilation done."
|
||||||
|
|
||||||
statusgo-ios: xgo ##@cross-compile Build status-go for iOS
|
statusgo-ios: xgo ##@cross-compile Build status-go for iOS
|
||||||
./_assets/patches/patcher -b . -p geth-xgo
|
./_assets/patches/patcher -b . -p geth-xgo
|
||||||
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||||
@echo "iOS framework cross compilation done."
|
@echo "iOS framework cross compilation done."
|
||||||
|
|
||||||
statusgo-ios-simulator: xgo ##@cross-compile Build status-go for iOS Simulator
|
statusgo-ios-simulator: xgo ##@cross-compile Build status-go for iOS Simulator
|
||||||
@docker pull $(XGOIMAGEIOSSIM)
|
@docker pull $(XGOIMAGEIOSSIM)
|
||||||
./_assets/patches/patcher -b . -p geth-xgo
|
./_assets/patches/patcher -b . -p geth-xgo
|
||||||
$(GOPATH)/bin/xgo --image $(XGOIMAGEIOSSIM) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
$(GOPATH)/bin/xgo --image $(XGOIMAGEIOSSIM) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
|
||||||
./_assets/patches/patcher -b . -p geth-xgo -r
|
./_assets/patches/patcher -b . -p geth-xgo -r
|
||||||
@echo "iOS framework cross compilation done."
|
@echo "iOS framework cross compilation done."
|
||||||
|
|
||||||
statusgo-library: ##@cross-compile Build status-go as static library for current platform
|
statusgo-library: ##@cross-compile Build status-go as static library for current platform
|
||||||
@echo "Building static library..."
|
@echo "Building static library..."
|
||||||
go build -buildmode=c-archive -tags library -o $(GOBIN)/libstatus.a ./lib
|
go build -buildmode=c-archive -o $(GOBIN)/libstatus.a ./lib
|
||||||
@echo "Static library built:"
|
@echo "Static library built:"
|
||||||
@ls -la $(GOBIN)/libstatus.*
|
@ls -la $(GOBIN)/libstatus.*
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ test-unit: UNIT_TEST_PACKAGES = $(shell go list ./... | \
|
||||||
grep -v /t/benchmarks | \
|
grep -v /t/benchmarks | \
|
||||||
grep -v /lib)
|
grep -v /lib)
|
||||||
test-unit: ##@tests Run unit and integration tests
|
test-unit: ##@tests Run unit and integration tests
|
||||||
go test $(UNIT_TEST_PACKAGES) $(gotest_extraflags)
|
go test -v $(UNIT_TEST_PACKAGES) $(gotest_extraflags)
|
||||||
|
|
||||||
test-unit-race: gotest_extraflags=-race
|
test-unit-race: gotest_extraflags=-race
|
||||||
test-unit-race: test-unit ##@tests Run unit and integration tests with -race flag
|
test-unit-race: test-unit ##@tests Run unit and integration tests with -race flag
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// +build darwin,cgo
|
||||||
|
|
||||||
|
package signal
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -x objective-c
|
||||||
|
#cgo LDFLAGS: -framework Foundation
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
extern bool StatusServiceSignalEvent( const char *jsonEvent );
|
||||||
|
*/
|
||||||
|
import "C"
|
207
signal/signals.c
207
signal/signals.c
|
@ -1,5 +1,208 @@
|
||||||
// +build library,!android,!arm
|
#if defined(IOS_DEPLOYMENT)
|
||||||
|
// ======================================================================================
|
||||||
|
// iOS framework compilation using xgo
|
||||||
|
// ======================================================================================
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <objc/objc.h>
|
||||||
|
#include <objc/runtime.h>
|
||||||
|
#include <objc/message.h>
|
||||||
|
|
||||||
|
static id statusServiceClassRef = nil;
|
||||||
|
static SEL statusServiceSelector = nil;
|
||||||
|
|
||||||
|
static bool initLibrary() {
|
||||||
|
if (statusServiceClassRef == nil) {
|
||||||
|
statusServiceClassRef = objc_getClass("Status");
|
||||||
|
if (statusServiceClassRef == nil) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusServiceSelector == nil) {
|
||||||
|
statusServiceSelector = sel_getUid("signalEvent:");
|
||||||
|
if (statusServiceSelector == nil) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Calls static method signalEvent of class GethService.
|
||||||
|
*
|
||||||
|
* @param jsonEvent - UTF8 string
|
||||||
|
*
|
||||||
|
* @note Definition of signalEvent method.
|
||||||
|
* + (void)signalEvent:(const char *)json
|
||||||
|
*/
|
||||||
|
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||||
|
if (!initLibrary()) return false;
|
||||||
|
|
||||||
|
void (*action)(id, SEL, const char *) = (void (*)(id, SEL, const char *)) objc_msgSend;
|
||||||
|
action(statusServiceClassRef, statusServiceSelector, jsonEvent);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEventCallback(void *cb) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(ANDROID_DEPLOYMENT)
|
||||||
|
// ======================================================================================
|
||||||
|
// Android archive compilation using xgo
|
||||||
|
// ======================================================================================
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
bool StatusServiceSignalEvent(const char *jsonEvent);
|
||||||
|
|
||||||
|
static JavaVM *gJavaVM = NULL;
|
||||||
|
static jclass JavaClassPtr_StatusService = NULL;
|
||||||
|
static jmethodID JavaMethodPtr_signalEvent = NULL;
|
||||||
|
|
||||||
|
static bool JniLibraryInit(JNIEnv *env);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Get interface to JNI.
|
||||||
|
*
|
||||||
|
* @return true if thread should be detached from JNI.
|
||||||
|
*/
|
||||||
|
static bool JniAttach(JNIEnv **env) {
|
||||||
|
jint status;
|
||||||
|
|
||||||
|
if (gJavaVM == NULL) {
|
||||||
|
env = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = (*gJavaVM)->GetEnv(gJavaVM, (void **)env, JNI_VERSION_1_6);
|
||||||
|
if (status == JNI_EDETACHED) {
|
||||||
|
// attach thread to JNI
|
||||||
|
//(*gJavaVM)->AttachCurrentThread( gJavaVM, (void **)env, NULL ); // Oracle JNI API
|
||||||
|
(*gJavaVM)->AttachCurrentThread(gJavaVM, env, NULL); // Android JNI API
|
||||||
|
return true;
|
||||||
|
} else if (status != JNI_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The VM calls JNI_OnLoad when the native library is loaded.
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
|
bool detach;
|
||||||
|
JNIEnv *env;
|
||||||
|
int result = JNI_VERSION_1_6;
|
||||||
|
|
||||||
|
gJavaVM = vm;
|
||||||
|
|
||||||
|
// attach thread to JNI
|
||||||
|
detach = JniAttach(&env);
|
||||||
|
if (env == NULL) {
|
||||||
|
// failed
|
||||||
|
gJavaVM = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!JniLibraryInit(env)) {
|
||||||
|
// fail loading of JNI library
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detach) {
|
||||||
|
// detach thread from JNI
|
||||||
|
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != JNI_VERSION_1_6) {
|
||||||
|
gJavaVM = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Initialize library.
|
||||||
|
*/
|
||||||
|
bool JniLibraryInit(JNIEnv *env) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
JavaClassPtr_StatusService = (*env)->FindClass(env, "im/status/ethereum/module/StatusService");
|
||||||
|
if (JavaClassPtr_StatusService == NULL) return false;
|
||||||
|
|
||||||
|
JavaClassPtr_StatusService = (jclass)(*env)->NewGlobalRef(env, JavaClassPtr_StatusService);
|
||||||
|
if (JavaClassPtr_StatusService == NULL) return false;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool bStatic;
|
||||||
|
jclass classPtr;
|
||||||
|
jmethodID *methodPtr;
|
||||||
|
const char *methodId;
|
||||||
|
const char *params;
|
||||||
|
} javaMethodDescriptors[] = {
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
JavaClassPtr_StatusService,
|
||||||
|
&JavaMethodPtr_signalEvent, // &JavaMethodPtr_someNonStaticMethod
|
||||||
|
"signalEvent", // someNonStaticMethod
|
||||||
|
"(Ljava/lang/String;)V"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(javaMethodDescriptors) / sizeof(javaMethodDescriptors[0]); i++) {
|
||||||
|
if (javaMethodDescriptors[i].bStatic) {
|
||||||
|
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetStaticMethodID(
|
||||||
|
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
||||||
|
} else {
|
||||||
|
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetMethodID(
|
||||||
|
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*(javaMethodDescriptors[i].methodPtr) == NULL) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Calls static method signalEvent of class im.status.ethereum.module.StatusService.
|
||||||
|
*
|
||||||
|
* @param jsonEvent - UTF8 string
|
||||||
|
*/
|
||||||
|
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||||
|
bool detach;
|
||||||
|
JNIEnv *env;
|
||||||
|
|
||||||
|
// attach thread to JNI
|
||||||
|
detach = JniAttach( &env );
|
||||||
|
if (env == NULL) { // failed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
jstring javaJsonEvent = NULL;
|
||||||
|
if (jsonEvent != NULL) {
|
||||||
|
javaJsonEvent = (*env)->NewStringUTF(env, jsonEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
(*env)->CallStaticVoidMethod(env, JavaClassPtr_StatusService, JavaMethodPtr_signalEvent, javaJsonEvent);
|
||||||
|
|
||||||
|
if (javaJsonEvent != NULL) (*env)->DeleteLocalRef(env, javaJsonEvent);
|
||||||
|
|
||||||
|
if (detach) { // detach thread from JNI
|
||||||
|
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEventCallback(void *cb) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
// ======================================================================================
|
// ======================================================================================
|
||||||
// cgo compilation (for desktop platforms and local tests)
|
// cgo compilation (for desktop platforms and local tests)
|
||||||
// ======================================================================================
|
// ======================================================================================
|
||||||
|
@ -25,3 +228,5 @@ bool StatusServiceSignalEvent(const char *jsonEvent) {
|
||||||
void SetEventCallback(void *cb) {
|
void SetEventCallback(void *cb) {
|
||||||
gCallback = (callback)cb;
|
gCallback = (callback)cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
// +build !library
|
|
||||||
|
|
||||||
package signal
|
package signal
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
extern bool StatusServiceSignalEvent(const char *jsonEvent);
|
||||||
|
extern void SetEventCallback(void *cb);
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -37,9 +44,9 @@ func send(typ string, event interface{}) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationHandlerMutex.RLock()
|
str := C.CString(string(data))
|
||||||
notificationHandler(string(data))
|
C.StatusServiceSignalEvent(str)
|
||||||
notificationHandlerMutex.RUnlock()
|
C.free(unsafe.Pointer(str))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeNotificationHandler defines a handler able to process incoming node events.
|
// NodeNotificationHandler defines a handler able to process incoming node events.
|
||||||
|
@ -53,7 +60,6 @@ var notificationHandlerMutex sync.RWMutex
|
||||||
|
|
||||||
// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
|
// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
|
||||||
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
||||||
logger.Warn("[DEBUG] Overriding notification handler")
|
|
||||||
notificationHandlerMutex.Lock()
|
notificationHandlerMutex.Lock()
|
||||||
notificationHandler = fn
|
notificationHandler = fn
|
||||||
notificationHandlerMutex.Unlock()
|
notificationHandlerMutex.Unlock()
|
||||||
|
@ -71,13 +77,23 @@ func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
|
||||||
logger.Trace("Notification received", "event", jsonEvent)
|
logger.Trace("Notification received", "event", jsonEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export NotifyNode
|
||||||
//nolint: golint
|
//nolint: golint
|
||||||
func TriggerTestSignal() {
|
func NotifyNode(jsonEvent *C.char) {
|
||||||
str := `{"answer": 42}`
|
|
||||||
notificationHandlerMutex.RLock()
|
notificationHandlerMutex.RLock()
|
||||||
notificationHandler(str)
|
defer notificationHandlerMutex.RUnlock()
|
||||||
notificationHandlerMutex.RUnlock()
|
notificationHandler(C.GoString(jsonEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export TriggerTestSignal
|
||||||
//nolint: golint
|
//nolint: golint
|
||||||
func SetSignalEventCallback(cb unsafe.Pointer) {}
|
func TriggerTestSignal() {
|
||||||
|
str := C.CString(`{"answer": 42}`)
|
||||||
|
C.StatusServiceSignalEvent(str)
|
||||||
|
C.free(unsafe.Pointer(str))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSignalEventCallback set callback
|
||||||
|
func SetSignalEventCallback(cb unsafe.Pointer) {
|
||||||
|
C.SetEventCallback(cb)
|
||||||
|
}
|
||||||
|
|
|
@ -1,153 +0,0 @@
|
||||||
// ======================================================================================
|
|
||||||
// Android archive compilation using xgo
|
|
||||||
// ======================================================================================
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <jni.h>
|
|
||||||
|
|
||||||
bool StatusServiceSignalEvent(const char *jsonEvent);
|
|
||||||
|
|
||||||
static JavaVM *gJavaVM = NULL;
|
|
||||||
static jclass JavaClassPtr_StatusService = NULL;
|
|
||||||
static jmethodID JavaMethodPtr_signalEvent = NULL;
|
|
||||||
|
|
||||||
static bool JniLibraryInit(JNIEnv *env);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Get interface to JNI.
|
|
||||||
*
|
|
||||||
* @return true if thread should be detached from JNI.
|
|
||||||
*/
|
|
||||||
static bool JniAttach(JNIEnv **env) {
|
|
||||||
jint status;
|
|
||||||
|
|
||||||
if (gJavaVM == NULL) {
|
|
||||||
env = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = (*gJavaVM)->GetEnv(gJavaVM, (void **)env, JNI_VERSION_1_6);
|
|
||||||
if (status == JNI_EDETACHED) {
|
|
||||||
// attach thread to JNI
|
|
||||||
//(*gJavaVM)->AttachCurrentThread( gJavaVM, (void **)env, NULL ); // Oracle JNI API
|
|
||||||
(*gJavaVM)->AttachCurrentThread(gJavaVM, env, NULL); // Android JNI API
|
|
||||||
return true;
|
|
||||||
} else if (status != JNI_OK) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief The VM calls JNI_OnLoad when the native library is loaded.
|
|
||||||
*/
|
|
||||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|
||||||
bool detach;
|
|
||||||
JNIEnv *env;
|
|
||||||
int result = JNI_VERSION_1_6;
|
|
||||||
|
|
||||||
gJavaVM = vm;
|
|
||||||
|
|
||||||
// attach thread to JNI
|
|
||||||
detach = JniAttach(&env);
|
|
||||||
if (env == NULL) {
|
|
||||||
// failed
|
|
||||||
gJavaVM = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!JniLibraryInit(env)) {
|
|
||||||
// fail loading of JNI library
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (detach) {
|
|
||||||
// detach thread from JNI
|
|
||||||
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != JNI_VERSION_1_6) {
|
|
||||||
gJavaVM = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Initialize library.
|
|
||||||
*/
|
|
||||||
bool JniLibraryInit(JNIEnv *env) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
JavaClassPtr_StatusService = (*env)->FindClass(env, "im/status/ethereum/module/StatusService");
|
|
||||||
if (JavaClassPtr_StatusService == NULL) return false;
|
|
||||||
|
|
||||||
JavaClassPtr_StatusService = (jclass)(*env)->NewGlobalRef(env, JavaClassPtr_StatusService);
|
|
||||||
if (JavaClassPtr_StatusService == NULL) return false;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
bool bStatic;
|
|
||||||
jclass classPtr;
|
|
||||||
jmethodID *methodPtr;
|
|
||||||
const char *methodId;
|
|
||||||
const char *params;
|
|
||||||
} javaMethodDescriptors[] = {
|
|
||||||
{
|
|
||||||
true,
|
|
||||||
JavaClassPtr_StatusService,
|
|
||||||
&JavaMethodPtr_signalEvent, // &JavaMethodPtr_someNonStaticMethod
|
|
||||||
"signalEvent", // someNonStaticMethod
|
|
||||||
"(Ljava/lang/String;)V"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(javaMethodDescriptors) / sizeof(javaMethodDescriptors[0]); i++) {
|
|
||||||
if (javaMethodDescriptors[i].bStatic) {
|
|
||||||
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetStaticMethodID(
|
|
||||||
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
|
||||||
} else {
|
|
||||||
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetMethodID(
|
|
||||||
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(javaMethodDescriptors[i].methodPtr) == NULL) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Calls static method signalEvent of class im.status.ethereum.module.StatusService.
|
|
||||||
*
|
|
||||||
* @param jsonEvent - UTF8 string
|
|
||||||
*/
|
|
||||||
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
|
||||||
bool detach;
|
|
||||||
JNIEnv *env;
|
|
||||||
|
|
||||||
// attach thread to JNI
|
|
||||||
detach = JniAttach( &env );
|
|
||||||
if (env == NULL) { // failed
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
jstring javaJsonEvent = NULL;
|
|
||||||
if (jsonEvent != NULL) {
|
|
||||||
javaJsonEvent = (*env)->NewStringUTF(env, jsonEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*env)->CallStaticVoidMethod(env, JavaClassPtr_StatusService, JavaMethodPtr_signalEvent, javaJsonEvent);
|
|
||||||
|
|
||||||
if (javaJsonEvent != NULL) (*env)->DeleteLocalRef(env, javaJsonEvent);
|
|
||||||
|
|
||||||
if (detach) { // detach thread from JNI
|
|
||||||
(*gJavaVM)->DetachCurrentThread(gJavaVM);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetEventCallback(void *cb) {
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,103 +0,0 @@
|
||||||
// +build library,darwin
|
|
||||||
|
|
||||||
package signal
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo CFLAGS: -x objective-c
|
|
||||||
#cgo LDFLAGS: -framework Foundation
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
extern bool StatusServiceSignalEvent(const char *jsonEvent);
|
|
||||||
extern void SetEventCallback(void *cb);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// All general log messages in this package should be routed through this logger.
|
|
||||||
var logger = log.New("package", "status-go/signal")
|
|
||||||
|
|
||||||
// Envelope is a general signal sent upward from node to RN app
|
|
||||||
type Envelope struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Event interface{} `json:"event"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEnvelope creates new envlope of given type and event payload.
|
|
||||||
func NewEnvelope(typ string, event interface{}) *Envelope {
|
|
||||||
return &Envelope{
|
|
||||||
Type: typ,
|
|
||||||
Event: event,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send sends application signal (in JSON) upwards to application (via default notification handler)
|
|
||||||
func send(typ string, event interface{}) {
|
|
||||||
signal := NewEnvelope(typ, event)
|
|
||||||
data, err := json.Marshal(&signal)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("Marshalling signal envelope", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
str := C.CString(string(data))
|
|
||||||
C.StatusServiceSignalEvent(str)
|
|
||||||
C.free(unsafe.Pointer(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeNotificationHandler defines a handler able to process incoming node events.
|
|
||||||
// Events are encoded as JSON strings.
|
|
||||||
type NodeNotificationHandler func(jsonEvent string)
|
|
||||||
|
|
||||||
var notificationHandler NodeNotificationHandler = TriggerDefaultNodeNotificationHandler
|
|
||||||
|
|
||||||
// notificationHandlerMutex guards notificationHandler for concurrent calls
|
|
||||||
var notificationHandlerMutex sync.RWMutex
|
|
||||||
|
|
||||||
// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
|
|
||||||
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
|
||||||
notificationHandlerMutex.Lock()
|
|
||||||
notificationHandler = fn
|
|
||||||
notificationHandlerMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetDefaultNodeNotificationHandler sets notification handler to default one
|
|
||||||
func ResetDefaultNodeNotificationHandler() {
|
|
||||||
notificationHandlerMutex.Lock()
|
|
||||||
notificationHandler = TriggerDefaultNodeNotificationHandler
|
|
||||||
notificationHandlerMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerDefaultNodeNotificationHandler triggers default notification handler (helpful in tests)
|
|
||||||
func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
|
|
||||||
logger.Trace("Notification received", "event", jsonEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export NotifyNode
|
|
||||||
//nolint: golint
|
|
||||||
func NotifyNode(jsonEvent *C.char) {
|
|
||||||
notificationHandlerMutex.RLock()
|
|
||||||
defer notificationHandlerMutex.RUnlock()
|
|
||||||
notificationHandler(C.GoString(jsonEvent))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export TriggerTestSignal
|
|
||||||
//nolint: golint
|
|
||||||
func TriggerTestSignal() {
|
|
||||||
str := C.CString(`{"answer": 42}`)
|
|
||||||
C.StatusServiceSignalEvent(str)
|
|
||||||
C.free(unsafe.Pointer(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSignalEventCallback set callback
|
|
||||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
|
||||||
C.SetEventCallback(cb)
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
// ======================================================================================
|
|
||||||
// iOS framework compilation using xgo
|
|
||||||
// ======================================================================================
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <objc/objc.h>
|
|
||||||
#include <objc/runtime.h>
|
|
||||||
#include <objc/message.h>
|
|
||||||
|
|
||||||
static id statusServiceClassRef = nil;
|
|
||||||
static SEL statusServiceSelector = nil;
|
|
||||||
|
|
||||||
static bool initLibrary() {
|
|
||||||
if (statusServiceClassRef == nil) {
|
|
||||||
statusServiceClassRef = objc_getClass("Status");
|
|
||||||
if (statusServiceClassRef == nil) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (statusServiceSelector == nil) {
|
|
||||||
statusServiceSelector = sel_getUid("signalEvent:");
|
|
||||||
if (statusServiceSelector == nil) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* @brief Calls static method signalEvent of class GethService.
|
|
||||||
*
|
|
||||||
* @param jsonEvent - UTF8 string
|
|
||||||
*
|
|
||||||
* @note Definition of signalEvent method.
|
|
||||||
* + (void)signalEvent:(const char *)json
|
|
||||||
*/
|
|
||||||
bool StatusServiceSignalEvent(const char *jsonEvent) {
|
|
||||||
if (!initLibrary()) return false;
|
|
||||||
|
|
||||||
void (*action)(id, SEL, const char *) = (void (*)(id, SEL, const char *)) objc_msgSend;
|
|
||||||
action(statusServiceClassRef, statusServiceSelector, jsonEvent);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetEventCallback(void *cb) {
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
// +build library,!darwin
|
|
||||||
|
|
||||||
package signal
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
extern bool StatusServiceSignalEvent(const char *jsonEvent);
|
|
||||||
extern void SetEventCallback(void *cb);
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// All general log messages in this package should be routed through this logger.
|
|
||||||
var logger = log.New("package", "status-go/signal")
|
|
||||||
|
|
||||||
// Envelope is a general signal sent upward from node to RN app
|
|
||||||
type Envelope struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
Event interface{} `json:"event"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEnvelope creates new envlope of given type and event payload.
|
|
||||||
func NewEnvelope(typ string, event interface{}) *Envelope {
|
|
||||||
return &Envelope{
|
|
||||||
Type: typ,
|
|
||||||
Event: event,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// send sends application signal (in JSON) upwards to application (via default notification handler)
|
|
||||||
func send(typ string, event interface{}) {
|
|
||||||
signal := NewEnvelope(typ, event)
|
|
||||||
data, err := json.Marshal(&signal)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("Marshalling signal envelope", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
str := C.CString(string(data))
|
|
||||||
C.StatusServiceSignalEvent(str)
|
|
||||||
C.free(unsafe.Pointer(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeNotificationHandler defines a handler able to process incoming node events.
|
|
||||||
// Events are encoded as JSON strings.
|
|
||||||
type NodeNotificationHandler func(jsonEvent string)
|
|
||||||
|
|
||||||
var notificationHandler NodeNotificationHandler = TriggerDefaultNodeNotificationHandler
|
|
||||||
|
|
||||||
// notificationHandlerMutex guards notificationHandler for concurrent calls
|
|
||||||
var notificationHandlerMutex sync.RWMutex
|
|
||||||
|
|
||||||
// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
|
|
||||||
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
|
||||||
notificationHandlerMutex.Lock()
|
|
||||||
notificationHandler = fn
|
|
||||||
notificationHandlerMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetDefaultNodeNotificationHandler sets notification handler to default one
|
|
||||||
func ResetDefaultNodeNotificationHandler() {
|
|
||||||
notificationHandlerMutex.Lock()
|
|
||||||
notificationHandler = TriggerDefaultNodeNotificationHandler
|
|
||||||
notificationHandlerMutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TriggerDefaultNodeNotificationHandler triggers default notification handler (helpful in tests)
|
|
||||||
func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
|
|
||||||
logger.Trace("Notification received", "event", jsonEvent)
|
|
||||||
}
|
|
||||||
|
|
||||||
//export NotifyNode
|
|
||||||
//nolint: golint
|
|
||||||
func NotifyNode(jsonEvent *C.char) {
|
|
||||||
notificationHandlerMutex.RLock()
|
|
||||||
defer notificationHandlerMutex.RUnlock()
|
|
||||||
notificationHandler(C.GoString(jsonEvent))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export TriggerTestSignal
|
|
||||||
//nolint: golint
|
|
||||||
func TriggerTestSignal() {
|
|
||||||
str := C.CString(`{"answer": 42}`)
|
|
||||||
C.StatusServiceSignalEvent(str)
|
|
||||||
C.free(unsafe.Pointer(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetSignalEventCallback set callback
|
|
||||||
func SetSignalEventCallback(cb unsafe.Pointer) {
|
|
||||||
C.SetEventCallback(cb)
|
|
||||||
}
|
|
Loading…
Reference in New Issue