mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-07 19:05:54 +08:00
add remote_ui to ui auto test
This commit is contained in:
parent
37bdd202c4
commit
4997b13211
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,3 +37,6 @@ tools/idl_gen/idl.json
|
||||
tools/idl_gen/tkc.json
|
||||
t.*
|
||||
test.png
|
||||
README.md.download
|
||||
manifest.txt
|
||||
test.xml
|
||||
|
@ -76,6 +76,7 @@ if complie_helper.get_value('BUILD_TOOLS', True) :
|
||||
'tools/preview_ui/SConscript',
|
||||
'tools/fdb/SConscript',
|
||||
'tools/dltest/SConscript',
|
||||
'tools/ui_test/SConscript',
|
||||
'src/hal/tools/network_shell/SConscript',
|
||||
]
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "ext_widgets.h"
|
||||
#include "base/font_manager.h"
|
||||
#include "base/event_recorder_player.h"
|
||||
#include "remote_ui/service/remote_ui_service.h"
|
||||
|
||||
#define DEMOUI_MAIN_WINDOW_NAME "main"
|
||||
#define SCROLL_BAR_H_WIDGT_NAME "bar_h"
|
||||
@ -1416,6 +1417,12 @@ ret_t application_init() {
|
||||
fs_get_user_storage_path(os_fs(), path);
|
||||
log_debug("user storage path:%s\n", path);
|
||||
|
||||
#ifndef REMOTE_UI_URL
|
||||
#define REMOTE_UI_URL "tcp://localhost:2233"
|
||||
#endif/*REMOTE_UI_URL*/
|
||||
|
||||
tk_service_start(main_loop_get_event_source_manager(main_loop()), REMOTE_UI_URL, remote_ui_service_create, NULL);
|
||||
|
||||
return show_preload_res_window();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,11 @@
|
||||
# 最新动态
|
||||
2023/11/5
|
||||
* 完善UI自动测试框架 src/remote\_ui
|
||||
* 增加服务接口 src/service
|
||||
|
||||
2023/11/4
|
||||
* 增加UI自动测试框架 src/remote\_ui
|
||||
|
||||
2023/11/03
|
||||
* 修复子进程继承句柄机制有概率导致父进程异常的问题(感谢智明提供补丁)
|
||||
* 修复ui\_loader\_load\_widget接口加载edit控件时打印大量警告的问题(感谢雨欣提供补丁)
|
||||
|
@ -23,6 +23,10 @@ BASE_SOURCES = Glob('layouters/*.c') + \
|
||||
Glob('widget_animators/*.c') + \
|
||||
Glob('window_animators/*.c') + \
|
||||
Glob('dialog_highlighters/*.c') + \
|
||||
Glob('service/*.c') + \
|
||||
Glob('remote_ui/service/*.c') + \
|
||||
Glob('remote_ui/client/*.c') + \
|
||||
Glob('remote_ui/shared/*.c') + \
|
||||
Glob('window_manager/window_manager_default.c')
|
||||
|
||||
if GRAPHIC_BUFFER == "default" :
|
||||
|
@ -5275,3 +5275,51 @@ ret_t widget_dispatch_model_event(widget_t* widget, const char* name, const char
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
widget_t* widget_find_by_path(widget_t* widget, const char* path, bool_t recursive) {
|
||||
bool_t is_first = TRUE;
|
||||
tokenizer_t tokenizer;
|
||||
widget_t* iter = widget;
|
||||
tokenizer_t* t = NULL;
|
||||
return_value_if_fail(widget != NULL && path != NULL, NULL);
|
||||
if (strchr(path, '.') == NULL) {
|
||||
const char* name = path;
|
||||
if (tk_str_eq(name, STR_PROP_PARENT)) {
|
||||
return widget->parent;
|
||||
} else if (tk_str_eq(name, STR_PROP_SELF)) {
|
||||
return widget;
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW)) {
|
||||
return widget_get_window(widget);
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) {
|
||||
return widget_get_window_manager(widget);
|
||||
} else {
|
||||
return widget_lookup(widget, name, recursive);
|
||||
}
|
||||
}
|
||||
t = tokenizer_init(&tokenizer, path, strlen(path), ".");
|
||||
return_value_if_fail(t != NULL, NULL);
|
||||
|
||||
while (tokenizer_has_more(t) && iter != NULL) {
|
||||
const char* name = tokenizer_next(t);
|
||||
if (is_first) {
|
||||
if (tk_str_eq(name, STR_PROP_PARENT)) {
|
||||
iter = widget->parent;
|
||||
} else if (tk_str_eq(name, STR_PROP_SELF)) {
|
||||
iter = widget;
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW)) {
|
||||
iter = widget_get_window(widget);
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) {
|
||||
iter = widget_get_window_manager(widget);
|
||||
} else {
|
||||
iter = widget_child(iter, name);
|
||||
}
|
||||
is_first = FALSE;
|
||||
} else {
|
||||
iter = widget_child(iter, name);
|
||||
}
|
||||
}
|
||||
tokenizer_deinit(t);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
|
@ -3390,6 +3390,8 @@ ret_t widget_draw_image_with_region(widget_t* widget, canvas_t* c, bitmap_t* img
|
||||
const char* region, const rect_t* dst,
|
||||
image_draw_type_t draw_type);
|
||||
|
||||
widget_t* widget_find_by_path(widget_t* widget, const char* path, bool_t recursive);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_WIDGET_H*/
|
||||
|
@ -31,54 +31,6 @@
|
||||
#include "file_browser/file_dialog.h"
|
||||
#include "ui_loader/ui_builder_default.h"
|
||||
|
||||
static widget_t* find_target_widget(widget_t* widget, const char* path, uint32_t len,
|
||||
bool_t recursive) {
|
||||
bool_t is_first = TRUE;
|
||||
tokenizer_t tokenizer;
|
||||
widget_t* iter = widget;
|
||||
tokenizer_t* t = NULL;
|
||||
return_value_if_fail(widget != NULL && path != NULL, NULL);
|
||||
if (strchr(path, '.') == NULL) {
|
||||
const char* name = path;
|
||||
if (tk_str_eq(name, STR_PROP_PARENT)) {
|
||||
return widget->parent;
|
||||
} else if (tk_str_eq(name, STR_PROP_SELF)) {
|
||||
return widget;
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW)) {
|
||||
return widget_get_window(widget);
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) {
|
||||
return widget_get_window_manager(widget);
|
||||
} else {
|
||||
return widget_lookup(widget, name, recursive);
|
||||
}
|
||||
}
|
||||
t = tokenizer_init(&tokenizer, path, len, ".");
|
||||
return_value_if_fail(t != NULL, NULL);
|
||||
|
||||
while (tokenizer_has_more(t) && iter != NULL) {
|
||||
const char* name = tokenizer_next(t);
|
||||
if (is_first) {
|
||||
if (tk_str_eq(name, STR_PROP_PARENT)) {
|
||||
iter = widget->parent;
|
||||
} else if (tk_str_eq(name, STR_PROP_SELF)) {
|
||||
iter = widget;
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW)) {
|
||||
iter = widget_get_window(widget);
|
||||
} else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) {
|
||||
iter = widget_get_window_manager(widget);
|
||||
} else {
|
||||
iter = widget_child(iter, name);
|
||||
}
|
||||
is_first = FALSE;
|
||||
} else {
|
||||
iter = widget_child(iter, name);
|
||||
}
|
||||
}
|
||||
tokenizer_deinit(t);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
static widget_t* to_widget(fscript_t* fscript, const value_t* v) {
|
||||
widget_t* widget = NULL;
|
||||
if (v->type == VALUE_TYPE_STRING) {
|
||||
@ -86,9 +38,9 @@ static widget_t* to_widget(fscript_t* fscript, const value_t* v) {
|
||||
const char* path = value_str(v);
|
||||
return_value_if_fail(path != NULL, NULL);
|
||||
|
||||
widget = find_target_widget(self, path, strlen(path), TRUE);
|
||||
widget = widget_find_by_path(self, path, TRUE);
|
||||
if (widget == NULL) {
|
||||
widget = find_target_widget(widget_get_window(self), path, strlen(path), TRUE);
|
||||
widget = widget_find_by_path(widget_get_window(self), path, TRUE);
|
||||
}
|
||||
|
||||
return widget;
|
||||
@ -189,7 +141,10 @@ static ret_t widget_set(widget_t* self, const char* path, const value_t* v) {
|
||||
widget_t* widget = self;
|
||||
const char* prop = strrchr(path, '.');
|
||||
if (prop != NULL) {
|
||||
widget = find_target_widget(self, path, prop - path, TRUE);
|
||||
char name[MAX_PATH+1] = {0};
|
||||
int32_t len = tk_min_int(prop - path, MAX_PATH);
|
||||
tk_strncpy(name, path, len);
|
||||
widget = widget_find_by_path(self, name, TRUE);
|
||||
prop++;
|
||||
} else {
|
||||
prop = path;
|
||||
@ -204,7 +159,10 @@ static ret_t widget_get(widget_t* self, const char* path, value_t* v) {
|
||||
widget_t* widget = self;
|
||||
const char* prop = strrchr(path, '.');
|
||||
if (prop != NULL) {
|
||||
widget = find_target_widget(self, path, prop - path, TRUE);
|
||||
char name[MAX_PATH+1] = {0};
|
||||
int32_t len = tk_min_int(prop - path, MAX_PATH);
|
||||
tk_strncpy(name, path, len);
|
||||
widget = widget_find_by_path(self, name, TRUE);
|
||||
prop++;
|
||||
} else {
|
||||
prop = path;
|
||||
@ -286,7 +244,7 @@ static ret_t func_widget_lookup(fscript_t* fscript, fscript_args_t* args, value_
|
||||
}
|
||||
|
||||
FSCRIPT_FUNC_CHECK(widget != NULL && path != NULL, RET_BAD_PARAMS);
|
||||
widget = find_target_widget(widget, path, strlen(path), recursive);
|
||||
widget = widget_find_by_path(widget, path, recursive);
|
||||
if (widget == NULL) {
|
||||
result->type = VALUE_TYPE_INVALID;
|
||||
return RET_NOT_FOUND;
|
||||
|
2
src/remote_ui/README.md
Normal file
2
src/remote_ui/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# 自动化测试框架
|
||||
|
609
src/remote_ui/client/remote_ui.c
Normal file
609
src/remote_ui/client/remote_ui.c
Normal file
@ -0,0 +1,609 @@
|
||||
/**
|
||||
* File: remote_ui.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: remote ui client
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/crc.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "base/keys.h"
|
||||
#include "base/events.h"
|
||||
#include "conf_io/conf_ubjson.h"
|
||||
#include "tkc/object_default.h"
|
||||
|
||||
#include "remote_ui/client/remote_ui.h"
|
||||
#include "remote_ui/shared/remote_ui_types_def.h"
|
||||
|
||||
#define REMOTE_UI_ISTREAM_TIMEOUT 100 * 1000
|
||||
|
||||
remote_ui_t* remote_ui_create(tk_iostream_t* io) {
|
||||
remote_ui_t* ui = NULL;
|
||||
return_value_if_fail(io != NULL, NULL);
|
||||
|
||||
ui = (remote_ui_t*)TKMEM_ZALLOC(remote_ui_t);
|
||||
return_value_if_fail(ui != NULL, NULL);
|
||||
|
||||
ui->io = io;
|
||||
ui->event_handlers = object_default_create_ex(FALSE);
|
||||
wbuffer_init_extendable(&(ui->wb));
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_send_req(tk_iostream_t* io, uint32_t type, uint32_t data_type,
|
||||
wbuffer_t* wb) {
|
||||
int32_t ret = 0;
|
||||
const void* data = NULL;
|
||||
uint32_t size = 0;
|
||||
uint32_t timeout = TK_OSTREAM_DEFAULT_TIMEOUT;
|
||||
uint16_t crc_value = PPPINITFCS16;
|
||||
remote_ui_msg_header_t header;
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
return_value_if_fail(io != NULL && wb != NULL, RET_BAD_PARAMS);
|
||||
|
||||
size = wb->cursor;
|
||||
data = wb->data;
|
||||
if (size > 0) {
|
||||
return_value_if_fail(data != NULL, RET_BAD_PARAMS);
|
||||
}
|
||||
|
||||
header.type = type;
|
||||
header.size = size;
|
||||
header.data_type = data_type;
|
||||
|
||||
crc_value = tk_crc16(crc_value, &header, sizeof(header));
|
||||
if (data != NULL && size > 0) {
|
||||
crc_value = tk_crc16(crc_value, data, size);
|
||||
}
|
||||
ret = tk_iostream_write_len(io, &header, sizeof(header), timeout);
|
||||
return_value_if_fail(ret == sizeof(header), RET_IO);
|
||||
|
||||
if (size > 0) {
|
||||
timeout = TK_OSTREAM_DEFAULT_TIMEOUT * (size / 10240) + TK_OSTREAM_DEFAULT_TIMEOUT;
|
||||
ret = tk_iostream_write_len(io, data, size, timeout);
|
||||
return_value_if_fail(ret == size, RET_IO);
|
||||
}
|
||||
|
||||
ret = tk_iostream_write_len(io, &crc_value, sizeof(crc_value), TK_OSTREAM_DEFAULT_TIMEOUT);
|
||||
return_value_if_fail(ret == sizeof(crc_value), RET_IO);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_read_resp(tk_iostream_t* io, remote_ui_msg_header_t* header, wbuffer_t* wb) {
|
||||
int32_t ret = 0;
|
||||
uint16_t crc_value = 0;
|
||||
uint16_t real_crc_value = PPPINITFCS16;
|
||||
return_value_if_fail(io != NULL && header != NULL && wb != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(wb);
|
||||
ret = tk_iostream_read_len(io, header, sizeof(*header), REMOTE_UI_ISTREAM_TIMEOUT);
|
||||
return_value_if_fail(ret == sizeof(*header), RET_IO);
|
||||
|
||||
real_crc_value = tk_crc16(real_crc_value, header, sizeof(*header));
|
||||
if (header->size > 0) {
|
||||
return_value_if_fail(wbuffer_extend_capacity(wb, header->size) == RET_OK, RET_OOM);
|
||||
ret = tk_iostream_read_len(io, wb->data, header->size, REMOTE_UI_ISTREAM_TIMEOUT);
|
||||
return_value_if_fail(ret == header->size, RET_IO);
|
||||
real_crc_value = tk_crc16(real_crc_value, wb->data, header->size);
|
||||
}
|
||||
|
||||
ret = tk_iostream_read_len(io, &crc_value, sizeof(crc_value), REMOTE_UI_ISTREAM_TIMEOUT);
|
||||
return_value_if_fail(ret == sizeof(crc_value), RET_IO);
|
||||
return_value_if_fail(real_crc_value == crc_value, RET_CRC);
|
||||
|
||||
wb->cursor = header->size;
|
||||
|
||||
return header->resp_code;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_request(tk_iostream_t* io, uint32_t type, uint32_t data_type,
|
||||
wbuffer_t* wb) {
|
||||
ret_t ret = remote_ui_send_req(io, type, data_type, wb);
|
||||
if (ret == RET_OK) {
|
||||
remote_ui_msg_header_t header;
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
ret = remote_ui_read_resp(io, &header, wb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ubjson_writer_t* remote_ui_client_get_writer(remote_ui_t* ui) {
|
||||
wbuffer_t* wb = &(ui->wb);
|
||||
ubjson_writer_t* writer = &(ui->writer);
|
||||
|
||||
wb->cursor = 0;
|
||||
return ubjson_writer_init(writer, (ubjson_write_callback_t)wbuffer_write_binary, wb);
|
||||
}
|
||||
|
||||
ret_t remote_ui_login(remote_ui_t* ui, const char* username, const char* password) {
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(username != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(password != NULL, RET_BAD_PARAMS);
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_USERNAME, username);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_PASSWORD, password);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_LOGIN, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_logout(remote_ui_t* ui) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_LOGOUT, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_get_dev_info(remote_ui_t* ui, remote_ui_dev_info_t* info) {
|
||||
ret_t ret = RET_FAIL;
|
||||
wbuffer_t* wb = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(info != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wb = &(ui->wb);
|
||||
wbuffer_rewind(wb);
|
||||
memset(info, 0x00, sizeof(*info));
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_GET_DEV_INFO, REMOTE_UI_DATA_TYPE_UBJSON, wb);
|
||||
if (ret == RET_OK) {
|
||||
tk_object_t* obj = conf_ubjson_load_from_buff(wb->data, wb->cursor, FALSE);
|
||||
if (obj != NULL) {
|
||||
const char* p = NULL;
|
||||
p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_NAME);
|
||||
if (p != NULL) {
|
||||
tk_strncpy(info->name, p, sizeof(info->name) - 1);
|
||||
}
|
||||
|
||||
p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_VERSION);
|
||||
if (p != NULL) {
|
||||
tk_strncpy(info->version, p, sizeof(info->version) - 1);
|
||||
}
|
||||
|
||||
p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_OS);
|
||||
if (p != NULL) {
|
||||
tk_strncpy(info->os, p, sizeof(info->os) - 1);
|
||||
}
|
||||
|
||||
p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_ARCH);
|
||||
if (p != NULL) {
|
||||
tk_strncpy(info->arch, p, sizeof(info->arch) - 1);
|
||||
}
|
||||
|
||||
info->screen_width = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_SCREEN_WIDTH, 0);
|
||||
info->screen_height = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_SCREEN_HEIGHT, 0);
|
||||
info->dpi = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_DPI, 0);
|
||||
|
||||
TK_OBJECT_UNREF(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_reboot(remote_ui_t* ui, remote_ui_reboot_type_t reboot_type) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_int32(&(ui->wb), reboot_type);
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_REBOOT, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_upload_file(remote_ui_t* ui, const char* remote_file, const char* local_file) {
|
||||
wbuffer_t wb;
|
||||
int32_t len = 0;
|
||||
ret_t ret = RET_OK;
|
||||
fs_file_t* file = NULL;
|
||||
uint8_t buff[4096] = {0};
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(local_file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
file = fs_open_file(os_fs(), local_file, "rb");
|
||||
return_value_if_fail(file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_init(&wb, (void*)remote_file, strlen(remote_file) + 1);
|
||||
wb.cursor = wb.capacity;
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_STRING, &wb);
|
||||
goto_error_if_fail(ret == RET_OK);
|
||||
|
||||
while ((len = fs_file_read(file, buff, sizeof(buff))) > 0) {
|
||||
wbuffer_init(&wb, buff, len);
|
||||
wb.cursor = len;
|
||||
ret =
|
||||
remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_DATA, REMOTE_UI_DATA_TYPE_BINARY, &wb);
|
||||
break_if_fail(ret == RET_OK);
|
||||
}
|
||||
|
||||
wbuffer_rewind(&wb);
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_END, REMOTE_UI_DATA_TYPE_NONE, &wb);
|
||||
|
||||
fs_file_close(file);
|
||||
|
||||
return ret;
|
||||
error:
|
||||
fs_file_close(file);
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t remote_ui_download_file(remote_ui_t* ui, const char* remote_file, const char* local_file) {
|
||||
int32_t len = 0;
|
||||
ret_t ret = RET_OK;
|
||||
fs_file_t* file = NULL;
|
||||
wbuffer_t* wb = NULL;
|
||||
remote_ui_msg_header_t header;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(local_file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
file = fs_open_file(os_fs(), local_file, "wb+");
|
||||
return_value_if_fail(file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wb = &(ui->wb);
|
||||
wbuffer_rewind(wb);
|
||||
wbuffer_write_string(wb, remote_file);
|
||||
ret =
|
||||
remote_ui_request(ui->io, REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_STRING, wb);
|
||||
goto_error_if_fail(ret == RET_OK);
|
||||
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
|
||||
while ((ret = remote_ui_read_resp(ui->io, &header, wb)) == RET_OK) {
|
||||
if (header.type == REMOTE_UI_RESP_DOWNLOAD_FILE_DATA) {
|
||||
len = fs_file_write(file, wb->data, wb->cursor);
|
||||
break_if_fail(len == wb->cursor);
|
||||
} else if (header.type == REMOTE_UI_RESP_DOWNLOAD_FILE_END) {
|
||||
ret = RET_OK;
|
||||
break;
|
||||
} else {
|
||||
assert(!"impossible");
|
||||
ret = RET_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fs_file_close(file);
|
||||
|
||||
return ret;
|
||||
error:
|
||||
fs_file_close(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_create_dir(remote_ui_t* ui, const char* remote_dir) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(remote_dir != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), remote_dir);
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_CREATE_DIR, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_remove_dir(remote_ui_t* ui, const char* remote_dir) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(remote_dir != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), remote_dir);
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_REMOVE_DIR, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_remove_file(remote_ui_t* ui, const char* remote_file) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), remote_file);
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_REMOVE_FILE, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_take_screen_shot(remote_ui_t* ui, const char* file) {
|
||||
return remote_ui_download_file(ui, REMOTE_UI_FILE_SCREEN_SHOT, file);
|
||||
}
|
||||
|
||||
ret_t remote_ui_get_manifest(remote_ui_t* ui, const char* file) {
|
||||
return remote_ui_download_file(ui, REMOTE_UI_FILE_MANIFEST, file);
|
||||
}
|
||||
|
||||
ret_t remote_ui_get_xml_source(remote_ui_t* ui, const char* file) {
|
||||
return remote_ui_download_file(ui, REMOTE_UI_FILE_XML_SOURCE, file);
|
||||
}
|
||||
|
||||
ret_t remote_ui_on_event(remote_ui_t* ui, const char* target, uint32_t event, event_func_t func,
|
||||
void* ctx) {
|
||||
emitter_t* emitter = NULL;
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->event_handlers != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(target != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(func != NULL, RET_BAD_PARAMS);
|
||||
|
||||
emitter = tk_object_get_prop_pointer(ui->event_handlers, target);
|
||||
if (emitter == NULL) {
|
||||
emitter = emitter_create();
|
||||
return_value_if_fail(emitter != NULL, RET_OOM);
|
||||
tk_object_set_prop_pointer_ex(ui->event_handlers, target, emitter,
|
||||
(tk_destroy_t)emitter_destroy);
|
||||
}
|
||||
emitter_on(emitter, event, func, ctx);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_ON_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_off_event(remote_ui_t* ui, const char* target, uint32_t event) {
|
||||
emitter_t* emitter = NULL;
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->event_handlers != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(target != NULL, RET_BAD_PARAMS);
|
||||
|
||||
emitter = tk_object_get_prop_pointer(ui->event_handlers, target);
|
||||
if (emitter != NULL) {
|
||||
emitter_off(emitter, event);
|
||||
}
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_OFF_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_send_event(remote_ui_t* ui, const char* target, event_t* event) {
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(target != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(event != NULL, RET_BAD_PARAMS);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event->type);
|
||||
switch (event->type) {
|
||||
case EVT_CLICK:
|
||||
case EVT_POINTER_DOWN:
|
||||
case EVT_POINTER_UP:
|
||||
case EVT_POINTER_MOVE: {
|
||||
pointer_event_t* e = (pointer_event_t*)event;
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_X, e->x);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_Y, e->y);
|
||||
break;
|
||||
}
|
||||
case EVT_KEY_DOWN:
|
||||
case EVT_KEY_UP: {
|
||||
key_event_t* e = (key_event_t*)event;
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_CODE, e->key);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
log_debug("not supported event type:%d\n", event->type);
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
}
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_SEND_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_open_window(remote_ui_t* ui, const char* name, const char* xml,
|
||||
const char* init_json) {
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL, RET_BAD_PARAMS);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name);
|
||||
if (xml != NULL) {
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_XML, xml);
|
||||
}
|
||||
if (init_json != NULL) {
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_INIT, init_json);
|
||||
}
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_OPEN_WINDOW, REMOTE_UI_DATA_TYPE_UBJSON,
|
||||
&(ui->wb));
|
||||
}
|
||||
|
||||
static ret_t remote_ui_show_dialog(remote_ui_t* ui, const char* type, const char* title,
|
||||
const char* content, uint32_t duration) {
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(type != NULL, RET_BAD_PARAMS);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TYPE, type);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TITLE, title);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_CONTENT, content);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DURATION, duration);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_OPEN_DIALOG, REMOTE_UI_DATA_TYPE_UBJSON,
|
||||
&(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_show_confirm(remote_ui_t* ui, const char* title, const char* content) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(title != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(content != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_CONFIRM, title, content, 0);
|
||||
}
|
||||
|
||||
ret_t remote_ui_show_warn(remote_ui_t* ui, const char* title, const char* content) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(title != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(content != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_WARN, title, content, 0);
|
||||
}
|
||||
|
||||
ret_t remote_ui_show_info(remote_ui_t* ui, const char* title, const char* content) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(title != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(content != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return remote_ui_show_dialog(ui, NULL, title, content, 0);
|
||||
}
|
||||
|
||||
ret_t remote_ui_show_toast(remote_ui_t* ui, uint32_t duration, const char* content) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(content != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_TOAST, "", content, duration);
|
||||
}
|
||||
|
||||
ret_t remote_ui_close_window(remote_ui_t* ui, const char* name) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), name);
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_CLOSE_WINDOW, REMOTE_UI_DATA_TYPE_STRING,
|
||||
&(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_back_to_prev(remote_ui_t* ui) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_BACK_TO_PREV, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_back_to_home(remote_ui_t* ui) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_BACK_TO_HOME, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_set_prop(remote_ui_t* ui, const char* target, const char* name,
|
||||
const value_t* value) {
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(target != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(value != NULL, RET_BAD_PARAMS);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name);
|
||||
ubjson_writer_write_kv_value(writer, REMOTE_UI_KEY_VALUE, value);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_PROP, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_get_prop(remote_ui_t* ui, const char* target, const char* name, value_t* value) {
|
||||
ret_t ret = RET_OK;
|
||||
ubjson_writer_t* writer = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(target != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(name != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(value != NULL, RET_BAD_PARAMS);
|
||||
|
||||
writer = remote_ui_client_get_writer(ui);
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name);
|
||||
ubjson_writer_write_kv_value(writer, REMOTE_UI_KEY_VALUE, value);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
ret = remote_ui_request(ui->io, REMOTE_UI_REQ_GET_PROP, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb));
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
|
||||
value_dup_str_with_len(value, (char*)(ui->wb.data), ui->wb.cursor);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t remote_ui_set_theme(remote_ui_t* ui, const char* theme) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(theme != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), theme);
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_THEME, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_set_language(remote_ui_t* ui, const char* language) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(language != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), language);
|
||||
return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_LANGUAGE, REMOTE_UI_DATA_TYPE_STRING,
|
||||
&(ui->wb));
|
||||
}
|
||||
|
||||
ret_t remote_ui_exec_fscript(remote_ui_t* ui, const char* script, str_t* str) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(script != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(&(ui->wb));
|
||||
wbuffer_write_string(&(ui->wb), script);
|
||||
ret =
|
||||
remote_ui_request(ui->io, REMOTE_UI_REQ_EXEC_FSCRIPT, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb));
|
||||
if (ret == RET_OK) {
|
||||
str_set_with_len(str, (char*)(ui->wb.data), ui->wb.cursor);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t remote_ui_dispatch(remote_ui_t* ui) {
|
||||
/*TODO*/
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t remote_ui_destroy(remote_ui_t* ui) {
|
||||
return_value_if_fail(ui != NULL, RET_BAD_PARAMS);
|
||||
|
||||
TK_OBJECT_UNREF(ui->io);
|
||||
TK_OBJECT_UNREF(ui->event_handlers);
|
||||
wbuffer_deinit(&(ui->wb));
|
||||
TKMEM_FREE(ui);
|
||||
|
||||
return RET_OK;
|
||||
}
|
398
src/remote_ui/client/remote_ui.h
Normal file
398
src/remote_ui/client/remote_ui.h
Normal file
@ -0,0 +1,398 @@
|
||||
/**
|
||||
* File: remote_ui.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: remote ui client
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_REMOTE_UI_H
|
||||
#define TK_REMOTE_UI_H
|
||||
|
||||
#include "tkc/buffer.h"
|
||||
#include "tkc/darray.h"
|
||||
#include "tkc/iostream.h"
|
||||
#include "ubjson/ubjson_writer.h"
|
||||
#include "remote_ui/shared/remote_ui_types_def.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class remote_ui_t
|
||||
* remote ui客户端。
|
||||
*/
|
||||
typedef struct _remote_ui_t {
|
||||
/**
|
||||
* @property {tk_iostream_t*} io
|
||||
* @annotation ["readable"]
|
||||
* IO stream。
|
||||
*/
|
||||
tk_iostream_t* io;
|
||||
|
||||
/*private*/
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t writer;
|
||||
tk_object_t* event_handlers;
|
||||
} remote_ui_t;
|
||||
|
||||
/**
|
||||
* @method remote_ui_create
|
||||
* 创建remote ui客户端。
|
||||
*
|
||||
* @param {tk_iostream_t*} io IO流。
|
||||
*
|
||||
* @return {remote_ui_t*} 返回remote ui客户端对象。
|
||||
*/
|
||||
remote_ui_t* remote_ui_create(tk_iostream_t* io);
|
||||
|
||||
/**
|
||||
* @method remote_ui_login
|
||||
* 登录。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} username 用户名。
|
||||
* @param {const char*} password 密码。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_login(remote_ui_t* ui, const char* username, const char* password);
|
||||
|
||||
/**
|
||||
* @method remote_ui_logout
|
||||
* 登出。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_logout(remote_ui_t* ui);
|
||||
|
||||
/**
|
||||
* @method remote_ui_get_dev_info
|
||||
* 获取设备信息。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {remote_ui_dev_info_t*} info 设备信息。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_get_dev_info(remote_ui_t* ui, remote_ui_dev_info_t* info);
|
||||
|
||||
/**
|
||||
* @method remote_ui_reboot
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* 重新启动。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_reboot(remote_ui_t* ui, remote_ui_reboot_type_t type);
|
||||
|
||||
/**
|
||||
* @method remote_ui_upload_file
|
||||
* 上传文件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} remote_file 远程文件。
|
||||
* @param {const char*} local_file 本地文件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_upload_file(remote_ui_t* ui, const char* remote_file, const char* local_file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_download_file
|
||||
* 下载文件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} remote_file 远程文件。
|
||||
* @param {const char*} local_file 本地文件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_download_file(remote_ui_t* ui, const char* remote_file, const char* local_file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_create_dir
|
||||
* 创建目录。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} remote_dir 远程目录。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_create_dir(remote_ui_t* ui, const char* remote_dir);
|
||||
|
||||
/**
|
||||
* @method remote_ui_remove_dir
|
||||
* 删除目录。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} remote_dir 远程目录。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_remove_dir(remote_ui_t* ui, const char* remote_dir);
|
||||
|
||||
/**
|
||||
* @method remote_ui_remove_file
|
||||
* 删除文件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} remote_file 远程文件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_remove_file(remote_ui_t* ui, const char* remote_file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_take_screen_shot
|
||||
* 截屏。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} file 文件名。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_take_screen_shot(remote_ui_t* ui, const char* file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_get_manifest
|
||||
* 获取manifest。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} file 文件名。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_get_manifest(remote_ui_t* ui, const char* file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_get_xml_source
|
||||
* 获取当前窗口的XML源码。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} file 文件名。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_get_xml_source(remote_ui_t* ui, const char* file);
|
||||
|
||||
/**
|
||||
* @method remote_ui_on_event
|
||||
* 注册事件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} target 目标。
|
||||
* @param {uint32_t} event 事件。
|
||||
* @param {event_func_t} func 事件处理函数。
|
||||
* @param {void*} ctx 上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_on_event(remote_ui_t* ui, const char* target, uint32_t event, event_func_t func,
|
||||
void* ctx);
|
||||
|
||||
/**
|
||||
* @method remote_ui_off_event
|
||||
* 注销事件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} target 目标。
|
||||
* @param {uint32_t} event 事件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_off_event(remote_ui_t* ui, const char* target, uint32_t event);
|
||||
|
||||
/**
|
||||
* @method remote_ui_send_event
|
||||
* 发送事件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} target 目标。
|
||||
* @param {event_t*} event 事件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_send_event(remote_ui_t* ui, const char* target, event_t* event);
|
||||
|
||||
/**
|
||||
* @method remote_ui_open_window
|
||||
* 打开窗口。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} name 窗口名称。
|
||||
* @param {const char*} xml 窗口XML。
|
||||
* @param {const char*} init_json 初始化JSON。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_open_window(remote_ui_t* ui, const char* name, const char* xml,
|
||||
const char* init_json);
|
||||
|
||||
/**
|
||||
* @method remote_ui_show_confirm
|
||||
* 显示确认对话框。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} title 标题。
|
||||
* @param {const char*} content 内容。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_show_confirm(remote_ui_t* ui, const char* title,
|
||||
const char* content);
|
||||
/**
|
||||
* @method remote_ui_show_warn
|
||||
* 显示警告对话框。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} title 标题。
|
||||
* @param {const char*} content 内容。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_show_warn(remote_ui_t* ui, const char* title,
|
||||
const char* content);
|
||||
|
||||
/**
|
||||
* @method remote_ui_show_info
|
||||
* 显示信息对话框。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} title 标题。
|
||||
* @param {const char*} content 内容。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_show_info(remote_ui_t* ui, const char* title,
|
||||
const char* content);
|
||||
/**
|
||||
* @method remote_ui_show_toast
|
||||
* 显示信息对话框。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {uint32_t} duration 时长。
|
||||
* @param {const char*} content 内容。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_show_toast(remote_ui_t* ui, uint32_t duration,
|
||||
const char* content);
|
||||
/**
|
||||
* @method remote_ui_close_window
|
||||
* 关闭窗口。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} name 窗口名称。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_close_window(remote_ui_t* ui, const char* name);
|
||||
|
||||
/**
|
||||
* @method remote_ui_back_to_prev
|
||||
* 返回上一个窗口。
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_back_to_prev(remote_ui_t* ui);
|
||||
|
||||
/**
|
||||
* @method remote_ui_back_to_home
|
||||
* 返回主窗口。
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_back_to_home(remote_ui_t* ui);
|
||||
|
||||
/**
|
||||
* @method remote_ui_set_prop
|
||||
* 设置属性。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} target 目标。
|
||||
* @param {const char*} name 属性名称。
|
||||
* @param {const value_t*} value 属性值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_set_prop(remote_ui_t* ui, const char* target, const char* name,
|
||||
const value_t* value);
|
||||
|
||||
/**
|
||||
* @method remote_ui_get_prop
|
||||
* 获取属性。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} target 目标。
|
||||
* @param {const char*} name 属性名称。
|
||||
* @param {value_t*} value 属性值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_get_prop(remote_ui_t* ui, const char* target, const char* name, value_t* value);
|
||||
|
||||
/**
|
||||
* @method remote_ui_set_theme
|
||||
* 设置主题。
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} theme 主题名称。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_set_theme(remote_ui_t* ui, const char* theme);
|
||||
|
||||
/**
|
||||
* @method remote_ui_set_language
|
||||
* 设置语言。
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} language 语言名称。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_set_language(remote_ui_t* ui, const char* language);
|
||||
|
||||
/**
|
||||
* @method remote_ui_exec_fscript
|
||||
* 执行fscript脚本。
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
* @param {const char*} script 脚本。
|
||||
* @param {str_t*} result 执行结果。
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_exec_fscript(remote_ui_t* ui, const char* script, str_t* result);
|
||||
|
||||
/**
|
||||
* @method remote_ui_dispatch
|
||||
* 分发事件。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_dispatch(remote_ui_t* ui);
|
||||
|
||||
/**
|
||||
* @method remote_ui_destroy
|
||||
* 销毁remote ui客户端。
|
||||
*
|
||||
* @param {remote_ui_t*} ui remote ui客户端对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t remote_ui_destroy(remote_ui_t* ui);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_REMOTE_UI_H*/
|
816
src/remote_ui/service/remote_ui_service.c
Normal file
816
src/remote_ui/service/remote_ui_service.c
Normal file
@ -0,0 +1,816 @@
|
||||
/**
|
||||
* File: remote_ui_service.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: remote ui service
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc/fs.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/crc.h"
|
||||
#include "tkc/path.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "tkc/fscript.h"
|
||||
#include "base/bitmap.h"
|
||||
#include "base/window.h"
|
||||
#include "base/window_manager.h"
|
||||
#include "base/ui_loader.h"
|
||||
#include "base/dialog.h"
|
||||
#include "conf_io/conf_ubjson.h"
|
||||
#include "tkc/object_default.h"
|
||||
#include "ui_loader/ui_serializer.h"
|
||||
#include "remote_ui/shared/remote_ui_types_def.h"
|
||||
#include "remote_ui/service/remote_ui_service.h"
|
||||
|
||||
#include "base/events.h"
|
||||
#include "base/keys.h"
|
||||
|
||||
static ret_t remote_ui_service_dispatch(remote_ui_service_t* ui);
|
||||
static ret_t remote_ui_service_destroy(remote_ui_service_t* ui);
|
||||
|
||||
tk_service_t* remote_ui_service_create(tk_iostream_t* io, void* args) {
|
||||
remote_ui_service_t* ui = NULL;
|
||||
remote_ui_service_args_t* service_args = (remote_ui_service_args_t*)args;
|
||||
|
||||
return_value_if_fail(io != NULL, NULL);
|
||||
|
||||
ui = (remote_ui_service_t*)TKMEM_ZALLOC(remote_ui_service_t);
|
||||
return_value_if_fail(ui != NULL, NULL);
|
||||
|
||||
ui->io = io;
|
||||
ui->service.dispatch = (tk_service_dispatch_t)remote_ui_service_dispatch;
|
||||
ui->service.destroy = (tk_service_destroy_t)remote_ui_service_destroy;
|
||||
|
||||
wbuffer_init_extendable(&(ui->wb));
|
||||
if (service_args != NULL && service_args->auth != NULL) {
|
||||
ui->auth = service_args->auth;
|
||||
}
|
||||
|
||||
return (tk_service_t*)ui;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_send_resp(tk_iostream_t* io, uint32_t type, uint32_t data_type,
|
||||
uint32_t resp_code, wbuffer_t* wb) {
|
||||
int32_t ret = 0;
|
||||
uint32_t size = 0;
|
||||
const void* data = NULL;
|
||||
remote_ui_msg_header_t header;
|
||||
uint16_t crc_value = PPPINITFCS16;
|
||||
uint32_t timeout = TK_OSTREAM_DEFAULT_TIMEOUT;
|
||||
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
return_value_if_fail(io != NULL && wb != NULL, RET_BAD_PARAMS);
|
||||
|
||||
data = wb->data;
|
||||
size = wb->cursor;
|
||||
if (size > 0) {
|
||||
return_value_if_fail(data != NULL, RET_BAD_PARAMS);
|
||||
}
|
||||
|
||||
header.type = type;
|
||||
header.size = size;
|
||||
header.data_type = data_type;
|
||||
header.resp_code = resp_code;
|
||||
|
||||
crc_value = tk_crc16(crc_value, &header, sizeof(header));
|
||||
if (data != NULL && size > 0) {
|
||||
crc_value = tk_crc16(crc_value, data, size);
|
||||
}
|
||||
|
||||
ret = tk_iostream_write_len(io, &header, sizeof(header), timeout);
|
||||
return_value_if_fail(ret == sizeof(header), RET_IO);
|
||||
|
||||
if (size > 0) {
|
||||
timeout = TK_OSTREAM_DEFAULT_TIMEOUT * (size / 10240) + TK_OSTREAM_DEFAULT_TIMEOUT;
|
||||
ret = tk_iostream_write_len(io, data, size, timeout);
|
||||
return_value_if_fail(ret == size, RET_IO);
|
||||
}
|
||||
|
||||
ret = tk_iostream_write_len(io, &crc_value, sizeof(crc_value), TK_OSTREAM_DEFAULT_TIMEOUT);
|
||||
return_value_if_fail(ret == sizeof(crc_value), RET_IO);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_read_req(tk_iostream_t* io, remote_ui_msg_header_t* header,
|
||||
wbuffer_t* wb) {
|
||||
int32_t ret = 0;
|
||||
uint16_t crc_value = 0;
|
||||
uint16_t real_crc_value = PPPINITFCS16;
|
||||
return_value_if_fail(io != NULL && header != NULL && wb != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_rewind(wb);
|
||||
ret = tk_iostream_read_len(io, header, sizeof(*header), TK_ISTREAM_DEFAULT_TIMEOUT);
|
||||
if (ret == 0) {
|
||||
return RET_IO;
|
||||
}
|
||||
return_value_if_fail(ret == sizeof(*header), RET_IO);
|
||||
|
||||
real_crc_value = tk_crc16(real_crc_value, header, sizeof(*header));
|
||||
if (header->size > 0) {
|
||||
return_value_if_fail(wbuffer_extend_capacity(wb, header->size) == RET_OK, RET_OOM);
|
||||
ret = tk_iostream_read_len(io, wb->data, header->size, TK_ISTREAM_DEFAULT_TIMEOUT);
|
||||
return_value_if_fail(ret == header->size, RET_IO);
|
||||
real_crc_value = tk_crc16(real_crc_value, wb->data, header->size);
|
||||
}
|
||||
|
||||
ret = tk_iostream_read_len(io, &crc_value, sizeof(crc_value), TK_ISTREAM_DEFAULT_TIMEOUT);
|
||||
return_value_if_fail(ret == sizeof(crc_value), RET_IO);
|
||||
return_value_if_fail(crc_value == real_crc_value, RET_CRC);
|
||||
|
||||
wb->cursor = header->size;
|
||||
|
||||
return header->resp_code;
|
||||
}
|
||||
|
||||
static ubjson_writer_t* remote_ui_service_get_writer(remote_ui_service_t* ui) {
|
||||
wbuffer_t* wb = &(ui->wb);
|
||||
ubjson_writer_t* writer = &(ui->writer);
|
||||
|
||||
wb->cursor = 0;
|
||||
return ubjson_writer_init(writer, (ubjson_write_callback_t)wbuffer_write_binary, wb);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_login(remote_ui_service_t* ui, const char* username, const char* password) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
if (ui->auth != NULL) {
|
||||
if (ui->auth((tk_service_t*)ui, username, password) == RET_OK) {
|
||||
ui->is_login = TRUE;
|
||||
return RET_OK;
|
||||
} else {
|
||||
return RET_FAIL;
|
||||
}
|
||||
} else {
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_logout(remote_ui_service_t* ui) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
ui->is_login = FALSE;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_get_dev_info(remote_ui_service_t* ui, remote_ui_dev_info_t* info) {
|
||||
ret_t ret = RET_OK;
|
||||
widget_t* wm = window_manager();
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(info != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(info, 0x00, sizeof(*info));
|
||||
info->screen_width = wm->w;
|
||||
info->screen_height = wm->h;
|
||||
/*TODO*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_reboot(remote_ui_service_t* ui, remote_ui_reboot_type_t reboot_type) {
|
||||
/*TODO*/
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_upload_file(remote_ui_service_t* ui, const char* filename) {
|
||||
int32_t len = 0;
|
||||
ret_t ret = RET_OK;
|
||||
fs_file_t* file = NULL;
|
||||
wbuffer_t* wb = NULL;
|
||||
remote_ui_msg_header_t header;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wb = &(ui->wb);
|
||||
wbuffer_rewind(wb);
|
||||
file = fs_open_file(os_fs(), filename, "wb+");
|
||||
if (file != NULL) {
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_NONE,
|
||||
RET_OK, wb);
|
||||
} else {
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_NONE,
|
||||
RET_FAIL, wb);
|
||||
}
|
||||
return_value_if_fail(file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
while ((ret = remote_ui_service_read_req(ui->io, &header, wb)) == RET_OK) {
|
||||
if (header.type == REMOTE_UI_REQ_UPLOAD_FILE_DATA) {
|
||||
len = fs_file_write(file, wb->data, wb->cursor);
|
||||
ret = (len == wb->cursor) ? RET_OK : RET_FAIL;
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_DATA, REMOTE_UI_DATA_TYPE_NONE,
|
||||
ret, wb);
|
||||
break_if_fail(ret == RET_OK);
|
||||
} else if (header.type == REMOTE_UI_REQ_UPLOAD_FILE_END) {
|
||||
ret = RET_OK;
|
||||
ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_END,
|
||||
REMOTE_UI_DATA_TYPE_NONE, ret, wb);
|
||||
break_if_fail(ret == RET_OK);
|
||||
break;
|
||||
} else {
|
||||
assert(!"impossible");
|
||||
ret = RET_FAIL;
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_END, REMOTE_UI_DATA_TYPE_NONE,
|
||||
ret, wb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fs_file_close(file);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_download_file(remote_ui_service_t* ui, const char* filename) {
|
||||
wbuffer_t wb;
|
||||
int32_t len = 0;
|
||||
ret_t ret = RET_OK;
|
||||
fs_file_t* file = NULL;
|
||||
uint8_t buff[4096] = {0};
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_init(&wb, buff, sizeof(buff));
|
||||
file = fs_open_file(os_fs(), filename, "rb");
|
||||
if (file != NULL) {
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN,
|
||||
REMOTE_UI_DATA_TYPE_NONE, RET_OK, &wb);
|
||||
} else {
|
||||
remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN,
|
||||
REMOTE_UI_DATA_TYPE_NONE, RET_FAIL, &wb);
|
||||
}
|
||||
return_value_if_fail(file != NULL, RET_BAD_PARAMS);
|
||||
|
||||
while ((len = fs_file_read(file, buff, sizeof(buff))) > 0) {
|
||||
wbuffer_init(&wb, buff, len);
|
||||
wb.cursor = len;
|
||||
ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_DATA,
|
||||
REMOTE_UI_DATA_TYPE_BINARY, RET_OK, &wb);
|
||||
break_if_fail(ret == RET_OK);
|
||||
}
|
||||
|
||||
wbuffer_rewind(&wb);
|
||||
ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_END,
|
||||
REMOTE_UI_DATA_TYPE_NONE, ret, &wb);
|
||||
|
||||
fs_file_close(file);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_create_dir(remote_ui_service_t* ui, const char* path) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(path != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return fs_create_dir_r(os_fs(), path);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_remove_dir(remote_ui_service_t* ui, const char* path) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(path != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return fs_remove_dir_r(os_fs(), path);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_remove_file(remote_ui_service_t* ui, const char* filename) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return fs_remove_file(os_fs(), filename);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_get_manifest(remote_ui_service_t* ui, str_t* result) {
|
||||
ret_t ret = RET_OK;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(result != NULL, RET_BAD_PARAMS);
|
||||
|
||||
str_set(result, "todo");
|
||||
|
||||
/*TODO*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_take_screen_shot(remote_ui_service_t* ui, const char* filename) {
|
||||
ret_t ret = RET_OK;
|
||||
bitmap_t* image = NULL;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
image = widget_take_snapshot(window_manager());
|
||||
if (image != NULL) {
|
||||
ret = bitmap_save_png(image, filename);
|
||||
} else {
|
||||
fs_remove_file(os_fs(), filename);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_prepare_manifest(remote_ui_service_t* ui, const char* filename) {
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return file_write(filename, "TODO", 5);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_prepare_xml_source(remote_ui_service_t* ui, const char* filename) {
|
||||
str_t str;
|
||||
ret_t ret = RET_OK;
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(filename != NULL, RET_BAD_PARAMS);
|
||||
|
||||
str_init(&str, 10000);
|
||||
widget_to_xml(win, &str);
|
||||
ret = file_write(filename, str.str, str.size);
|
||||
str_reset(&str);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_on_event_func(void* ctx, event_t* e) {
|
||||
remote_ui_service_t* ui = (remote_ui_service_t*)ctx;
|
||||
return_value_if_fail(ui != NULL, RET_BAD_PARAMS);
|
||||
/*TODO*/
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
static ret_t remote_ui_service_on_event(remote_ui_service_t* ui, const char* target, uint32_t event) {
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
widget_t* widget = widget_find_by_path(win, target, TRUE);
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
widget_on(widget, event, remote_ui_service_on_event_func, ui);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_off_event(remote_ui_service_t* ui, const char* target, uint32_t event) {
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
widget_t* widget = widget_find_by_path(win, target, TRUE);
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
widget_off_by_func(widget, event, remote_ui_service_on_event_func, ui);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_send_event(remote_ui_service_t* ui, const char* target, event_t* event) {
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
widget_t* widget = widget_find_by_path(win, target, TRUE);
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
switch (event->type) {
|
||||
case EVT_CLICK: {
|
||||
event->type = EVT_POINTER_DOWN;
|
||||
widget_on_pointer_down(widget, pointer_event_cast(event));
|
||||
|
||||
event->type = EVT_POINTER_UP;
|
||||
return widget_on_pointer_up(widget, pointer_event_cast(event));
|
||||
}
|
||||
case EVT_POINTER_DOWN: {
|
||||
return widget_on_pointer_down(widget, pointer_event_cast(event));
|
||||
}
|
||||
case EVT_POINTER_MOVE: {
|
||||
return widget_on_pointer_move(widget, pointer_event_cast(event));
|
||||
}
|
||||
case EVT_POINTER_UP: {
|
||||
return widget_on_pointer_up(widget, pointer_event_cast(event));
|
||||
}
|
||||
case EVT_KEY_DOWN: {
|
||||
return widget_on_keydown(widget, key_event_cast(event));
|
||||
}
|
||||
case EVT_KEY_UP: {
|
||||
return widget_on_keyup(widget, key_event_cast(event));
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_open_dialog(remote_ui_service_t* ui, const char* type, const char* title,
|
||||
const char* content, uint32_t duration) {
|
||||
if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_CONFIRM)) {
|
||||
return dialog_confirm(title, content);
|
||||
} else if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_INFO)) {
|
||||
return dialog_info(title, content);
|
||||
} else if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_WARN)) {
|
||||
return dialog_warn(title, content);
|
||||
} else {
|
||||
return dialog_toast(content, duration);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_open_window(remote_ui_service_t* ui, const char* name, const char* xml,
|
||||
const char* init_json) {
|
||||
widget_t* win = NULL;
|
||||
if (TK_STR_IS_NOT_EMPTY(xml)) {
|
||||
win = ui_loader_load_widget_from_xml(NULL, xml, strlen(xml));
|
||||
} else {
|
||||
win = window_open(name);
|
||||
}
|
||||
|
||||
return_value_if_fail(win != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (init_json != NULL) {
|
||||
/*TODO*/
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_close_window(remote_ui_service_t* ui, const char* name) {
|
||||
widget_t* win = widget_child(window_manager(), name);
|
||||
return_value_if_fail(win != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return window_manager_close_window(window_manager(), win);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_back_to_prev(remote_ui_service_t* ui) {
|
||||
window_manager_back(window_manager());
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_back_to_home(remote_ui_service_t* ui) {
|
||||
window_manager_back_to_home(window_manager());
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_set_prop(remote_ui_service_t* ui, const char* target, const char* name,
|
||||
const value_t* value) {
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
widget_t* widget = widget_find_by_path(win, target, TRUE);
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return widget_set_prop(widget, name, value);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_get_prop(remote_ui_service_t* ui, const char* target, const char* name,
|
||||
value_t* value) {
|
||||
widget_t* win = window_manager_get_top_window(window_manager());
|
||||
widget_t* widget = widget_find_by_path(win, target, TRUE);
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return widget_get_prop(widget, name, value);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_set_theme(remote_ui_service_t* ui, const char* theme) {
|
||||
return widget_set_theme(window_manager(), theme);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_exec_script(remote_ui_service_t* ui, const char* script, value_t* v) {
|
||||
tk_object_t* obj = object_default_create();
|
||||
ret_t ret = fscript_eval(obj, script, v);
|
||||
TK_OBJECT_UNREF(obj);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_set_language(remote_ui_service_t* ui, const char* language) {
|
||||
const char* p = NULL;
|
||||
char lang[TK_NAME_LEN + 1] = {0};
|
||||
char country[TK_NAME_LEN + 1] = {0};
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(language != NULL, RET_BAD_PARAMS);
|
||||
|
||||
p = strchr(language, '_');
|
||||
if (p != NULL) {
|
||||
tk_strncpy(lang, language, p - language);
|
||||
tk_strcpy(country, p + 1);
|
||||
} else {
|
||||
tk_strcpy(lang, language);
|
||||
}
|
||||
|
||||
return locale_info_change(locale_info(), lang, country);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_dev_info_write(ubjson_writer_t* writer, remote_ui_dev_info_t* info) {
|
||||
return_value_if_fail(writer != NULL && info != NULL, RET_BAD_PARAMS);
|
||||
|
||||
ubjson_writer_write_object_begin(writer);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_NAME, info->name);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_OS, info->os);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_VERSION, info->version);
|
||||
ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_ARCH, info->arch);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_SCREEN_WIDTH, info->screen_width);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_SCREEN_HEIGHT, info->screen_height);
|
||||
ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_DPI, info->dpi);
|
||||
ubjson_writer_write_object_end(writer);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_dispatch_impl(remote_ui_service_t* ui, remote_ui_msg_header_t* req,
|
||||
wbuffer_t* wb) {
|
||||
value_t v;
|
||||
char buff[1024] = {0};
|
||||
ret_t ret = RET_FAIL;
|
||||
tk_object_t* obj = NULL;
|
||||
ubjson_writer_t* writer = NULL;
|
||||
remote_ui_msg_header_t resp;
|
||||
char local_file[MAX_PATH + 1] = {0};
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(req != NULL && wb != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(&resp, 0x00, sizeof(resp));
|
||||
if (req->data_type == REMOTE_UI_DATA_TYPE_UBJSON) {
|
||||
obj = conf_ubjson_load_from_buff(wb->data, wb->cursor, FALSE);
|
||||
}
|
||||
|
||||
switch (req->type) {
|
||||
case REMOTE_UI_REQ_LOGIN: {
|
||||
const char* username = tk_object_get_prop_str(obj, "username");
|
||||
const char* password = tk_object_get_prop_str(obj, "password");
|
||||
resp.resp_code = remote_ui_service_login(ui, username, password);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_LOGIN;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_LOGOUT: {
|
||||
resp.resp_code = remote_ui_service_logout(ui);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_LOGOUT;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_GET_DEV_INFO: {
|
||||
remote_ui_dev_info_t info;
|
||||
memset(&info, 0x00, sizeof(info));
|
||||
resp.resp_code = remote_ui_service_get_dev_info(ui, &info);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_UBJSON;
|
||||
resp.type = REMOTE_UI_RESP_GET_DEV_INFO;
|
||||
writer = remote_ui_service_get_writer(ui);
|
||||
ret = remote_ui_dev_info_write(writer, &info);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_REBOOT: {
|
||||
rbuffer_t rb;
|
||||
uint32_t reboot_type = REMOTE_UI_REBOOT_DEFAULT;
|
||||
rbuffer_init(&rb, wb->data, wb->cursor);
|
||||
|
||||
rbuffer_read_uint32(&rb, &reboot_type);
|
||||
resp.resp_code = remote_ui_service_reboot(ui, reboot_type);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_REBOOT;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_UPLOAD_FILE_BEGIN: {
|
||||
const char* filename = (const char*)(wb->data);
|
||||
filename = path_prepend_app_root(local_file, filename);
|
||||
resp.resp_code = remote_ui_service_upload_file(ui, filename);
|
||||
return RET_OK;
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN: {
|
||||
const char* filename = (const char*)(wb->data);
|
||||
|
||||
if (tk_str_eq(filename, REMOTE_UI_FILE_SCREEN_SHOT)) {
|
||||
filename = path_prepend_temp_path(local_file, filename);
|
||||
resp.resp_code = remote_ui_service_take_screen_shot(ui, filename);
|
||||
} else if (tk_str_eq(filename, REMOTE_UI_FILE_MANIFEST)) {
|
||||
filename = path_prepend_temp_path(local_file, filename);
|
||||
resp.resp_code = remote_ui_service_prepare_manifest(ui, filename);
|
||||
} else if (tk_str_eq(filename, REMOTE_UI_FILE_XML_SOURCE)) {
|
||||
filename = path_prepend_temp_path(local_file, filename);
|
||||
resp.resp_code = remote_ui_service_prepare_xml_source(ui, filename);
|
||||
} else {
|
||||
filename = path_prepend_app_root(local_file, filename);
|
||||
}
|
||||
|
||||
resp.resp_code = remote_ui_service_download_file(ui, filename);
|
||||
return RET_OK;
|
||||
}
|
||||
case REMOTE_UI_REQ_CREATE_DIR: {
|
||||
const char* filename = (const char*)(wb->data);
|
||||
filename = path_prepend_app_root(local_file, filename);
|
||||
|
||||
resp.resp_code = remote_ui_service_create_dir(ui, filename);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_CREATE_DIR;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_REMOVE_DIR: {
|
||||
const char* filename = (const char*)(wb->data);
|
||||
filename = path_prepend_app_root(local_file, filename);
|
||||
|
||||
resp.resp_code = remote_ui_service_remove_dir(ui, filename);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_REMOVE_DIR;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_REMOVE_FILE: {
|
||||
const char* filename = (const char*)(wb->data);
|
||||
filename = path_prepend_app_root(local_file, filename);
|
||||
resp.resp_code = remote_ui_service_remove_file(ui, filename);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_REMOVE_FILE;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_OPEN_WINDOW: {
|
||||
const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME);
|
||||
const char* xml = tk_object_get_prop_str(obj, REMOTE_UI_KEY_XML);
|
||||
const char* init_json = tk_object_get_prop_str(obj, REMOTE_UI_KEY_INIT);
|
||||
resp.resp_code = remote_ui_service_open_window(ui, name, xml, init_json);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_OPEN_WINDOW;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_OPEN_DIALOG: {
|
||||
const char* type = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TYPE);
|
||||
const char* title = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TITLE);
|
||||
const char* content = tk_object_get_prop_str(obj, REMOTE_UI_KEY_CONTENT);
|
||||
uint32_t duration = tk_object_get_prop_uint32(obj, REMOTE_UI_KEY_DURATION, 3000);
|
||||
|
||||
resp.resp_code = remote_ui_service_open_dialog(ui, type, title, content, duration);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_OPEN_WINDOW;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_BACK_TO_PREV: {
|
||||
resp.resp_code = remote_ui_service_back_to_prev(ui);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_BACK_TO_PREV;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_BACK_TO_HOME: {
|
||||
resp.resp_code = remote_ui_service_back_to_home(ui);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_BACK_TO_HOME;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_CLOSE_WINDOW: {
|
||||
const char* name = (const char*)(wb->data);
|
||||
resp.resp_code = remote_ui_service_close_window(ui, name);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_CLOSE_WINDOW;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_SET_PROP: {
|
||||
value_t v;
|
||||
const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET);
|
||||
const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME);
|
||||
|
||||
if (tk_object_get_prop(obj, REMOTE_UI_KEY_VALUE, &v) == RET_OK) {
|
||||
resp.resp_code = remote_ui_service_set_prop(ui, target, name, &v);
|
||||
} else {
|
||||
resp.resp_code = RET_FAIL;
|
||||
}
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_GET_PROP: {
|
||||
const char* str = NULL;
|
||||
const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET);
|
||||
const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME);
|
||||
|
||||
value_set_int(&v, 0);
|
||||
resp.resp_code = remote_ui_service_get_prop(ui, target, name, &v);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_STRING;
|
||||
str = value_str_ex(&v, buff, sizeof(buff));
|
||||
wbuffer_rewind(wb);
|
||||
wbuffer_write_string(wb, str);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_SET_LANGUAGE: {
|
||||
const char* language = (const char*)(wb->data);
|
||||
resp.resp_code = remote_ui_service_set_language(ui, language);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_SET_LANGUAGE;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_SET_THEME: {
|
||||
const char* theme = (const char*)(wb->data);
|
||||
resp.resp_code = remote_ui_service_set_theme(ui, theme);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_SET_THEME;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_EXEC_FSCRIPT: {
|
||||
const char* script = (const char*)(wb->data);
|
||||
|
||||
value_set_int(&v, 0);
|
||||
resp.resp_code = remote_ui_service_exec_script(ui, script, &v);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_EXEC_FSCRIPT;
|
||||
wbuffer_rewind(wb);
|
||||
wbuffer_write_string(wb, value_str_ex(&v, buff, sizeof(buff)));
|
||||
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_ON_EVENT: {
|
||||
const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET);
|
||||
uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0);
|
||||
resp.resp_code = remote_ui_service_on_event(ui, target, event_type);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_ON_EVENT;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_OFF_EVENT: {
|
||||
const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET);
|
||||
uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0);
|
||||
resp.resp_code = remote_ui_service_off_event(ui, target, event_type);
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_OFF_EVENT;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
case REMOTE_UI_REQ_SEND_EVENT: {
|
||||
event_t* e = NULL;
|
||||
const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET);
|
||||
uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0);
|
||||
|
||||
switch (event_type) {
|
||||
case EVT_CLICK:
|
||||
case EVT_POINTER_DOWN:
|
||||
case EVT_POINTER_UP:
|
||||
case EVT_POINTER_MOVE: {
|
||||
pointer_event_t evt;
|
||||
int x = tk_object_get_prop_int(obj, REMOTE_UI_KEY_X, 0);
|
||||
int y = tk_object_get_prop_int(obj, REMOTE_UI_KEY_Y, 0);
|
||||
e = pointer_event_init(&evt, event_type, NULL, x, y);
|
||||
break;
|
||||
}
|
||||
case EVT_KEY_DOWN:
|
||||
case EVT_KEY_UP: {
|
||||
key_event_t evt;
|
||||
uint32_t key = tk_object_get_prop_int(obj, REMOTE_UI_KEY_CODE, 0);
|
||||
e = key_event_init(&evt, event_type, NULL, key);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (e != NULL) {
|
||||
resp.resp_code = remote_ui_service_send_event(ui, target, e);
|
||||
} else {
|
||||
resp.resp_code = RET_FAIL;
|
||||
}
|
||||
resp.data_type = REMOTE_UI_DATA_TYPE_NONE;
|
||||
resp.type = REMOTE_UI_RESP_SEND_EVENT;
|
||||
wbuffer_rewind(wb);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
ret = RET_NOT_IMPL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TK_OBJECT_UNREF(obj);
|
||||
|
||||
return remote_ui_service_send_resp(ui->io, resp.type, resp.data_type, resp.resp_code, wb);
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_dispatch(remote_ui_service_t* ui) {
|
||||
ret_t ret = RET_OK;
|
||||
remote_ui_msg_header_t header;
|
||||
return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
memset(&header, 0x00, sizeof(header));
|
||||
ret = remote_ui_service_read_req(ui->io, &header, &(ui->wb));
|
||||
return_value_if_fail(ret == RET_OK, ret);
|
||||
|
||||
return remote_ui_service_dispatch_impl(ui, &header, &(ui->wb));
|
||||
}
|
||||
|
||||
static ret_t remote_ui_service_destroy(remote_ui_service_t* ui) {
|
||||
return_value_if_fail(ui != NULL, RET_BAD_PARAMS);
|
||||
|
||||
wbuffer_deinit(&(ui->wb));
|
||||
TKMEM_FREE(ui);
|
||||
|
||||
return RET_OK;
|
||||
}
|
82
src/remote_ui/service/remote_ui_service.h
Normal file
82
src/remote_ui/service/remote_ui_service.h
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* File: remote_ui_service.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: remote ui service
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_REMOTE_UI_SERVICE_H
|
||||
#define TK_REMOTE_UI_SERVICE_H
|
||||
|
||||
#include "tkc/buffer.h"
|
||||
#include "tkc/darray.h"
|
||||
#include "tkc/iostream.h"
|
||||
#include "ubjson/ubjson_writer.h"
|
||||
#include "service/service.h"
|
||||
#include "remote_ui/shared/remote_ui_types_def.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class remote_ui_service_args_t
|
||||
* remote ui服务端启动参数。
|
||||
*/
|
||||
typedef struct _remote_ui_service_args_t {
|
||||
/**
|
||||
* @property {tk_service_auth_t} auth
|
||||
* @annotation ["readable"]
|
||||
* 登陆认证函数。
|
||||
*/
|
||||
tk_service_auth_t auth;
|
||||
} remote_ui_service_args_t;
|
||||
|
||||
/**
|
||||
* @class remote_ui_service_t
|
||||
* remote ui服务端。
|
||||
*/
|
||||
typedef struct _remote_ui_service_t {
|
||||
tk_service_t service;
|
||||
|
||||
/**
|
||||
* @property {tk_iostream_t*} io
|
||||
* @annotation ["readable"]
|
||||
* IO stream。
|
||||
*/
|
||||
tk_iostream_t* io;
|
||||
|
||||
/*private*/
|
||||
wbuffer_t wb;
|
||||
ubjson_writer_t writer;
|
||||
tk_object_t* event_handlers;
|
||||
bool_t is_login;
|
||||
tk_service_auth_t auth;
|
||||
} remote_ui_service_t;
|
||||
|
||||
/**
|
||||
* @method remote_ui_service_create
|
||||
* 创建remote ui客户端。
|
||||
*
|
||||
* @param {tk_iostream_t*} io IO流(由service释放)。
|
||||
* @param {void*} args 参数。
|
||||
*
|
||||
* @return {tk_service_t*} 返回service对象。
|
||||
*/
|
||||
tk_service_t* remote_ui_service_create(tk_iostream_t* io, void* args);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_REMOTE_UI_SERVICE_H*/
|
465
src/remote_ui/shared/remote_ui_types_def.h
Normal file
465
src/remote_ui/shared/remote_ui_types_def.h
Normal file
@ -0,0 +1,465 @@
|
||||
/**
|
||||
* File: remote_ui_types_def.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: remote ui types def
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_REMOTE_UI_TYPES_DEF_H
|
||||
#define TK_REMOTE_UI_TYPES_DEF_H
|
||||
|
||||
#include "tkc/types_def.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @enum remote_ui_msg_code_t
|
||||
* @prefix REMOTE_UI_
|
||||
* 消息类型。
|
||||
*
|
||||
*/
|
||||
typedef enum _remote_ui_msg_code_t {
|
||||
/**
|
||||
* @const REMOTE_UI_MSG_NONE
|
||||
* 无效消息。
|
||||
*/
|
||||
REMOTE_UI_MSG_NONE = 0,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_LOGIN
|
||||
* 登录请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_LOGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_LOGOUT
|
||||
* 登出请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_LOGOUT,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_GET_DEV_INFO
|
||||
* 获取设备信息。
|
||||
*/
|
||||
REMOTE_UI_REQ_GET_DEV_INFO,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_REBOOT
|
||||
* 重新加载请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_REBOOT,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_UPLOAD_FILE_BEGIN
|
||||
* 上传文件请求开始。
|
||||
*/
|
||||
REMOTE_UI_REQ_UPLOAD_FILE_BEGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_UPLOAD_FILE_DATA
|
||||
* 上传文件请求数据。
|
||||
*/
|
||||
REMOTE_UI_REQ_UPLOAD_FILE_DATA,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_UPLOAD_FILE_END
|
||||
* 上传文件请求结束。
|
||||
*/
|
||||
REMOTE_UI_REQ_UPLOAD_FILE_END,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN
|
||||
* 下载文件请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_CREATE_DIR
|
||||
* 创建目录请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_CREATE_DIR,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_REMOVE_DIR
|
||||
* 删除目录请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_REMOVE_DIR,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_REMOVE_FILE
|
||||
* 删除文件请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_REMOVE_FILE,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_ON_EVENT
|
||||
* 注册事件请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_ON_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_OFF_EVENT
|
||||
* 注销事件请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_OFF_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_SEND_EVENT
|
||||
* 发送事件请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_SEND_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_OPEN_WINDOW
|
||||
* 打开窗口请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_OPEN_WINDOW,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_OPEN_DIALOG
|
||||
* 打开基本对话框请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_OPEN_DIALOG,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_CLOSE_WINDOW
|
||||
* 关闭窗口请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_CLOSE_WINDOW,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_BACK_TO_PREV
|
||||
* 返回请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_BACK_TO_PREV,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_BACK_TO_HOME
|
||||
* 返回主页请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_BACK_TO_HOME,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_SET_PROP
|
||||
* 设置属性请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_SET_PROP,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_GET_PROP
|
||||
* 获取属性请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_GET_PROP,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_SET_THEME
|
||||
* 设置主题请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_SET_THEME,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_SET_LANGUAGE
|
||||
* 设置语言请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_SET_LANGUAGE,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_GET_XML_SOURCE
|
||||
* 获取xml源码请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_GET_XML_SOURCE,
|
||||
/**
|
||||
* @const REMOTE_UI_REQ_EXEC_FSCRIPT
|
||||
* 执行脚本请求。
|
||||
*/
|
||||
REMOTE_UI_REQ_EXEC_FSCRIPT,
|
||||
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_LOGIN
|
||||
* 登录响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_LOGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_LOGOUT
|
||||
* 登出响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_LOGOUT,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_GET_DEV_INFO
|
||||
* 获取设备信息响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_GET_DEV_INFO,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_REBOOT
|
||||
* 重新加载响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_REBOOT,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_UPLOAD_FILE_BEGIN
|
||||
* 上传文件开始响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_UPLOAD_FILE_BEGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_UPLOAD_FILE_DATA
|
||||
* 上传文件数据响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_UPLOAD_FILE_DATA,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_UPLOAD_FILE_END
|
||||
* 上传文件结束响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_UPLOAD_FILE_END,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN
|
||||
* 下载文件开始响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_DOWNLOAD_FILE_DATA
|
||||
* 下载文件数据响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_DOWNLOAD_FILE_DATA,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_DOWNLOAD_FILE_END
|
||||
* 下载文件数据响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_DOWNLOAD_FILE_END,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_CREATE_DIR
|
||||
* 创建目录响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_CREATE_DIR,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_REMOVE_DIR
|
||||
* 删除目录响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_REMOVE_DIR,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_REMOVE_FILE
|
||||
* 删除文件响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_REMOVE_FILE,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_ON_EVENT
|
||||
* 注册事件响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_ON_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_OFF_EVENT
|
||||
* 注销事件响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_OFF_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_SEND_EVENT
|
||||
* 发送事件响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_SEND_EVENT,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_OPEN_WINDOW
|
||||
* 打开窗口响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_OPEN_WINDOW,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_OPEN_DIALOG
|
||||
* 打开基本对话框响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_OPEN_DIALOG,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_CLOSE_WINDOW
|
||||
* 关闭窗口响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_CLOSE_WINDOW,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_BACK_TO_PREV
|
||||
* 返回响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_BACK_TO_PREV,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_BACK_TO_HOME
|
||||
* 返回主页响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_BACK_TO_HOME,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_SET_PROP
|
||||
* 设置属性响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_SET_PROP,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_GET_PROP
|
||||
* 获取属性响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_GET_PROP,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_SET_THEME
|
||||
* 设置主题响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_SET_THEME,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_SET_LANGUAGE
|
||||
* 设置语言响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_SET_LANGUAGE,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_GET_XML_SOURCE
|
||||
* 获取xml源码响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_GET_XML_SOURCE,
|
||||
/**
|
||||
* @const REMOTE_UI_RESP_EXEC_FSCRIPT
|
||||
* 执行脚本响应。
|
||||
*/
|
||||
REMOTE_UI_RESP_EXEC_FSCRIPT,
|
||||
/**
|
||||
* @const REMOTE_UI_NOTIFY
|
||||
* 事件通知。
|
||||
*/
|
||||
REMOTE_UI_NOTIFY,
|
||||
} remote_ui_msg_code_t;
|
||||
|
||||
/**
|
||||
* @enum remote_ui_data_type_t
|
||||
* @prefix REMOTE_UI_DATA_TYPE_
|
||||
* 数据类型。
|
||||
*/
|
||||
typedef enum _remote_ui_data_type_t {
|
||||
/**
|
||||
* @const REMOTE_UI_DATA_TYPE_NONE
|
||||
* 无效数据类型。
|
||||
*/
|
||||
REMOTE_UI_DATA_TYPE_NONE = 0,
|
||||
/**
|
||||
* @const REMOTE_UI_DATA_TYPE_UBJSON
|
||||
* JSON数据类型。
|
||||
*/
|
||||
REMOTE_UI_DATA_TYPE_UBJSON,
|
||||
/**
|
||||
* @const REMOTE_UI_DATA_TYPE_STRING
|
||||
* 字符串数据类型。
|
||||
*/
|
||||
REMOTE_UI_DATA_TYPE_STRING,
|
||||
/**
|
||||
* @const REMOTE_UI_DATA_TYPE_BINARY
|
||||
* 二进制数据类型。
|
||||
*/
|
||||
REMOTE_UI_DATA_TYPE_BINARY
|
||||
} remote_ui_data_type_t;
|
||||
|
||||
/**
|
||||
* @class remote_ui_msg_header_t
|
||||
* 消息头。
|
||||
*/
|
||||
typedef struct _remote_ui_msg_header_t {
|
||||
/**
|
||||
* @property {uint32_t} size
|
||||
* 消息体的大小。
|
||||
*/
|
||||
uint32_t size;
|
||||
/**
|
||||
* @property {uint16_t} type
|
||||
* 消息类型。
|
||||
*/
|
||||
uint16_t type;
|
||||
/**
|
||||
* @property {uint8_t} data_type
|
||||
* 数据类型。
|
||||
*/
|
||||
uint8_t data_type;
|
||||
/**
|
||||
* @property {uint8_t} resp_code
|
||||
* 响应码(仅适用于resp)。
|
||||
*/
|
||||
uint8_t resp_code;
|
||||
} remote_ui_msg_header_t;
|
||||
|
||||
/**
|
||||
* @class remote_ui_dev_info_t
|
||||
* 设备信息。
|
||||
*/
|
||||
typedef struct _remote_ui_dev_info_t {
|
||||
/**
|
||||
* @property {char*} name
|
||||
* 设备名称。
|
||||
*/
|
||||
char name[64];
|
||||
/**
|
||||
* @property {char*} version
|
||||
* 设备版本。
|
||||
*/
|
||||
char version[64];
|
||||
/**
|
||||
* @property {char*} os
|
||||
* 操作系统。
|
||||
*/
|
||||
char os[16];
|
||||
|
||||
/**
|
||||
* @property {char*} arch
|
||||
* CPU架构。
|
||||
*/
|
||||
char arch[16];
|
||||
|
||||
/**
|
||||
* @property {uint32_t} screen_width
|
||||
* 屏幕宽度。
|
||||
*/
|
||||
uint32_t screen_width;
|
||||
/**
|
||||
* @property {uint32_t} screen_height
|
||||
* 屏幕高度。
|
||||
*/
|
||||
uint32_t screen_height;
|
||||
/**
|
||||
* @property {uint32_t} dpi
|
||||
* 屏幕DPI。
|
||||
*/
|
||||
uint32_t dpi;
|
||||
} remote_ui_dev_info_t;
|
||||
|
||||
/**
|
||||
* @enum remote_ui_reboot_type_t
|
||||
* @prefix REMOTE_UI_REBOOT_
|
||||
* 重启类型。
|
||||
*/
|
||||
typedef enum _remote_ui_reboot_type_t {
|
||||
/**
|
||||
* @const REMOTE_UI_REBOOT_DEFAULT
|
||||
* 重启。
|
||||
*/
|
||||
REMOTE_UI_REBOOT_DEFAULT = 0,
|
||||
/**
|
||||
* @const REMOTE_UI_REBOOT_RELOAD
|
||||
* 重新加载。
|
||||
*/
|
||||
REMOTE_UI_REBOOT_RELOAD,
|
||||
/**
|
||||
* @const REMOTE_UI_REBOOT_POWEROFF
|
||||
* 关机。
|
||||
*/
|
||||
REMOTE_UI_REBOOT_POWEROFF
|
||||
} remote_ui_reboot_type_t;
|
||||
|
||||
#define REMOTE_UI_KEY_USERNAME "username"
|
||||
#define REMOTE_UI_KEY_PASSWORD "password"
|
||||
|
||||
#define REMOTE_UI_KEY_DEV_NAME "dev_name"
|
||||
#define REMOTE_UI_KEY_DEV_OS "dev_os"
|
||||
#define REMOTE_UI_KEY_DEV_ARCH "dev_arch"
|
||||
#define REMOTE_UI_KEY_DEV_VERSION "dev_version"
|
||||
#define REMOTE_UI_KEY_DEV_SCREEN_WIDTH "dev_screen_width"
|
||||
#define REMOTE_UI_KEY_DEV_SCREEN_HEIGHT "dev_screen_height"
|
||||
#define REMOTE_UI_KEY_DEV_DPI "dev_dpi"
|
||||
#define REMOTE_UI_KEY_TARGET "target"
|
||||
#define REMOTE_UI_KEY_NAME "name"
|
||||
#define REMOTE_UI_KEY_VALUE "value"
|
||||
#define REMOTE_UI_KEY_EVENT "event"
|
||||
#define REMOTE_UI_KEY_XML "xml"
|
||||
#define REMOTE_UI_KEY_INIT "init"
|
||||
#define REMOTE_UI_KEY_X "x"
|
||||
#define REMOTE_UI_KEY_Y "y"
|
||||
#define REMOTE_UI_KEY_CODE "code"
|
||||
#define REMOTE_UI_KEY_TYPE "type"
|
||||
#define REMOTE_UI_KEY_TITLE "title"
|
||||
#define REMOTE_UI_KEY_CONTENT "content"
|
||||
#define REMOTE_UI_KEY_DURATION "duration"
|
||||
#define REMOTE_UI_FILE_MANIFEST "__manifest__.txt"
|
||||
#define REMOTE_UI_FILE_XML_SOURCE "__xml_source__.xml"
|
||||
#define REMOTE_UI_FILE_SCREEN_SHOT "__screen_shot__.png"
|
||||
|
||||
#define REMOTE_UI_DIALOG_TYPE_CONFIRM "confirm"
|
||||
#define REMOTE_UI_DIALOG_TYPE_WARN "warn"
|
||||
#define REMOTE_UI_DIALOG_TYPE_INFO "info"
|
||||
#define REMOTE_UI_DIALOG_TYPE_TOAST "toast"
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_REMOTE_UI_TYPES_DEF_H*/
|
147
src/service/service.c
Normal file
147
src/service/service.c
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* File: service.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: service interface
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-05 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
#include "tkc/url.h"
|
||||
#include "tkc/utils.h"
|
||||
#include "service/service.h"
|
||||
#include "tkc/event_source_fd.h"
|
||||
#include "streams/inet/iostream_tcp.h"
|
||||
#include "streams/serial/iostream_serial.h"
|
||||
|
||||
#include "tkc/socket_helper.h"
|
||||
|
||||
ret_t tk_service_dispatch(tk_service_t* service) {
|
||||
return_value_if_fail(service != NULL && service->dispatch != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return service->dispatch(service);
|
||||
}
|
||||
|
||||
ret_t tk_service_destroy(tk_service_t* service) {
|
||||
return_value_if_fail(service != NULL && service->destroy != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return service->destroy(service);
|
||||
}
|
||||
|
||||
static ret_t tk_service_on_data(event_source_t* source) {
|
||||
event_source_fd_t* event_source_fd = (event_source_fd_t*)source;
|
||||
tk_service_t* service = (tk_service_t*)(event_source_fd->ctx);
|
||||
|
||||
if (tk_service_dispatch(service) != RET_OK) {
|
||||
tk_service_destroy(service);
|
||||
log_debug("client disconnected\n");
|
||||
return RET_REMOVE;
|
||||
} else {
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t tk_service_tcp_on_client(event_source_t* source) {
|
||||
event_source_fd_t* event_source_fd = (event_source_fd_t*)source;
|
||||
tk_service_create_t create = (tk_service_create_t)(event_source_fd->ctx);
|
||||
|
||||
int listen_sock = event_source_get_fd(source);
|
||||
int sock = tcp_accept(listen_sock);
|
||||
|
||||
if (sock >= 0) {
|
||||
log_debug("client connected:%d\n", sock);
|
||||
tk_iostream_t* io = tk_iostream_tcp_create(sock);
|
||||
if (io != NULL) {
|
||||
tk_service_t* service = create(io, event_source_fd->ctx2);
|
||||
if (service != NULL) {
|
||||
event_source_manager_t* esm = source->manager;
|
||||
event_source_t* client_source = event_source_fd_create(sock, tk_service_on_data, service);
|
||||
event_source_manager_add(esm, client_source);
|
||||
TK_OBJECT_UNREF(client_source);
|
||||
} else {
|
||||
TK_OBJECT_UNREF(io);
|
||||
}
|
||||
} else {
|
||||
log_debug("oom! disconnected:%d\n", sock);
|
||||
tk_socket_close(sock);
|
||||
}
|
||||
} else {
|
||||
log_debug("error disconnected:%d\n", sock);
|
||||
tk_socket_close(sock);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t tk_service_start_tcp(event_source_manager_t* esm, const char* url,
|
||||
tk_service_create_t create, void* args) {
|
||||
int port = 0;
|
||||
int listen_sock = -1;
|
||||
event_source_t* source = NULL;
|
||||
url_t* aurl = url_create(url);
|
||||
return_value_if_fail(esm != NULL && aurl != NULL && create != NULL, RET_BAD_PARAMS);
|
||||
|
||||
port = aurl->port;
|
||||
listen_sock = tcp_listen(port);
|
||||
url_destroy(aurl);
|
||||
return_value_if_fail(listen_sock >= 0, RET_BAD_PARAMS);
|
||||
|
||||
log_debug("listen on %d listen_sock=%d\n", port, listen_sock);
|
||||
|
||||
source = event_source_fd_create(listen_sock, tk_service_tcp_on_client, create);
|
||||
return_value_if_fail(source != NULL, RET_OOM);
|
||||
EVENT_SOURCE_FD(source)->ctx2 = args;
|
||||
event_source_manager_add(esm, source);
|
||||
OBJECT_UNREF(source);
|
||||
log_debug("service start: %s\n", url);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t tk_service_start_serial(event_source_manager_t* esm, const char* url,
|
||||
tk_service_create_t create, void* args) {
|
||||
tk_iostream_t* io = NULL;
|
||||
tk_service_t* service = NULL;
|
||||
return_value_if_fail(esm != NULL && create != NULL, RET_BAD_PARAMS);
|
||||
|
||||
io = tk_iostream_serial_create_ex(url);
|
||||
return_value_if_fail(io != NULL, RET_BAD_PARAMS);
|
||||
|
||||
service = create(io, args);
|
||||
if (service != NULL) {
|
||||
int fd = tk_object_get_prop_int(TK_OBJECT(io), TK_STREAM_PROP_FD, -1);
|
||||
event_source_t* client_source = event_source_fd_create(fd, tk_service_on_data, service);
|
||||
event_source_manager_add(esm, client_source);
|
||||
TK_OBJECT_UNREF(client_source);
|
||||
log_debug("service start: %s\n", url);
|
||||
} else {
|
||||
TK_OBJECT_UNREF(io);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t tk_service_start(event_source_manager_t* esm, const char* url, tk_service_create_t create,
|
||||
void* args) {
|
||||
return_value_if_fail(esm != NULL && create != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (tk_str_start_with(url, STR_SCHEMA_TCP)) {
|
||||
return tk_service_start_tcp(esm, url, create, args);
|
||||
} else if (tk_str_start_with(url, STR_SCHEMA_SERIAL)) {
|
||||
return tk_service_start_serial(esm, url, create, args);
|
||||
} else {
|
||||
log_debug("not supported: %s\n", url);
|
||||
return RET_NOT_IMPL;
|
||||
}
|
||||
}
|
86
src/service/service.h
Normal file
86
src/service/service.h
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* File: service.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: service interface
|
||||
*
|
||||
* Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-05 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_SERVICE_H
|
||||
#define TK_SERVICE_H
|
||||
|
||||
#include "tkc/iostream.h"
|
||||
#include "tkc/event_source_manager.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
struct _tk_service_t;
|
||||
typedef struct _tk_service_t tk_service_t;
|
||||
|
||||
typedef tk_service_t* (*tk_service_create_t)(tk_iostream_t* io, void* args);
|
||||
typedef ret_t (*tk_service_dispatch_t)(tk_service_t* service);
|
||||
typedef ret_t (*tk_service_destroy_t)(tk_service_t* service);
|
||||
|
||||
typedef ret_t (*tk_service_auth_t)(tk_service_t* service, const char* username,
|
||||
const char* password);
|
||||
|
||||
/**
|
||||
* @class tk_service_t
|
||||
* 服务接口。
|
||||
*/
|
||||
struct _tk_service_t {
|
||||
tk_service_dispatch_t dispatch;
|
||||
tk_service_destroy_t destroy;
|
||||
tk_iostream_t* io;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method tk_service_dispatch
|
||||
* 处理服务器请求。
|
||||
*
|
||||
* @param {tk_service_t*} service 服务对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_service_dispatch(tk_service_t* service);
|
||||
|
||||
/**
|
||||
* @method tk_service_destroy
|
||||
* 销毁服务对象。
|
||||
*
|
||||
* @param {tk_service_t*} service 服务对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_service_destroy(tk_service_t* service);
|
||||
|
||||
/**
|
||||
* @method tk_service_start
|
||||
* 启动服务。
|
||||
*
|
||||
* @param {event_source_manager_t*} esm 事件源管理器。
|
||||
* @param {const char*} url 服务地址。
|
||||
* @param {tk_service_create_t} create 创建服务对象的函数。
|
||||
* @param {void*} args 参数。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_service_start(event_source_manager_t* esm, const char* url, tk_service_create_t create,
|
||||
void* args);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_SERVICE_H*/
|
68
tests/ui_test_data/demo_ui_old.ini
Normal file
68
tests/ui_test_data/demo_ui_old.ini
Normal file
@ -0,0 +1,68 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
[get_dev_info]
|
||||
|
||||
[create_dir]
|
||||
path=abc/123
|
||||
|
||||
[upload]
|
||||
remote = abc/123/test.txt
|
||||
local = README.md
|
||||
|
||||
[download]
|
||||
remote = abc/123/test.txt
|
||||
local = README.md.download
|
||||
ret=RET_OK
|
||||
|
||||
[remove_file]
|
||||
filename=abc/123/test.txt
|
||||
[remove_dir]
|
||||
path=abc/123
|
||||
|
||||
[take_screen_shot]
|
||||
filename=test.png
|
||||
|
||||
[get_manifest]
|
||||
|
||||
[open_window]
|
||||
name=button
|
||||
|
||||
[sleep]
|
||||
time=2000
|
||||
|
||||
[back]
|
||||
|
||||
[open_window]
|
||||
name=edit
|
||||
|
||||
[sleep]
|
||||
time=2000
|
||||
|
||||
[home]
|
||||
|
||||
[open_window]
|
||||
name=rich_text
|
||||
|
||||
[sleep]
|
||||
time=2000
|
||||
|
||||
[close_window]
|
||||
name=rich_text
|
||||
|
||||
[set_prop]
|
||||
target=open:button
|
||||
name=text
|
||||
value=Hello
|
||||
|
||||
[get_prop]
|
||||
target=open:button
|
||||
name=text
|
||||
value=Hello
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
17
tests/ui_test_data/demo_ui_old_confirm.ini
Normal file
17
tests/ui_test_data/demo_ui_old_confirm.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[confirm]
|
||||
title=title
|
||||
content=content
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
16
tests/ui_test_data/demo_ui_old_exec_fscript.ini
Normal file
16
tests/ui_test_data/demo_ui_old_exec_fscript.ini
Normal file
@ -0,0 +1,16 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[exec_fscript]
|
||||
fscript=print("hello");
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
15
tests/ui_test_data/demo_ui_old_get_source.ini
Normal file
15
tests/ui_test_data/demo_ui_old_get_source.ini
Normal file
@ -0,0 +1,15 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[get_source]
|
||||
filename=test.xml
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
17
tests/ui_test_data/demo_ui_old_info.ini
Normal file
17
tests/ui_test_data/demo_ui_old_info.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[info]
|
||||
title=title
|
||||
content=content
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
19
tests/ui_test_data/demo_ui_old_send_click_events.ini
Normal file
19
tests/ui_test_data/demo_ui_old_send_click_events.ini
Normal file
@ -0,0 +1,19 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[send_event]
|
||||
target=window
|
||||
type=click
|
||||
x = 100
|
||||
y = 300
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
19
tests/ui_test_data/demo_ui_old_send_key_events.ini
Normal file
19
tests/ui_test_data/demo_ui_old_send_key_events.ini
Normal file
@ -0,0 +1,19 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[send_event]
|
||||
type=key_down
|
||||
key=RIGHT
|
||||
|
||||
[send_event]
|
||||
type=key_up
|
||||
key=RIGHT
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
31
tests/ui_test_data/demo_ui_old_send_pointer_events.ini
Normal file
31
tests/ui_test_data/demo_ui_old_send_pointer_events.ini
Normal file
@ -0,0 +1,31 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[send_event]
|
||||
target=window
|
||||
type=pointer_down
|
||||
x = 100
|
||||
y = 300
|
||||
|
||||
[send_event]
|
||||
target=window
|
||||
type=pointer_move
|
||||
x = 101
|
||||
y = 301
|
||||
|
||||
[send_event]
|
||||
target=window
|
||||
type=pointer_up
|
||||
x = 100
|
||||
y = 300
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
21
tests/ui_test_data/demo_ui_old_set_get_prop.ini
Normal file
21
tests/ui_test_data/demo_ui_old_set_get_prop.ini
Normal file
@ -0,0 +1,21 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[set_prop]
|
||||
target=open:button
|
||||
name=text
|
||||
value=Hello
|
||||
|
||||
[get_prop]
|
||||
target=open:button
|
||||
name=text
|
||||
value=Hello
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
17
tests/ui_test_data/demo_ui_old_set_theme_language.ini
Normal file
17
tests/ui_test_data/demo_ui_old_set_theme_language.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[set_theme]
|
||||
theme=default
|
||||
|
||||
[set_language]
|
||||
language=zh_CN
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
17
tests/ui_test_data/demo_ui_old_toast.ini
Normal file
17
tests/ui_test_data/demo_ui_old_toast.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[toast]
|
||||
content=content
|
||||
duration=3000
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
17
tests/ui_test_data/demo_ui_old_warn.ini
Normal file
17
tests/ui_test_data/demo_ui_old_warn.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[create]
|
||||
url=tcp://localhost:2233
|
||||
|
||||
[login]
|
||||
username=admin
|
||||
password=admin
|
||||
|
||||
[warn]
|
||||
title=title
|
||||
content=content
|
||||
|
||||
[back]
|
||||
|
||||
[logout]
|
||||
|
||||
[close]
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "base/theme_xml.h"
|
||||
#include "base/style_factory.h"
|
||||
#include "base/window.h"
|
||||
#include "base/window_manager.h"
|
||||
|
||||
using std::string;
|
||||
#include "common.h"
|
||||
@ -68,6 +69,46 @@ TEST(Widget, move_to_center) {
|
||||
|
||||
ASSERT_EQ(b->x, 150);
|
||||
ASSERT_EQ(b->y, 120);
|
||||
|
||||
widget_destroy(w);
|
||||
}
|
||||
|
||||
TEST(Widget, find_by_path) {
|
||||
widget_t* w = window_create(NULL, 0, 0, 400, 300);
|
||||
widget_t* b = button_create(w, 0, 0, 100, 60);
|
||||
widget_t* label = label_create(b, 0, 0, 100, 60);
|
||||
|
||||
widget_set_name(w, "win");
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_SELF, TRUE), w);
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW, TRUE), w);
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW_MANAGER, TRUE), window_manager());
|
||||
|
||||
widget_set_name(b, "foo");
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_SELF".foo", TRUE), b);
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW".foo", TRUE), b);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo", TRUE), b);
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo", TRUE), b);
|
||||
|
||||
widget_set_name(label, "bar");
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_SELF".bar", TRUE), (widget_t*)NULL);
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW".bar", TRUE), (widget_t*)NULL);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo.bar", TRUE), label);
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo.bar", TRUE), label);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo.bar", FALSE), label);
|
||||
ASSERT_EQ(widget_find_by_path(w, "foo.bar", FALSE), label);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, "bar", TRUE), label);
|
||||
ASSERT_EQ(widget_find_by_path(w, "bar", TRUE), label);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, "bar", FALSE), (widget_t*)NULL);
|
||||
ASSERT_EQ(widget_find_by_path(w, "bar", FALSE), (widget_t*)NULL);
|
||||
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW_MANAGER ".win.foo.bar", TRUE), label);
|
||||
ASSERT_EQ(widget_find_by_path(w, STR_PROP_WINDOW_MANAGER ".win.foo.bar", TRUE), label);
|
||||
|
||||
widget_destroy(w);
|
||||
}
|
||||
|
6
tools/ui_test/SConscript
Executable file
6
tools/ui_test/SConscript
Executable file
@ -0,0 +1,6 @@
|
||||
import os
|
||||
|
||||
env=DefaultEnvironment().Clone()
|
||||
BIN_DIR=os.environ['BIN_DIR'];
|
||||
|
||||
env.Program(os.path.join(BIN_DIR, 'ui_test'), Glob('ui_test.c'))
|
308
tools/ui_test/ui_test.c
Normal file
308
tools/ui_test/ui_test.c
Normal file
@ -0,0 +1,308 @@
|
||||
/**
|
||||
* File: ui_test.c
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: ui test
|
||||
*
|
||||
* Copyright (c) 2023 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2023-11-04 Li XianJing <lixianjing@zlg.cn> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tkc.h"
|
||||
#include "base/enums.h"
|
||||
#include "base/events.h"
|
||||
#include "base/widget_consts.h"
|
||||
|
||||
#include "conf_io/conf_ini.h"
|
||||
#include "conf_io/conf_node.h"
|
||||
#include "remote_ui/client/remote_ui.h"
|
||||
#include "streams/stream_factory.h"
|
||||
|
||||
static const char* fix_str(const char* str) {
|
||||
return str != NULL ? str : "";
|
||||
}
|
||||
|
||||
static void check_return_code(ret_t ret, const char* expected_ret, const char* name,
|
||||
const char* arg1, const char* arg2, const char* arg3) {
|
||||
if (expected_ret != NULL) {
|
||||
if (ret != ret_code_from_name(expected_ret)) {
|
||||
log_debug("%s failed(%s != %s)\n", name, ret_code_to_name(ret), expected_ret);
|
||||
} else {
|
||||
log_debug("%s (%s %s %s) ok\n", name, fix_str(arg1), fix_str(arg2), fix_str(arg3));
|
||||
}
|
||||
} else {
|
||||
if (ret == RET_OK) {
|
||||
log_debug("%s (%s %s %s) ok\n", name, fix_str(arg1), fix_str(arg2), fix_str(arg3));
|
||||
} else {
|
||||
log_debug("%s (%s %s %s) fail\n", name, fix_str(arg1), fix_str(arg2), fix_str(arg3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void run_script(conf_doc_t* doc, uint32_t times) {
|
||||
ret_t ret = RET_OK;
|
||||
remote_ui_t* ui = NULL;
|
||||
const char* expected_ret = NULL;
|
||||
conf_node_t* iter = conf_node_get_first_child(doc->root);
|
||||
|
||||
while (iter != NULL) {
|
||||
const char* name = conf_node_get_name(iter);
|
||||
|
||||
if (tk_str_eq(name, "create")) {
|
||||
const char* url = conf_node_get_child_value_str(iter, "url", "tcp://localhost:2233");
|
||||
tk_iostream_t* io = tk_stream_factory_create_iostream(url);
|
||||
|
||||
break_if_fail(io != NULL);
|
||||
if (ui != NULL) {
|
||||
remote_ui_destroy(ui);
|
||||
}
|
||||
ui = remote_ui_create(io);
|
||||
iter = iter->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui == NULL) {
|
||||
log_debug("ui is null.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
expected_ret = conf_node_get_child_value_str(iter, "ret", NULL);
|
||||
if (tk_str_eq(name, "login")) {
|
||||
const char* user = conf_node_get_child_value_str(iter, "user", "admin");
|
||||
const char* password = conf_node_get_child_value_str(iter, "password", "admin");
|
||||
ret = remote_ui_login(ui, user, password);
|
||||
check_return_code(ret, expected_ret, name, user, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "create_dir")) {
|
||||
const char* path = conf_node_get_child_value_str(iter, "path", NULL);
|
||||
ret = remote_ui_create_dir(ui, path);
|
||||
check_return_code(ret, expected_ret, name, path, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "remove_dir")) {
|
||||
const char* path = conf_node_get_child_value_str(iter, "path", NULL);
|
||||
ret = remote_ui_remove_dir(ui, path);
|
||||
check_return_code(ret, expected_ret, name, path, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "remove_file")) {
|
||||
const char* filename = conf_node_get_child_value_str(iter, "filename", NULL);
|
||||
ret = remote_ui_remove_file(ui, filename);
|
||||
check_return_code(ret, expected_ret, name, filename, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "upload")) {
|
||||
const char* remote = conf_node_get_child_value_str(iter, "remote", NULL);
|
||||
const char* local = conf_node_get_child_value_str(iter, "local", NULL);
|
||||
ret = remote_ui_upload_file(ui, remote, local);
|
||||
check_return_code(ret, expected_ret, name, remote, local, NULL);
|
||||
} else if (tk_str_eq(name, "download")) {
|
||||
const char* remote = conf_node_get_child_value_str(iter, "remote", NULL);
|
||||
const char* local = conf_node_get_child_value_str(iter, "local", NULL);
|
||||
ret = remote_ui_download_file(ui, remote, local);
|
||||
check_return_code(ret, expected_ret, name, remote, local, NULL);
|
||||
} else if (tk_str_eq(name, "get_dev_info")) {
|
||||
remote_ui_dev_info_t info;
|
||||
ret = remote_ui_get_dev_info(ui, &info);
|
||||
check_return_code(ret, expected_ret, name, info.name, info.os, info.arch);
|
||||
log_debug("width=%d height=%d\n", info.screen_width, info.screen_height);
|
||||
} else if (tk_str_eq(name, "take_screen_shot")) {
|
||||
const char* filename = conf_node_get_child_value_str(iter, "filename", NULL);
|
||||
ret = remote_ui_take_screen_shot(ui, filename);
|
||||
check_return_code(ret, expected_ret, name, filename, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "get_source")) {
|
||||
const char* filename = conf_node_get_child_value_str(iter, "filename", NULL);
|
||||
ret = remote_ui_get_xml_source(ui, filename);
|
||||
check_return_code(ret, expected_ret, name, filename, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "get_manifest")) {
|
||||
const char* filename = conf_node_get_child_value_str(iter, "filename", "manifest.txt");
|
||||
ret = remote_ui_get_manifest(ui, filename);
|
||||
check_return_code(ret, expected_ret, name, filename, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "open_window")) {
|
||||
const char* wname = conf_node_get_child_value_str(iter, "name", NULL);
|
||||
const char* xml = conf_node_get_child_value_str(iter, "xml", NULL);
|
||||
const char* init = conf_node_get_child_value_str(iter, "init", NULL);
|
||||
ret = remote_ui_open_window(ui, wname, xml, init);
|
||||
check_return_code(ret, expected_ret, name, wname, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "close_window")) {
|
||||
const char* wname = conf_node_get_child_value_str(iter, "name", NULL);
|
||||
ret = remote_ui_close_window(ui, wname);
|
||||
check_return_code(ret, expected_ret, name, wname, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "back")) {
|
||||
ret = remote_ui_back_to_prev(ui);
|
||||
check_return_code(ret, expected_ret, name, NULL, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "home")) {
|
||||
ret = remote_ui_back_to_home(ui);
|
||||
check_return_code(ret, expected_ret, name, NULL, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "logout")) {
|
||||
ret = remote_ui_logout(ui);
|
||||
check_return_code(ret, expected_ret, name, NULL, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "set_prop")) {
|
||||
value_t v;
|
||||
const char* target = conf_node_get_child_value_str(iter, "target", NULL);
|
||||
const char* prop = conf_node_get_child_value_str(iter, "name", NULL);
|
||||
const char* value = conf_node_get_child_value_str(iter, "value", NULL);
|
||||
|
||||
value_set_str(&v, value);
|
||||
ret = remote_ui_set_prop(ui, target, prop, &v);
|
||||
check_return_code(ret, expected_ret, name, target, prop, value);
|
||||
} else if (tk_str_eq(name, "get_prop")) {
|
||||
value_t v;
|
||||
const char* target = conf_node_get_child_value_str(iter, "target", NULL);
|
||||
const char* prop = conf_node_get_child_value_str(iter, "name", NULL);
|
||||
const char* value = conf_node_get_child_value_str(iter, "value", NULL);
|
||||
value_set_str(&v, NULL);
|
||||
ret = remote_ui_get_prop(ui, target, prop, &v);
|
||||
if (value != NULL) {
|
||||
if (!tk_str_eq(value, value_str(&v))) {
|
||||
ret = RET_FAIL;
|
||||
}
|
||||
}
|
||||
check_return_code(ret, expected_ret, name, target, prop, value_str(&v));
|
||||
} else if (tk_str_eq(name, "set_theme")) {
|
||||
const char* theme = conf_node_get_child_value_str(iter, "theme", NULL);
|
||||
ret = remote_ui_set_theme(ui, theme);
|
||||
check_return_code(ret, expected_ret, name, theme, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "set_language")) {
|
||||
const char* language = conf_node_get_child_value_str(iter, "language", NULL);
|
||||
ret = remote_ui_set_language(ui, language);
|
||||
check_return_code(ret, expected_ret, name, language, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "exec_fscript")) {
|
||||
str_t str;
|
||||
const char* fscript = conf_node_get_child_value_str(iter, "fscript", NULL);
|
||||
str_init(&str, 1000);
|
||||
ret = remote_ui_exec_fscript(ui, fscript, &str);
|
||||
check_return_code(ret, expected_ret, name, fscript, str.str, NULL);
|
||||
str_reset(&str);
|
||||
} else if (tk_str_eq(name, "send_event")) {
|
||||
event_t* e = NULL;
|
||||
const char* target = conf_node_get_child_value_str(iter, "target", NULL);
|
||||
const char* type = conf_node_get_child_value_str(iter, "type", NULL);
|
||||
const char* key = conf_node_get_child_value_str(iter, "key", NULL);
|
||||
const char* x = conf_node_get_child_value_str(iter, "x", NULL);
|
||||
const char* y = conf_node_get_child_value_str(iter, "y", NULL);
|
||||
break_if_fail(type != NULL);
|
||||
|
||||
if (target == NULL) {
|
||||
target = STR_PROP_WINDOW;
|
||||
}
|
||||
|
||||
if (strstr(type, "pointer") != NULL || strstr(type, "click") != NULL) {
|
||||
pointer_event_t event;
|
||||
if (strstr(type, "down") != NULL) {
|
||||
e = pointer_event_init(&event, EVT_POINTER_DOWN, NULL, tk_atoi(x), tk_atoi(y));
|
||||
} else if (strstr(type, "up") != NULL) {
|
||||
e = pointer_event_init(&event, EVT_POINTER_UP, NULL, tk_atoi(x), tk_atoi(y));
|
||||
} else if (strstr(type, "click") != NULL) {
|
||||
e = pointer_event_init(&event, EVT_CLICK, NULL, tk_atoi(x), tk_atoi(y));
|
||||
} else {
|
||||
e = pointer_event_init(&event, EVT_POINTER_MOVE, NULL, tk_atoi(x), tk_atoi(y));
|
||||
}
|
||||
ret = remote_ui_send_event(ui, target, e);
|
||||
} else if (strstr(type, "key") != NULL) {
|
||||
key_event_t event;
|
||||
const key_type_value_t* kv = keys_type_find(key);
|
||||
break_if_fail(kv != NULL);
|
||||
if (strstr(type, "down") != NULL) {
|
||||
e = key_event_init(&event, EVT_KEY_DOWN, NULL, kv->value);
|
||||
} else {
|
||||
e = key_event_init(&event, EVT_KEY_UP, NULL, kv->value);
|
||||
}
|
||||
ret = remote_ui_send_event(ui, target, e);
|
||||
}
|
||||
check_return_code(ret, expected_ret, name, target, type, NULL);
|
||||
} else if (tk_str_eq(name, "confirm")) {
|
||||
const char* title = conf_node_get_child_value_str(iter, "title", NULL);
|
||||
const char* content = conf_node_get_child_value_str(iter, "content", NULL);
|
||||
ret = remote_ui_show_confirm(ui, title, content);
|
||||
check_return_code(ret, expected_ret, name, title, content, NULL);
|
||||
} else if (tk_str_eq(name, "warn")) {
|
||||
const char* title = conf_node_get_child_value_str(iter, "title", NULL);
|
||||
const char* content = conf_node_get_child_value_str(iter, "content", NULL);
|
||||
ret = remote_ui_show_warn(ui, title, content);
|
||||
check_return_code(ret, expected_ret, name, title, content, NULL);
|
||||
} else if (tk_str_eq(name, "info")) {
|
||||
const char* title = conf_node_get_child_value_str(iter, "title", NULL);
|
||||
const char* content = conf_node_get_child_value_str(iter, "content", NULL);
|
||||
ret = remote_ui_show_info(ui, title, content);
|
||||
check_return_code(ret, expected_ret, name, title, content, NULL);
|
||||
} else if (tk_str_eq(name, "toast")) {
|
||||
const char* content = conf_node_get_child_value_str(iter, "content", NULL);
|
||||
int32_t duration = conf_node_get_child_value_int32(iter, "duration", 3000);
|
||||
ret = remote_ui_show_toast(ui, duration, content);
|
||||
check_return_code(ret, expected_ret, name, content, NULL, NULL);
|
||||
} else if (tk_str_eq(name, "sleep")) {
|
||||
int32_t time_ms = conf_node_get_child_value_int32(iter, "time", 1000);
|
||||
sleep_ms(time_ms);
|
||||
} else if (tk_str_eq(name, "close")) {
|
||||
remote_ui_destroy(ui);
|
||||
ui = NULL;
|
||||
}
|
||||
|
||||
iter = iter->next;
|
||||
|
||||
if (iter == NULL) {
|
||||
iter = conf_node_get_first_child(doc->root);
|
||||
times--;
|
||||
log_debug("=============%u===============\n", times);
|
||||
}
|
||||
|
||||
if (times == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ui != NULL) {
|
||||
remote_ui_destroy(ui);
|
||||
ui = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#include "tkc/data_reader_factory.h"
|
||||
#include "tkc/data_writer_factory.h"
|
||||
#include "tkc/data_writer_file.h"
|
||||
#include "tkc/data_writer_wbuffer.h"
|
||||
#include "tkc/data_reader_file.h"
|
||||
#include "tkc/data_reader_mem.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* data = NULL;
|
||||
conf_doc_t* doc = NULL;
|
||||
const char* input = argc > 1 ? argv[1] : "data/fs_default.ini";
|
||||
uint32_t times = argc > 2 ? tk_atoi(argv[2]) : 1;
|
||||
|
||||
platform_prepare();
|
||||
data_writer_factory_set(data_writer_factory_create());
|
||||
data_reader_factory_set(data_reader_factory_create());
|
||||
data_writer_factory_register(data_writer_factory(), "file", data_writer_file_create);
|
||||
data_reader_factory_register(data_reader_factory(), "file", data_reader_file_create);
|
||||
data_reader_factory_register(data_reader_factory(), "mem", data_reader_mem_create);
|
||||
data_writer_factory_register(data_writer_factory(), "wbuffer", data_writer_wbuffer_create);
|
||||
|
||||
if (argc < 2) {
|
||||
log_debug("Usage: %s config times\n", argv[0]);
|
||||
log_debug(" ex: %s data/tcp.ini\n", argv[0]);
|
||||
log_debug(" ex: %s data/tcp.ini 10\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tk_socket_init();
|
||||
|
||||
data = (char*)file_read(input, NULL);
|
||||
if (data != NULL) {
|
||||
doc = conf_doc_load_ini(data);
|
||||
if (doc != NULL) {
|
||||
run_script(doc, times);
|
||||
conf_doc_destroy(doc);
|
||||
}
|
||||
TKMEM_FREE(data);
|
||||
}
|
||||
|
||||
tk_socket_deinit();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user