Revert "Add build tags to signal package (#1119)" (#1148)

This reverts commit 27e432a5b1.
This commit is contained in:
Adam Babik 2018-08-10 13:23:28 +02:00 committed by GitHub
parent 7c70ce02bc
commit f26e849fb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 251 additions and 424 deletions

View File

@ -97,32 +97,32 @@ statusgo-cross: statusgo-android statusgo-ios
statusgo-linux: xgo ##@cross-compile Build status-go for Linux
./_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
@echo "Android cross compilation done."
statusgo-android: xgo ##@cross-compile Build status-go for Android
./_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
@echo "Android cross compilation done."
statusgo-ios: xgo ##@cross-compile Build status-go for iOS
./_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
@echo "iOS framework cross compilation done."
statusgo-ios-simulator: xgo ##@cross-compile Build status-go for iOS Simulator
@docker pull $(XGOIMAGEIOSSIM)
./_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
@echo "iOS framework cross compilation done."
statusgo-library: ##@cross-compile Build status-go as static library for current platform
@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:"
@ls -la $(GOBIN)/libstatus.*
@ -197,7 +197,7 @@ test-unit: UNIT_TEST_PACKAGES = $(shell go list ./... | \
grep -v /t/benchmarks | \
grep -v /lib)
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: test-unit ##@tests Run unit and integration tests with -race flag

12
signal/ios.go Normal file
View File

@ -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"

View File

@ -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)
// ======================================================================================
@ -25,3 +228,5 @@ bool StatusServiceSignalEvent(const char *jsonEvent) {
void SetEventCallback(void *cb) {
gCallback = (callback)cb;
}
#endif

View File

@ -1,9 +1,16 @@
// +build !library
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"
@ -37,9 +44,9 @@ func send(typ string, event interface{}) {
return
}
notificationHandlerMutex.RLock()
notificationHandler(string(data))
notificationHandlerMutex.RUnlock()
str := C.CString(string(data))
C.StatusServiceSignalEvent(str)
C.free(unsafe.Pointer(str))
}
// 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
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
logger.Warn("[DEBUG] Overriding notification handler")
notificationHandlerMutex.Lock()
notificationHandler = fn
notificationHandlerMutex.Unlock()
@ -71,13 +77,23 @@ func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
logger.Trace("Notification received", "event", jsonEvent)
}
//export NotifyNode
//nolint: golint
func TriggerTestSignal() {
str := `{"answer": 42}`
func NotifyNode(jsonEvent *C.char) {
notificationHandlerMutex.RLock()
notificationHandler(str)
notificationHandlerMutex.RUnlock()
defer notificationHandlerMutex.RUnlock()
notificationHandler(C.GoString(jsonEvent))
}
//export TriggerTestSignal
//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)
}

View File

@ -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) {
}

View File

@ -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)
}

View File

@ -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) {
}

View File

@ -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)
}