1 /*
2 * Copyright (c) 2021 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_print_extension_connection.h"
17 #include "js_data_struct_converter.h"
18 #include "js_extension_context.h"
19 #include "js_runtime.h"
20 #include "js_runtime_utils.h"
21 #include "napi/native_api.h"
22 #include "napi_common_start_options.h"
23 #include "napi_common_util.h"
24 #include "napi_common_want.h"
25 #include "napi_print_utils.h"
26 #include "napi_remote_object.h"
27 #include "print_log.h"
28 #include "start_options.h"
29 #include <shared_mutex>
30
31 using namespace OHOS::Print;
32
33 namespace OHOS {
34 namespace AbilityRuntime {
JSPrintExtensionConnection(napi_env engine)35 JSPrintExtensionConnection::JSPrintExtensionConnection(napi_env engine) : engine_(engine) {}
36
37 JSPrintExtensionConnection::~JSPrintExtensionConnection() = default;
38
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)39 void JSPrintExtensionConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
40 const sptr<IRemoteObject> &remoteObject, int resultCode)
41 {
42 PRINT_HILOGD("OnAbilityConnectDone begin, resultCode:%{public}d", resultCode);
43 if (handler_ == nullptr) {
44 PRINT_HILOGD("handler_ nullptr");
45 return;
46 }
47 wptr<JSPrintExtensionConnection> connection = this;
48 auto task = [connection, element, remoteObject, resultCode]() {
49 sptr<JSPrintExtensionConnection> connectionSptr = connection.promote();
50 if (!connectionSptr) {
51 PRINT_HILOGD("connectionSptr nullptr");
52 return;
53 }
54 connectionSptr->HandleOnAbilityConnectDone(element, remoteObject, resultCode);
55 };
56 handler_->PostTask(task, "OnAbilityConnectDone");
57 }
58
HandleOnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)59 void JSPrintExtensionConnection::HandleOnAbilityConnectDone(const AppExecFwk::ElementName &element,
60 const sptr<IRemoteObject> &remoteObject, int resultCode)
61 {
62 PRINT_HILOGD("HandleOnAbilityConnectDone begin, resultCode:%{public}d", resultCode);
63 // wrap ElementName
64 napi_value nativeElementName = OHOS::AppExecFwk::WrapElementName(engine_, element);
65
66 // wrap RemoteObject
67 PRINT_HILOGD("OnAbilityConnectDone begin NAPI_ohos_rpc_CreateJsRemoteObject");
68 napi_value nativeRemoteObject = NAPI_ohos_rpc_CreateJsRemoteObject(engine_, remoteObject);
69 napi_value argv[] = {nativeElementName, nativeRemoteObject};
70 if (jsConnectionObject_ == nullptr) {
71 PRINT_HILOGE("jsConnectionObject_ nullptr");
72 return;
73 }
74 napi_value obj = jsConnectionObject_->GetNapiValue();
75 if (obj == nullptr) {
76 PRINT_HILOGE("Failed to get object");
77 return;
78 }
79 napi_value methodOnConnect = nullptr;
80 napi_get_named_property(engine_, obj, "onConnect", &methodOnConnect);
81 if (methodOnConnect == nullptr) {
82 PRINT_HILOGE("Failed to get onConnect from object");
83 return;
84 }
85 PRINT_HILOGD("JSPrintExtensionConnection::napi_call_function onConnect, success");
86 napi_value callResult = nullptr;
87 napi_call_function(engine_, obj, methodOnConnect, NapiPrintUtils::ARGC_TWO, argv, &callResult);
88 PRINT_HILOGD("OnAbilityConnectDone end");
89 }
90
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)91 void JSPrintExtensionConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
92 {
93 PRINT_HILOGD("OnAbilityDisconnectDone begin, resultCode:%{public}d", resultCode);
94 if (handler_ == nullptr) {
95 PRINT_HILOGD("handler_ nullptr");
96 return;
97 }
98 wptr<JSPrintExtensionConnection> connection = this;
99 auto task = [connection, element, resultCode]() {
100 sptr<JSPrintExtensionConnection> connectionSptr = connection.promote();
101 if (!connectionSptr) {
102 PRINT_HILOGD("connectionSptr nullptr");
103 return;
104 }
105 connectionSptr->HandleOnAbilityDisconnectDone(element, resultCode);
106 };
107 handler_->PostTask(task, "OnAbilityDisconnectDone");
108 }
109
HandleOnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)110 void JSPrintExtensionConnection::HandleOnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
111 int resultCode)
112 {
113 PRINT_HILOGD("HandleOnAbilityDisconnectDone begin, resultCode:%{public}d", resultCode);
114 napi_value nativeElementName = OHOS::AppExecFwk::WrapElementName(engine_, element);
115 napi_value argv[] = {nativeElementName};
116 if (jsConnectionObject_ == nullptr) {
117 PRINT_HILOGE("jsConnectionObject_ nullptr");
118 return;
119 }
120 napi_value obj = jsConnectionObject_->GetNapiValue();
121 if (obj == nullptr) {
122 PRINT_HILOGE("Failed to get object");
123 return;
124 }
125
126 napi_value method = nullptr;
127 napi_get_named_property(engine_, obj, "onDisconnect", &method);
128 if (method == nullptr) {
129 PRINT_HILOGE("Failed to get onDisconnect from object");
130 return;
131 }
132
133 // release connect
134 PRINT_HILOGD("OnAbilityDisconnectDone connects_.size:%{public}zu", connects_.size());
135 std::string bundleName = element.GetBundleName();
136 std::string abilityName = element.GetAbilityName();
137 auto item = std::find_if(connects_.begin(),
138 connects_.end(),
139 [bundleName, abilityName](
140 const std::map<ConnecttionKey, sptr<JSPrintExtensionConnection>>::value_type &obj) {
141 return (bundleName == obj.first.want.GetBundle()) &&
142 (abilityName == obj.first.want.GetElement().GetAbilityName());
143 });
144 if (item != connects_.end()) {
145 std::unique_lock<std::shared_timed_mutex> lock(managersMutex_);
146 // match bundlename && abilityname
147 connects_.erase(item);
148 PRINT_HILOGD("OnAbilityDisconnectDone erase connects_.size:%{public}zu", connects_.size());
149 }
150 PRINT_HILOGD("OnAbilityDisconnectDone napi_call_function success");
151 napi_value callResult = nullptr;
152 napi_call_function(engine_, obj, method, NapiPrintUtils::ARGC_ONE, argv, &callResult);
153 }
154
SetJsConnectionObject(napi_value jsConnectionObject)155 void JSPrintExtensionConnection::SetJsConnectionObject(napi_value jsConnectionObject)
156 {
157 napi_ref jsRef = nullptr;
158 napi_create_reference(engine_, jsConnectionObject, 1, &jsRef);
159 jsConnectionObject_.reset(reinterpret_cast<NativeReference*>(jsRef));
160 }
161
CallJsFailed(int32_t errorCode)162 void JSPrintExtensionConnection::CallJsFailed(int32_t errorCode)
163 {
164 PRINT_HILOGD("CallJsFailed begin");
165 if (jsConnectionObject_ == nullptr) {
166 PRINT_HILOGE("jsConnectionObject_ nullptr");
167 return;
168 }
169 napi_value obj = jsConnectionObject_->GetNapiValue();
170 if (obj == nullptr) {
171 PRINT_HILOGE("Failed to get object");
172 return;
173 }
174
175 napi_value method = nullptr;
176 napi_get_named_property(engine_, obj, "onFailed", &method);
177 if (method == nullptr) {
178 PRINT_HILOGE("Failed to get onFailed from object");
179 return;
180 }
181
182 napi_value result = nullptr;
183 napi_create_int32(engine_, errorCode, &result);
184 napi_value argv[] = { result };
185 PRINT_HILOGD("CallJsFailed napi_call_function success");
186 napi_value callResult = nullptr;
187 napi_call_function(engine_, obj, method, NapiPrintUtils::ARGC_ONE, argv, &callResult);
188 PRINT_HILOGD("CallJsFailed end");
189 }
190 } // namespace AbilityRuntime
191 } // namespace OHOS