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 "cj_lambda.h"
17 #include "cj_utils_ffi.h"
18 #include "cj_want_agent_ffi.h"
19 #include "hilog_tag_wrapper.h"
20 #include "js_native_api.h"
21 #include "napi/native_api.h"
22 #include "start_options.h"
23 #include "want_agent_helper.h"
24 #include "want_params_wrapper.h"
25
26 namespace OHOS {
27 namespace FfiWantAgent {
28
29 using OHOS::AbilityRuntime::WantAgent::WantAgent;
30 using OHOS::FFI::FFIData;
31
32 namespace {
33
34 constexpr int32_t INVALID_REMOTE_DATA_ID = -1;
35
WrapWantAgent(napi_env env,WantAgent * wantAgent)36 napi_value WrapWantAgent(napi_env env, WantAgent* wantAgent)
37 {
38 TAG_LOGD(AAFwkTag::WANTAGENT, "called");
39 napi_value wantAgentClass = nullptr;
40 napi_define_class(
41 env, "WantAgentClass", NAPI_AUTO_LENGTH,
42 [](napi_env env, napi_callback_info info) -> napi_value {
43 napi_value thisVar = nullptr;
44 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
45 return thisVar;
46 },
47 nullptr, 0, nullptr, &wantAgentClass);
48 napi_value result = nullptr;
49 napi_new_instance(env, wantAgentClass, 0, nullptr, &result);
50 if (result == nullptr) {
51 TAG_LOGE(AAFwkTag::WANTAGENT, "create instance failed");
52 delete wantAgent;
53 wantAgent = nullptr;
54 return nullptr;
55 }
56
57 auto res = napi_wrap(
58 env, result, reinterpret_cast<void*>(wantAgent),
59 [](napi_env env, void* data, void* hint) {
60 TAG_LOGD(AAFwkTag::WANTAGENT, "delete wantAgent");
61 auto agent = static_cast<WantAgent*>(data);
62 delete agent;
63 agent = nullptr;
64 },
65 nullptr, nullptr);
66 if (res != napi_ok && wantAgent != nullptr) {
67 TAG_LOGE(AAFwkTag::WANTAGENT, "napi_wrap failed:%{public}d", res);
68 delete wantAgent;
69 wantAgent = nullptr;
70 return nullptr;
71 }
72 return result;
73 }
74
CheckTypeForNapiValue(napi_env env,napi_value param,napi_valuetype expectType)75 bool CheckTypeForNapiValue(napi_env env, napi_value param, napi_valuetype expectType)
76 {
77 napi_valuetype valueType = napi_undefined;
78 if (napi_typeof(env, param, &valueType) != napi_ok) {
79 return false;
80 }
81 return valueType == expectType;
82 }
83
UnwrapWantAgent(napi_env env,napi_value jsParam,void ** result)84 void UnwrapWantAgent(napi_env env, napi_value jsParam, void** result)
85 {
86 TAG_LOGD(AAFwkTag::WANTAGENT, "called");
87 if (jsParam == nullptr) {
88 TAG_LOGE(AAFwkTag::WANTAGENT, "null jsParam");
89 return;
90 }
91
92 if (!CheckTypeForNapiValue(env, jsParam, napi_object)) {
93 TAG_LOGE(AAFwkTag::WANTAGENT, "jsParam type error");
94 return;
95 }
96
97 napi_unwrap(env, jsParam, result);
98 }
99 } // namespace
100
101 extern "C" {
FfiConvertWantAgent2Napi(napi_env env,int64_t id)102 napi_value FfiConvertWantAgent2Napi(napi_env env, int64_t id)
103 {
104 napi_value undefined = nullptr;
105 napi_get_undefined(env, &undefined);
106 auto cjWantAgent = FFIData::GetData<CJWantAgent>(id);
107 if (cjWantAgent == nullptr || cjWantAgent->wantAgent_ == nullptr) {
108 TAG_LOGE(AAFwkTag::WANTAGENT, "cj wantagent nullptr");
109 return undefined;
110 }
111 WantAgent* agent = new WantAgent(cjWantAgent->wantAgent_->GetPendingWant());
112 if (agent == nullptr) {
113 TAG_LOGE(AAFwkTag::WANTAGENT, "cj wantaget malloc failed");
114 return undefined;
115 }
116
117 return WrapWantAgent(env, agent);
118 }
119
FfiCreateWantAgentFromNapi(napi_env env,napi_value wantAgent)120 int64_t FfiCreateWantAgentFromNapi(napi_env env, napi_value wantAgent)
121 {
122 if (env == nullptr || wantAgent == nullptr) {
123 return INVALID_REMOTE_DATA_ID;
124 }
125 WantAgent* napiAgent = nullptr;
126 UnwrapWantAgent(env, wantAgent, reinterpret_cast<void**>(&napiAgent));
127 if (napiAgent == nullptr) {
128 return INVALID_REMOTE_DATA_ID;
129 }
130
131 auto nativeWantAgent = FFIData::Create<CJWantAgent>(std::make_shared<WantAgent>(napiAgent->GetPendingWant()));
132 if (nativeWantAgent == nullptr) {
133 return INVALID_REMOTE_DATA_ID;
134 }
135
136 return nativeWantAgent->GetID();
137 }
138 }
139 } // namespace FfiWantAgent
140 } // namespace OHOS