Skip to content

Commit

Permalink
Add calling js functions based on string parameters (#1602)
Browse files Browse the repository at this point in the history
As written in iotjs_tizen_service_app.c, iot.js app for tizen is a
hybrid one, which combines features of both native and js app.
This commit provides a way to call  js function bound with tizen
module in the app model.

This also includes a patch for the bug in getResPath.

IoT.js-DCO-1.0-Signed-off-by: Daeyeon Jeong daeyeon.jeong@samsung.com
  • Loading branch information
daeyeon authored and yichoi committed May 3, 2018
1 parent 1ed223c commit 5af9e46
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 9 deletions.
47 changes: 47 additions & 0 deletions include/iotjs_module_tizen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef IOTJS_MODULE_TIZEN_H
#define IOTJS_MODULE_TIZEN_H

#ifndef IOTJS_EXTERN_C
#ifdef __cplusplus
#define IOTJS_EXTERN_C extern "C"
#else /* !__cplusplus */
#define IOTJS_EXTERN_C extern
#endif /* !__cplusplus */
#endif /* !IOTJS_EXTERN_C */

#include <app_control.h>
#include <string.h>

typedef void (*user_callback_t)(int error, const char* data);

IOTJS_EXTERN_C
void iotjs_tizen_app_control_cb(app_control_h app_control, void* user_data);

IOTJS_EXTERN_C
int iotjs_tizen_bridge_native(const char* fn_name, unsigned fn_name_size,
const char* message, unsigned message_size,
user_callback_t cb);

#define IOTJS_TIZEN_CALL_JFUNC(name, msg, cb) \
({ \
if (name != NULL && (msg) != NULL) \
iotjs_tizen_bridge_native(name, strlen(name), msg, strlen(msg), cb); \
})


#endif /* IOTJS_MODULE_TIZEN_H */
52 changes: 52 additions & 0 deletions samples/tizen-bridge-native/tizen_bridge_native.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "iotjs.h"
#include "iotjs_module_tizen.h"

/* thread */
#include <pthread.h>
#include <unistd.h>
/* printf */
#include <stdio.h>


static void user_cb(int err, const char* data) {
printf("err: %d, data: %s\n", err, data);
}


void* thread(void* data) {
sleep(1);

char* str = "1234567A1234567B1234567C";
IOTJS_TIZEN_CALL_JFUNC("hello", "world", user_cb);
IOTJS_TIZEN_CALL_JFUNC("hello", str, user_cb);
IOTJS_TIZEN_CALL_JFUNC("hello", "", user_cb);
IOTJS_TIZEN_CALL_JFUNC("", "", user_cb);
IOTJS_TIZEN_CALL_JFUNC("", "", NULL);
IOTJS_TIZEN_CALL_JFUNC("notReturnString", "", user_cb);
return 0;
}


int main(int argc, char** argv) {
pthread_t tid;
if (pthread_create(&(tid), NULL, &thread, NULL)) {
return 1;
}

return iotjs_entry(argc, argv);
}
27 changes: 27 additions & 0 deletions samples/tizen-bridge-native/tizen_bridge_native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

var tizen = require('tizen');

tizen.hello = function(data) {
return 'tizen.hello is called with data, ' + (data ? data : 'null');
}

tizen.notReturnString = function(data) {
}

setInterval(function() {
console.log('heartbeat');
}, 10000);
3 changes: 3 additions & 0 deletions src/iotjs_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void iotjs_buffer_release(char* buff);
#define IOTJS_ALLOC(type) /* Allocate (type)-sized, (type*)-typed memory */ \
(type*)iotjs_buffer_allocate(sizeof(type))

#define IOTJS_CALLOC(num, type) \
(type*)iotjs_buffer_allocate((num * sizeof(type)))

#define IOTJS_RELEASE(ptr) /* Release memory allocated by IOTJS_ALLOC() */ \
({ \
iotjs_buffer_release((char*)ptr); \
Expand Down
2 changes: 1 addition & 1 deletion src/js/tizen.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function launchAppControl(option) {


var getResPath = function() {
return this.bridge.sendSync('getResPath', '');
return bridge.sendSync('getResPath', '');
};


Expand Down
123 changes: 115 additions & 8 deletions src/modules/tizen/iotjs_module_tizen-tizen.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,22 @@
#include "modules/iotjs_module_bridge.h"

#include <app_common.h>
#include <app_control.h>
#include <bundle.h>

typedef enum {
IOTJS_ERROR_NONE = 0,
IOTJS_ERROR_RESULT_FAILED,
IOTJS_ERROR_RESULT_FAILED = INT_MIN,
IOTJS_ERROR_INVALID_PARAMETER,
IOTJS_ERROR_OUT_OF_MEMORY,
IOTJS_ERROR_NONE = 0,
} iotjs_error_t;

// application control
// # tizen app-control
#include <app_control.h>
#include <app_control_internal.h>
#include <bundle.h>
#include <bundle_internal.h>

iotjs_error_t send_launch_request(const char* json, void* hbridge) {
static iotjs_error_t tizen_send_launch_request(const char* json,
void* hbridge) {
DDDLOG("%s", __func__);

bundle* b;
Expand Down Expand Up @@ -87,7 +89,7 @@ iotjs_error_t send_launch_request(const char* json, void* hbridge) {
}


void iotjs_service_app_control_cb(app_control_h app_control, void* user_data) {
void iotjs_tizen_app_control_cb(app_control_h app_control, void* user_data) {
DDDLOG("%s", __func__);

iotjs_environment_t* env = iotjs_environment_get();
Expand Down Expand Up @@ -131,6 +133,7 @@ void iotjs_service_app_control_cb(app_control_h app_control, void* user_data) {
}


// # tizen bridge
void iotjs_tizen_func(const char* command, const char* message, void* handle) {
DDDLOG("%s, cmd: %s, msg: %s", __func__, command, message);

Expand All @@ -140,7 +143,7 @@ void iotjs_tizen_func(const char* command, const char* message, void* handle) {

} else if (strncmp(command, "launchAppControl", strlen("launchAppControl")) ==
0) {
iotjs_error_t err = send_launch_request(message, handle);
iotjs_error_t err = tizen_send_launch_request(message, handle);
if (err == IOTJS_ERROR_NONE) {
iotjs_bridge_set_msg(handle, "OK");
}
Expand All @@ -149,3 +152,107 @@ void iotjs_tizen_func(const char* command, const char* message, void* handle) {
iotjs_bridge_set_err(handle, "Can't find command");
}
}


// # tizen bridge-native
typedef void (*user_callback_t)(int error, const char* data);

typedef struct {
uv_async_t async;
char* module;
char* fn_name;
char* message;
user_callback_t cb;
} iotjs_call_jfunc_t;


static char* create_string_buffer(const char* src, size_t size) {
char* dest = IOTJS_CALLOC(size + 1, char);
strncpy(dest, src, size);
dest[size] = '\0'; // just for being sure
return dest;
}


static bool bridge_native_call(const char* module_name, const char* func_name,
const char* message,
iotjs_string_t* output_str) {
bool result = false;

jerry_value_t jmodule = iotjs_module_get(module_name);
jerry_value_t jfunc = iotjs_jval_get_property(jmodule, func_name);

if (jerry_value_is_function(jfunc) == false) {
return result;
}

iotjs_jargs_t jargv = iotjs_jargs_create(1);
iotjs_jargs_append_string_raw(&jargv, message);
jerry_value_t jres = iotjs_make_callback_with_result(jfunc, jmodule, &jargv);

if (jerry_value_is_string(jres)) {
IOTJS_ASSERT(output_str != NULL);
*output_str = iotjs_jval_as_string(jres);
result = true;
}

jerry_release_value(jfunc);
jerry_release_value(jres);
iotjs_jargs_destroy(&jargv);
return result;
}


static void bridge_native_async_handler(uv_async_t* handle) {
DDDLOG("%s\n", __func__);
iotjs_call_jfunc_t* data = (iotjs_call_jfunc_t*)handle->data;

bool result;
iotjs_string_t output;

result = bridge_native_call(IOTJS_MAGIC_STRING_TIZEN, data->fn_name,
data->message, &output);

if (data->cb) {
data->cb((int)!result, iotjs_string_data(&output));
}

iotjs_string_destroy(&output);

// release
uv_close((uv_handle_t*)&data->async, NULL);
IOTJS_RELEASE(data->module);
IOTJS_RELEASE(data->fn_name);
IOTJS_RELEASE(data->message);
IOTJS_RELEASE(data);
}


int iotjs_tizen_bridge_native(const char* fn_name, unsigned fn_name_size,
const char* message, unsigned message_size,
user_callback_t cb) {
iotjs_environment_t* env = iotjs_environment_get();

if (env->state != kRunningMain && env->state != kRunningLoop) {
return IOTJS_ERROR_RESULT_FAILED;
}

iotjs_call_jfunc_t* handle = IOTJS_ALLOC(iotjs_call_jfunc_t);

if (handle == NULL) {
return IOTJS_ERROR_OUT_OF_MEMORY;
}

handle->async.data = (void*)handle;
handle->fn_name = create_string_buffer(fn_name, fn_name_size);
handle->message = create_string_buffer(message, message_size);
handle->module = create_string_buffer(IOTJS_MAGIC_STRING_TIZEN,
sizeof(IOTJS_MAGIC_STRING_TIZEN));
handle->cb = cb;

uv_loop_t* loop = iotjs_environment_loop(env);
uv_async_init(loop, &handle->async, bridge_native_async_handler);
uv_async_send(&handle->async);

return IOTJS_ERROR_NONE;
}

0 comments on commit 5af9e46

Please sign in to comment.