diff --git a/BUILD.gn b/BUILD.gn index de26b37a2f6104bfb0235684b6d28b5ab1928649..48f1657a48e70f4c6a798336883770bf56eac27f 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -148,4 +148,7 @@ group("syscap_codec") { ":syscap_interface_shared", ":syscap_tool_shared", ] + if (support_jsapi) { + deps += [ "napi:systemcapability" ] + } } diff --git a/napi/BUILD.gn b/napi/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..7c27751254b694eb48929e4c186778d32a5d9e53 --- /dev/null +++ b/napi/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (C) 2022-2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("//build/ohos/ace/ace.gni") + +base_output_path = get_label_info(":query_syscap", "target_out_dir") +query_syscap_obj_path = base_output_path + "/query_syscap.o" + +gen_js_obj("query_syscap_js") { + input = "query_syscap.js" + output = query_syscap_obj_path +} + +sources_platform_common = [ + "../src/syscap_tool.c", + "../src/create_pcid.c", + "../src/endian_internal.c", + "../interfaces/inner_api/syscap_interface.c", +] + +ohos_shared_library("systemcapability") { + include_dirs = [ + "//third_party/node/src", + "//foundation/ace/napi/interfaces/kits", + "//developtools/syscap_codec/napi", + "//developtools/syscap_codec/interfaces/inner_api", + "//developtools/syscap_codec/include", + ] + + sources = [ "napi_query_syscap.cpp" ] + sources += sources_platform_common + + deps = [ + ":query_syscap_js", + "//third_party/bounds_checking_function:libsec_static", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "napi:ace_napi", + ] + + if (defined(ohos_lite)) { + deps += [ "//build/lite/config/component/cJSON:cjson_static" ] + } else { + deps += [ "//third_party/cJSON:cjson_static" ] + } + + relative_install_dir = "module" + subsystem_name = "developtools" + part_name = "syscap_codec" +} diff --git a/napi/napi_query_syscap.cpp b/napi/napi_query_syscap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..71dc4a4b9639e8122af3e9c500e51b28e11033dd --- /dev/null +++ b/napi/napi_query_syscap.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "hilog/log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "syscap_interface.h" + +namespace OHOS { +EXTERN_C_START +constexpr size_t OS_SYSCAP_U32_NUM = 30; +constexpr size_t U32_TO_STR_MAX_LEN = 11; +constexpr size_t SYSCAP_STR_MAX_LEN = 128; +constexpr size_t KEY_BUFFER_SIZE = 32; + +#define PRINT_ERR(...) \ + do { \ + printf("ERROR: in file %s at line %d -> ", __FILE__, __LINE__); \ + printf(__VA_ARGS__); \ + } while (0) + +#define GET_PARAMS(env, info, num) \ + size_t argc = num; \ + napi_value argv[num] = {0}; \ + napi_value thisVar = nullptr; \ + void *data; \ + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) + +// Async Function Set +struct systemCapabilityAsyncContext { + napi_env env = nullptr; + napi_async_work work = nullptr; + char key[KEY_BUFFER_SIZE] = { 0 }; + size_t keyLen = 0; + char *value = nullptr; + size_t valueLen = 0; + napi_deferred deferred = nullptr; + napi_ref callbackRef = nullptr; + + int status = 0; +}; + +static char* getSystemCapability() +{ + bool retBool; + int retError, priOutputLen, priCapArrayCnt, sumLen; + int i = 0; + int *osOutput = nullptr; + errno_t err = EOK; + uint32_t *osCapU32 = nullptr; + char *priOutput = nullptr; + char *temp = nullptr; + char *allSyscapBUffer = nullptr; + char osCapArray[OS_SYSCAP_U32_NUM][U32_TO_STR_MAX_LEN] = {}; + char (*priCapArray)[SYSCAP_STR_MAX_LEN] = nullptr; + + retBool = EncodeOsSyscap(&osOutput); + if (!retBool) { + PRINT_ERR("get encoded os syscap failed."); + goto FREE_OSOUTPUT; + } + retBool = EncodePrivateSyscap(&priOutput, &priOutputLen); + if (!retBool) { + PRINT_ERR("get encoded private syscap failed."); + goto FREE_PRIOUTPUT; + } + + osCapU32 = reinterpret_cast(osOutput + 2); // 2, header of pcid.sc + for (i = 0; i < OS_SYSCAP_U32_NUM; i++) { + retError = sprintf_s(osCapArray[i], U32_TO_STR_MAX_LEN, "%u", osCapU32[i]); + if (retError == -1) { + PRINT_ERR("get uint32_t syscap string failed."); + goto FREE_PRIOUTPUT; + } + } + + retBool = DecodePrivateSyscap(priOutput, &priCapArray, &priCapArrayCnt); + if (!retBool) { + PRINT_ERR("get encoded private syscap failed."); + goto FREE_PRICAP_ARRAY; + } + + // calculate all string length + sumLen = 0; + for (i = 0; i < OS_SYSCAP_U32_NUM; i++) { + sumLen += strlen(osCapArray[i]); + } + for (i = 0; i < priCapArrayCnt; i++) { + sumLen += strlen(*(priCapArray + i)); + } + sumLen += (OS_SYSCAP_U32_NUM + priCapArrayCnt + 1); // split with ',' + + // splicing string + allSyscapBUffer = (char *)malloc(sumLen); + if (allSyscapBUffer == nullptr) { + PRINT_ERR("malloc failed!"); + goto FREE_PRICAP_ARRAY; + } + err = memset_s(allSyscapBUffer, sumLen, 0, sumLen); + if (err != EOK) { + PRINT_ERR("memset failed!"); + free(allSyscapBUffer); + allSyscapBUffer = nullptr; + goto FREE_PRICAP_ARRAY; + } + temp = *osCapArray; + + for (i = 1; i < OS_SYSCAP_U32_NUM; i++) { + retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, osCapArray[i]); + if (retError == -1) { + PRINT_ERR("splicing os syscap string failed."); + free(allSyscapBUffer); + allSyscapBUffer = nullptr; + goto FREE_PRICAP_ARRAY; + } + temp = allSyscapBUffer; + } + for (i = 0; i < priCapArrayCnt; i++) { + retError = sprintf_s(allSyscapBUffer, sumLen, "%s,%s", temp, *(priCapArray + i)); + if (retError == -1) { + PRINT_ERR("splicing pri syscap string failed."); + free(allSyscapBUffer); + allSyscapBUffer = nullptr; + goto FREE_PRICAP_ARRAY; + } + temp = allSyscapBUffer; + } + +FREE_PRICAP_ARRAY: + free(priCapArray); +FREE_PRIOUTPUT: + free(priOutput); +FREE_OSOUTPUT: + free(osOutput); + temp = nullptr; + + return allSyscapBUffer; +} + +napi_value QuerySystemCapability(napi_env env, napi_callback_info info) +{ + GET_PARAMS(env, info, 1); + NAPI_ASSERT(env, argc <= 1, "too many parameters"); + napi_value result = nullptr; + + systemCapabilityAsyncContext* asyncContext = new systemCapabilityAsyncContext(); + + asyncContext->env = env; + + napi_valuetype valueType = napi_undefined; + if (argc == 1) { + napi_typeof(env, argv[0], &valueType); + } + if (valueType == napi_function) { + napi_create_reference(env, argv[0], 1, &asyncContext->callbackRef); + } + + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "napi_value QuerySystemCapability", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work( + env, nullptr, resource, + [](napi_env env, void* data) { + systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; + char *syscapStr = getSystemCapability(); + if (syscapStr != nullptr) { + asyncContext->value = syscapStr; + asyncContext->status = 0; + } else { + asyncContext->status = 1; + } + }, + [](napi_env env, napi_status status, void* data) { + systemCapabilityAsyncContext *asyncContext = (systemCapabilityAsyncContext *)data; + napi_value result[2] = {0}; + if (!asyncContext->status) { + napi_get_undefined(env, &result[0]); + napi_create_string_utf8(env, asyncContext->value, strlen(asyncContext->value), &result[1]); // ? + } else { + napi_value message = nullptr; + napi_create_string_utf8(env, "key does not exist", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result[0]); + napi_get_undefined(env, &result[1]); + } + if (asyncContext->deferred) { + if (!asyncContext->status) { + napi_resolve_deferred(env, asyncContext->deferred, result[1]); + } else { + napi_reject_deferred(env, asyncContext->deferred, result[0]); + } + } else { + napi_value callback = nullptr; + napi_value returnVal; + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + napi_call_function(env, nullptr, callback, 2, result, &returnVal); // 2, count of result + napi_delete_reference(env, asyncContext->callbackRef); + } + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + + return result; +} + +napi_value QuerryExport(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("querySystemCapabilities", QuerySystemCapability), + }; + + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; +} +EXTERN_C_END + +/* + * Module define + */ +static napi_module systemCapabilityModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = QuerryExport, + .nm_modname = "systemCapability", + .nm_priv = ((void*)0), + .reserved = {0}, +}; + +/* + * Module register function + */ +extern "C" __attribute__((constructor)) void systemCapabilityRegisterModule(void) +{ + napi_module_register(&systemCapabilityModule); +} +} \ No newline at end of file diff --git a/napi/query_syscap.js b/napi/query_syscap.js new file mode 100644 index 0000000000000000000000000000000000000000..6b9bfcd3d460f60b1d819c2d93c86fe599ce94cf --- /dev/null +++ b/napi/query_syscap.js @@ -0,0 +1,7 @@ +// 首先需要通过requireInternal函数加载本模块 +const systemCapability = requireInternal('systemCapability'); + +// 这里定义了calc模块对外暴露的所有api +export default { + querySystemCapabilities: systemCapability.querySystemCapabilities +} \ No newline at end of file