在本示例将演示如何在系统中添加自定义JS API,达到能通过JS应用关闭灯、开启灯以及翻转灯的状态。希望通过本教程的学习,开发者能掌握如何在OpenHarmony中自定义JS API。
注: 在学习本教程之前,请确保已经完成编写一个点亮LED灯程序实验,因为本实验将依赖编写一个点亮LED灯程序实验中开发的驱动,以下教程篇幅较长,请耐心仔细阅读。
添加控制LED灯的JS API接口
修改foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.h
,加入toggleLed JS API,("##start##"和"##end##"仅用来标识位置,添加完配置后删除这两行)
public:
ACE_DISALLOW_COPY_AND_MOVE(AppModule);
AppModule() = default;
~AppModule() = default;
static JSIValue GetInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
static JSIValue Terminate(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
##start##
static JSIValue ToggleLed(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);
##end##
#ifdef FEATURE_SCREEN_ON_VISIBLE
static JSIValue ScreenOnVisible(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum);
#endif
void InitAppModule(JSIValue exports)
{
JSI::SetModuleAPI(exports, "getInfo", AppModule::GetInfo);
JSI::SetModuleAPI(exports, "terminate", AppModule::Terminate);
##start##
JSI::SetModuleAPI(exports, "ledcontrol", AppModule::ToggleLed);
##end##
#ifdef FEATURE_SCREEN_ON_VISIBLE
JSI::SetModuleAPI(exports, "screenOnVisible", AppModule::ScreenOnVisible);
#endif
}
编写控制LED灯c++ 业务代码
在foundation\ace\ace_engine_lite\frameworks\src\core\modules\app_module.cpp
中加入控制LED灯c++ 业务代码("##start##"和"##end##"仅用来标识位置,添加完配置后删除这两行)。
#include "app_module.h"
#include "ace_log.h"
#include "js_app_context.h"
#ifdef FEATURE_SCREEN_ON_VISIBLE
#include "js_async_work.h"
#include "product_adapter.h"
#endif
##start##
#include "hdf_sbuf.h"
#include "hdf_io_service_if.h"
#define LED_WRITE_READ 1
#define LED_SERVICE "hdf_led"
##end##
namespace OHOS {
namespace ACELite {
const char * const AppModule::FILE_MANIFEST = "manifest.json";
const char * const AppModule::KEY_APP_NAME = "appName";
const char * const AppModule::KEY_VERSION_NAME = "versionName";
const char * const AppModule::KEY_VERSION_CODE = "versionCode";
struct AsyncParams : public MemoryHeap {
ACE_DISALLOW_COPY_AND_MOVE(AsyncParams);
AsyncParams() : result(nullptr), callback(nullptr), context(nullptr) {}
JSIValue result;
JSIValue callback;
JSIValue context;
};
#endif
##start##
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
{
uint32_t value;
HdfSbufReadUint32(data, &value);
HILOG_ERROR(HILOG_MODULE_ACE,"%s: dev event received: %u %u\n", (char *)priv, id, value);
return HDF_SUCCESS;
}
static int GpioWriteRead(struct HdfIoService *serv, int32_t eventData, int32_t *val)
{
int ret = HDF_FAILURE;
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
if (data == NULL || reply == NULL) {
HILOG_ERROR(HILOG_MODULE_ACE,"fail to obtain sbuf data\n");
return ret;
}
if (!HdfSbufWriteUint8(data, (uint8_t)eventData))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to write sbuf\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
ret = serv->dispatcher->Dispatch(&serv->object, LED_WRITE_READ, data, reply);
if (ret != HDF_SUCCESS)
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to send service call\n");
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
if (!HdfSbufReadInt32(reply, val))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service call reply\n");
ret = HDF_ERR_INVALID_OBJECT;
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
HILOG_ERROR(HILOG_MODULE_ACE,"Get reply is: %d\n", val);
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
return ret;
}
JSIValue AppModule::ToggleLed(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
HILOG_ERROR(HILOG_MODULE_ACE, "led button pressed.");
struct HdfIoService *serv = HdfIoServiceBind(LED_SERVICE);
if (serv == NULL)
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service2 %s\n", LED_SERVICE);
return JSI::CreateUndefined();
}
if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {
return JSI::CreateUndefined();
}
JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);
int32_t num = (int32_t)JSI::GetNumberProperty(args[0], "code");
int32_t replyData = 0;
if (GpioWriteRead(serv, num, &replyData))
{
HILOG_ERROR(HILOG_MODULE_ACE,"fail to send event\n");
JSI::CallFunction(fail, thisVal, nullptr, 0);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete);
return JSI::CreateUndefined();
}
JSIValue result = JSI::CreateObject();
JSI::SetNumberProperty(result, "led_status", replyData);
JSIValue argv[ARGC_ONE] = {result};
JSI::CallFunction(success, thisVal, argv, ARGC_ONE);
JSI::CallFunction(complete, thisVal, nullptr, 0);
JSI::ReleaseValueList(success, fail, complete, result);
HdfIoServiceRecycle(serv);
return JSI::CreateUndefined();
}
##end##
JSIValue AppModule::GetInfo(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
JSIValue result = JSI::CreateUndefined();
cJSON *manifest = ReadManifest();
if (manifest == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "Fail to get the content of manifest.");
return result;
}
cJSON *appName = cJSON_GetObjectItem(manifest, KEY_APP_NAME);
cJSON *versionName = cJSON_GetObjectItem(manifest, KEY_VERSION_NAME);
cJSON *versionCode = cJSON_GetObjectItem(manifest, KEY_VERSION_CODE);
result = JSI::CreateObject();
if (appName != nullptr && appName->type == cJSON_String) {
JSI::SetStringProperty(result, KEY_APP_NAME, appName->valuestring);
}
if (versionName != nullptr && versionName->type == cJSON_String) {
JSI::SetStringProperty(result, KEY_VERSION_NAME, versionName->valuestring);
}
if (versionCode != nullptr && versionCode->type == cJSON_Number) {
JSI::SetNumberProperty(result, KEY_VERSION_CODE, versionCode->valuedouble);
}
cJSON_Delete(manifest);
manifest = nullptr;
return result;
}
配置HDF头文件路径
在foundation\ace\ace_engine_lite\ace_lite.gni
中添加HDF头文件路径。
ace_lite_include_dirs += [
"//drivers/framework/ability/sbuf/include",
"//drivers/framework/include/core",
"//drivers/framework/include/utils",
"//drivers/adapter/uhdf/posix/include",
]
添加编译依赖
修改foundation\ace\ace_engine_lite\frameworks\BUILD.gn
,在public_deps
中添加以下代码
"//drivers/adapter/uhdf/manager:hdf_core",
修改foundation\ace\ace_engine_lite\test\ace_test_config.gni
,在extra_deps
中添加以下代码
"//drivers/adapter/uhdf/manager:hdf_core",
示例代码编译、烧录后,参考如何在开发板上安装HAP应用教程安装applications/BearPi/BearPi-HM_Micro/tools/hap_tools/hap_example目录下的LED.hap应用进行测试
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。