• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define LOG_TAG "DataLoadParamsNapi"
16 #include "data_load_params_napi.h"
17 
18 #include "logger.h"
19 #include "napi_data_utils.h"
20 #include "unified_data_napi.h"
21 #include "udmf_client.h"
22 #include "udmf_utils.h"
23 
24 namespace OHOS {
25 namespace UDMF {
26 ConcurrentMap<std::string, napi_threadsafe_function> DataLoadParamsNapi::tsfns_;
27 
Convert2NativeValue(napi_env env,napi_value in,DataLoadParams & dataLoadParams)28 bool DataLoadParamsNapi::Convert2NativeValue(napi_env env, napi_value in, DataLoadParams &dataLoadParams)
29 {
30     napi_value jsDataLoadInfo = nullptr;
31     NAPI_CALL_BASE(env, napi_get_named_property(env, in, "dataLoadInfo", &jsDataLoadInfo), false);
32     NAPI_CALL_BASE(env, NapiDataUtils::GetValue(env, jsDataLoadInfo, dataLoadParams.dataLoadInfo), false);
33     napi_value jsLoadHandler = nullptr;
34     NAPI_CALL_BASE(env, napi_get_named_property(env, in, "loadHandler", &jsLoadHandler), false);
35     dataLoadParams.dataLoadInfo.sequenceKey = UTILS::GenerateId();
36     tsfns_.Compute(dataLoadParams.dataLoadInfo.sequenceKey, [&](const std::string &k, napi_threadsafe_function &tsfn) {
37         if (tsfn != nullptr) {
38             LOG_WARN(UDMF_KITS_NAPI, "Listener has existed!");
39             napi_release_threadsafe_function(tsfn, napi_tsfn_release);
40             tsfn = nullptr;
41         }
42         napi_value workName;
43         napi_create_string_utf8(env, "threadsafe_function", NAPI_AUTO_LENGTH, &workName);
44         auto status = napi_create_threadsafe_function(env, jsLoadHandler, nullptr, workName, 0, 1, nullptr,
45             nullptr, nullptr, CallDataLoadHandler, &tsfn);
46         if (status != napi_ok) {
47             LOG_ERROR(UDMF_KITS_NAPI, "napi_create_threadsafe_function failed, status=%{public}d", status);
48             return false;
49         }
50         return true;
51     });
52     dataLoadParams.loadHandler = [](const std::string &udKey, const DataLoadInfo &dataLoadInfo) {
53         LOG_INFO(UDMF_KITS_NAPI, "Load handler Start.");
54         auto seqKey = UTILS::GetSequenceKey(udKey);
55         if (seqKey.empty()) {
56             LOG_ERROR(UDMF_KITS_NAPI, "Error udKey:%{public}s", udKey.c_str());
57             return;
58         }
59         bool tsfnExist = tsfns_.ComputeIfPresent(seqKey, [&](const std::string &key, napi_threadsafe_function &tsfn) {
60             DataLoadArgs *infoArgs = new (std::nothrow) DataLoadArgs;
61             if (infoArgs == nullptr) {
62                 LOG_ERROR(UDMF_KITS_NAPI, "No space for dataLoadArgs, udKey=%{public}s", udKey.c_str());
63                 return false;
64             }
65             infoArgs->udKey = udKey;
66             infoArgs->dataLoadInfo = dataLoadInfo;
67             auto status = napi_call_threadsafe_function(tsfn, infoArgs, napi_tsfn_blocking);
68             if (status != napi_ok) {
69                 LOG_ERROR(UDMF_KITS_NAPI, "call func failed,status=%{public}d,udKey=%{public}s", status, udKey.c_str());
70             }
71             napi_release_threadsafe_function(tsfn, napi_tsfn_release);
72             return false;
73         });
74         if (!tsfnExist) { LOG_ERROR(UDMF_KITS_NAPI, "Tsfn not exist, udKey=%{public}s", udKey.c_str()); }
75     };
76     return true;
77 }
78 
CallDataLoadHandler(napi_env env,napi_value callback,void * context,void * data)79 void DataLoadParamsNapi::CallDataLoadHandler(napi_env env, napi_value callback, void *context, void *data)
80 {
81     DataLoadArgs* infoArgs = static_cast<DataLoadArgs*>(data);
82     std::string udKey = infoArgs->udKey;
83     napi_value param;
84     auto status = NapiDataUtils::SetValue(env, infoArgs->dataLoadInfo, param);
85     delete infoArgs;
86     if (status != napi_ok) {
87         LOG_ERROR(UDMF_KITS_NAPI, "SetValue dataLoadInfo failed, status=%{public}d", status);
88         return;
89     }
90     napi_value result = nullptr;
91     status = napi_call_function(env, nullptr, callback, 1, &param, &result);
92     if (status != napi_ok || result == nullptr) {
93         LOG_ERROR(UDMF_KITS_NAPI, "napi_call_function failed, status=%{public}d", status);
94         return;
95     }
96     LOG_INFO(UDMF_KITS_NAPI, "Call napi_call_function end.");
97     napi_valuetype type = napi_undefined;
98     napi_typeof(env, result, &type);
99     if (type == napi_null) {
100         LOG_ERROR(UDMF_KITS_NAPI, "DataLoad has no data");
101         return;
102     }
103     UnifiedDataNapi *unifiedDataNapi = nullptr;
104     status = napi_unwrap(env, result, reinterpret_cast<void **>(&unifiedDataNapi));
105     if (status != napi_ok || unifiedDataNapi == nullptr) {
106         LOG_ERROR(UDMF_KITS_NAPI, "napi_unwrap data failed, status=%{public}d", status);
107         return;
108     }
109 
110     auto ret = UdmfClient::GetInstance().PushDelayData(udKey, *unifiedDataNapi->value_);
111     if (ret != E_OK) {
112         LOG_ERROR(UDMF_KITS_NAPI, "SetData failed, status=%{public}d", ret);
113     }
114 }
115 } // namespace UDMF
116 } // namespace OHOS