• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "js_ability_connection_session_listener.h"
17 
18 #include "dtbcollabmgr_log.h"
19 #include "js_runtime_utils.h"
20 #include "napi_common_util.h"
21 #include "pixel_map_napi.h"
22 
23 namespace OHOS {
24 namespace DistributedCollab {
25 using namespace OHOS::AbilityRuntime;
26 namespace {
27 const std::string TAG = "JsAbilityConnectionSessionListener";
28 }
29 
SetCallback(const napi_value & jsListenerObj)30 void JsAbilityConnectionSessionListener::SetCallback(const napi_value& jsListenerObj)
31 {
32     HILOGI("called.");
33     napi_ref tempRef = nullptr;
34     std::unique_ptr<NativeReference> callbackRef;
35     if (env_ == nullptr) {
36         HILOGE("env_ is nullptr");
37         return;
38     }
39     napi_create_reference(env_, jsListenerObj, 1, &tempRef);
40     callbackRef.reset(reinterpret_cast<NativeReference *>(tempRef));
41     callbackRef_ = std::move(callbackRef);
42 }
43 
CallJsMethod(const EventCallbackInfo & eventCallbackInfo)44 void JsAbilityConnectionSessionListener::CallJsMethod(const EventCallbackInfo& eventCallbackInfo)
45 {
46     CallJsMethodTemplate(eventCallbackInfo);
47 }
48 
CallJsMethod(const CollaborateEventInfo & collaborateEventInfo)49 void JsAbilityConnectionSessionListener::CallJsMethod(const CollaborateEventInfo& collaborateEventInfo)
50 {
51     CallJsMethodTemplate(collaborateEventInfo);
52 }
53 
54 template <typename T>
CallJsMethodTemplate(const T & callbackInfo)55 void JsAbilityConnectionSessionListener::CallJsMethodTemplate(const T& callbackInfo)
56 {
57     HILOGI("called.");
58     if (env_ == nullptr) {
59         HILOGE("env_ is nullptr");
60         return;
61     }
62 
63     auto task = [this, callbackInfo]() {
64         HILOGI("called js method template.");
65         napi_handle_scope scope = nullptr;
66         auto env = this->env_;
67         napi_status result = napi_open_handle_scope(env, &scope);
68         if (result != napi_ok || scope == nullptr) {
69             HILOGE("open handle scope failed!");
70             return;
71         }
72 
73         CallJsMethodInner(callbackInfo);
74         result = napi_close_handle_scope(env, scope);
75         if (result != napi_ok) {
76             HILOGE("close handle scope failed!");
77         }
78         HILOGI("end.");
79     };
80     if (napi_status::napi_ok != napi_send_event(env_, task, napi_eprio_vip)) {
81         HILOGE("send event failed!");
82     }
83 }
84 
CallJsMethodInner(const EventCallbackInfo & eventCallbackInfo)85 void JsAbilityConnectionSessionListener::CallJsMethodInner(const EventCallbackInfo& eventCallbackInfo)
86 {
87     CallJsMethodInnerTemplate(eventCallbackInfo);
88 }
89 
CallJsMethodInner(const CollaborateEventInfo & collaborateEventInfo)90 void JsAbilityConnectionSessionListener::CallJsMethodInner(const CollaborateEventInfo& collaborateEventInfo)
91 {
92     CallJsMethodInnerTemplate(collaborateEventInfo);
93 }
94 
95 template <typename T>
CallJsMethodInnerTemplate(const T & callbackInfo)96 void JsAbilityConnectionSessionListener::CallJsMethodInnerTemplate(const T& callbackInfo)
97 {
98     HILOGI("called.");
99     if (callbackRef_ == nullptr) {
100         HILOGE("callbackRef_ is nullptr");
101         return;
102     }
103 
104     napi_value method = callbackRef_->GetNapiValue();
105     if (method == nullptr) {
106         HILOGE("Failed to get method from object");
107         return;
108     }
109     napi_value argv[] = { WrapEventCallbackInfo(env_, callbackInfo) };
110     napi_call_function(env_, CreateJsUndefined(env_), method, ArraySize(argv), argv, nullptr);
111     HILOGI("end.");
112 }
113 
WrapEventCallbackInfo(napi_env & env,const EventCallbackInfo & eventCallbackInfo)114 napi_value JsAbilityConnectionSessionListener::WrapEventCallbackInfo(napi_env& env,
115     const EventCallbackInfo& eventCallbackInfo)
116 {
117     napi_value jsObject;
118     napi_create_object(env, &jsObject);
119 
120     napi_value jsSessionId;
121     napi_create_int32(env, eventCallbackInfo.sessionId, &jsSessionId);
122     napi_set_named_property(env, jsObject, "sessionId", jsSessionId);
123 
124     napi_value jsEventType;
125     napi_create_string_utf8(env, eventCallbackInfo.eventType.c_str(), NAPI_AUTO_LENGTH, &jsEventType);
126     napi_set_named_property(env, jsObject, "eventType", jsEventType);
127 
128     if (eventCallbackInfo.reason != DisconnectReason::UNKNOW) {
129         napi_value jsReason;
130         napi_create_int32(env, static_cast<int32_t>(eventCallbackInfo.reason), &jsReason);
131         napi_set_named_property(env, jsObject, "reason", jsReason);
132     }
133 
134     if (!eventCallbackInfo.msg.empty()) {
135         napi_value jsMsg;
136         napi_create_string_utf8(env, eventCallbackInfo.msg.c_str(), NAPI_AUTO_LENGTH, &jsMsg);
137         napi_set_named_property(env, jsObject, "msg", jsMsg);
138     }
139 
140     if (eventCallbackInfo.data != nullptr) {
141         napi_value jsDataBuffer = WrapAVTransDataBuffer(env, eventCallbackInfo.data);
142         napi_set_named_property(env, jsObject, "data", jsDataBuffer);
143     }
144 
145     if (eventCallbackInfo.image != nullptr) {
146         napi_value jsPixelMap = Media::PixelMapNapi::CreatePixelMap(env, eventCallbackInfo.image);
147         napi_set_named_property(env, jsObject, "image", jsPixelMap);
148     }
149     return jsObject;
150 }
151 
WrapEventCallbackInfo(napi_env & env,const CollaborateEventInfo & collaborateEventInfo)152 napi_value JsAbilityConnectionSessionListener::WrapEventCallbackInfo(napi_env& env,
153     const CollaborateEventInfo& collaborateEventInfo)
154 {
155     napi_value jsCallbackInfo;
156     napi_create_object(env, &jsCallbackInfo);
157 
158     napi_value jsSessionId;
159     napi_create_int32(env, collaborateEventInfo.sessionId, &jsSessionId);
160     napi_set_named_property(env, jsCallbackInfo, "sessionId", jsSessionId);
161 
162     napi_value jsEventType;
163     napi_create_int32(env, static_cast<int32_t>(collaborateEventInfo.eventType), &jsEventType);
164     napi_set_named_property(env, jsCallbackInfo, "eventType", jsEventType);
165 
166     napi_value jsEventMsg;
167     napi_create_string_utf8(env, collaborateEventInfo.eventMsg.c_str(), NAPI_AUTO_LENGTH, &jsEventMsg);
168     napi_set_named_property(env, jsCallbackInfo, "eventMsg", jsEventMsg);
169 
170     return jsCallbackInfo;
171 }
172 
WrapAVTransDataBuffer(napi_env & env,const std::shared_ptr<AVTransDataBuffer> & dataBuffer)173 napi_value JsAbilityConnectionSessionListener::WrapAVTransDataBuffer(
174     napi_env& env, const std::shared_ptr<AVTransDataBuffer>& dataBuffer)
175 {
176     size_t dataSize = dataBuffer->Size();
177     uint8_t* data = dataBuffer->Data();
178 
179     napi_value arrayBuffer;
180     void* arrayBufferData;
181     NAPI_CALL(env, napi_create_arraybuffer(env, dataSize, &arrayBufferData, &arrayBuffer));
182 
183     int32_t ret = memcpy_s(arrayBufferData, dataSize, data, dataSize);
184     if (ret != EOK) {
185         HILOGE("memory copy failed, ret %{public}d", ret);
186         return nullptr;
187     }
188     return arrayBuffer;
189 }
190 }  // namespace DistributedCollab
191 }  // namespace OHOS