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 <cstdint>
17 #include <string>
18 #include <cstdio>
19
20 #include "plugin_common.h"
21 #include "plugin_manager.h"
22
23 enum class ContextType {
24 APP_LIFECYCLE = 0,
25 JS_PAGE_LIFECYCLE,
26 };
27
28 PluginManager PluginManager::manager_;
29
GetContext(napi_env env,napi_callback_info info)30 napi_value PluginManager::GetContext(napi_env env, napi_callback_info info)
31 {
32 napi_status status;
33 napi_value exports;
34 size_t argc = 1;
35 napi_value args[1];
36 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
37
38 if (argc != 1) {
39 napi_throw_type_error(env, NULL, "Wrong number of arguments");
40 return nullptr;
41 }
42
43 napi_valuetype valuetype;
44 status = napi_typeof(env, args[0], &valuetype);
45 if (status != napi_ok) {
46 return nullptr;
47 }
48 if (valuetype != napi_number) {
49 napi_throw_type_error(env, NULL, "Wrong arguments");
50 return nullptr;
51 }
52
53 int64_t value;
54 NAPI_CALL(env, napi_get_value_int64(env, args[0], &value));
55
56 NAPI_CALL(env, napi_create_object(env, &exports));
57
58 switch (value) {
59 case int64_t(ContextType::APP_LIFECYCLE):
60 {
61 /**** AppInit 对应 app.ets中的应用生命周期 onCreate, onShow, onHide, onDestroy ******/
62 LOGD("GetContext APP_LIFECYCLE");
63 /**** Register App Lifecycle ******/
64 napi_property_descriptor desc[] = {
65 DECLARE_NAPI_FUNCTION("onCreate", PluginManager::NapiOnCreate),
66 DECLARE_NAPI_FUNCTION("onShow", PluginManager::NapiOnShow),
67 DECLARE_NAPI_FUNCTION("onHide", PluginManager::NapiOnHide),
68 DECLARE_NAPI_FUNCTION("onDestroy", PluginManager::NapiOnDestroy),
69 };
70 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
71 }
72
73 break;
74 case int64_t(ContextType::JS_PAGE_LIFECYCLE):
75 {
76 /**************** 声明式开发范式 JS Page 生命周期注册 ****************************/
77 LOGD("GetContext JS_PAGE_LIFECYCLE");
78 napi_property_descriptor desc[] = {
79 DECLARE_NAPI_FUNCTION("onPageShow", PluginManager::NapiOnPageShow),
80 DECLARE_NAPI_FUNCTION("onPageHide", PluginManager::NapiOnPageHide),
81 };
82 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
83 }
84 break;
85 default:
86 LOGE("unknown type");
87 }
88 return exports;
89 }
90
Export(napi_env env,napi_value exports)91 bool PluginManager::Export(napi_env env, napi_value exports)
92 {
93 napi_status status;
94 napi_value exportInstance = nullptr;
95 OH_NativeXComponent *nativeXComponent = nullptr;
96 int32_t ret;
97 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { };
98 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
99
100 status = napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
101 if (status != napi_ok) {
102 return false;
103 }
104
105 status = napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
106 if (status != napi_ok) {
107 return false;
108 }
109
110 ret = OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
111 if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
112 return false;
113 }
114
115 std::string id(idStr);
116 auto context = PluginManager::GetInstance();
117 if (context) {
118 context->SetNativeXComponent(id, nativeXComponent);
119 auto render = context->GetRender(id);
120 render->SetNativeXComponent(nativeXComponent);
121 render->Export(env, exports);
122 return true;
123 }
124
125 return false;
126 }
127
SetNativeXComponent(std::string & id,OH_NativeXComponent * nativeXComponent)128 void PluginManager::SetNativeXComponent(std::string& id, OH_NativeXComponent* nativeXComponent)
129 {
130 if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
131 nativeXComponentMap_[id] = nativeXComponent;
132 } else {
133 if (nativeXComponentMap_[id] != nativeXComponent) {
134 nativeXComponentMap_[id] = nativeXComponent;
135 }
136 }
137 }
138
GetNativeXComponent(std::string & id)139 OH_NativeXComponent* PluginManager::GetNativeXComponent(std::string& id)
140 {
141 if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
142 return nullptr;
143 } else {
144 return nativeXComponentMap_[id];
145 }
146 }
147
GetRender(std::string & id)148 PluginRender* PluginManager::GetRender(std::string& id)
149 {
150 if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) {
151 PluginRender* instance = PluginRender::GetInstance(id);
152 pluginRenderMap_[id] = instance;
153 return instance;
154 } else {
155 return pluginRenderMap_[id];
156 }
157 }
158
MainOnMessage(const uv_async_t * req)159 void PluginManager::MainOnMessage(const uv_async_t* req)
160 {
161 LOGD("MainOnMessage Triggered");
162 }
NapiOnCreate(napi_env env,napi_callback_info info)163 napi_value PluginManager::NapiOnCreate(napi_env env, napi_callback_info info)
164 {
165 LOGD("PluginManager::NapiOnCreate");
166 uv_loop_t* loop = nullptr;
167 NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
168 PluginManager::GetInstance()->OnCreateNative(env, loop);
169 return nullptr;
170 }
171
NapiOnShow(napi_env env,napi_callback_info info)172 napi_value PluginManager::NapiOnShow(napi_env env, napi_callback_info info)
173 {
174 PluginManager::GetInstance()->OnShowNative();
175 return nullptr;
176 }
177
NapiOnHide(napi_env env,napi_callback_info info)178 napi_value PluginManager::NapiOnHide(napi_env env, napi_callback_info info)
179 {
180 PluginManager::GetInstance()->OnHideNative();
181 return nullptr;
182 }
183
NapiOnDestroy(napi_env env,napi_callback_info info)184 napi_value PluginManager::NapiOnDestroy(napi_env env, napi_callback_info info)
185 {
186 PluginManager::GetInstance()->OnDestroyNative();
187 return nullptr;
188 }
189
OnCreateNative(napi_env env,uv_loop_t * loop)190 void PluginManager::OnCreateNative(napi_env env, uv_loop_t* loop)
191 {
192 mainEnv_ = env;
193 mainLoop_ = loop;
194 if (mainLoop_) {
195 uv_async_init(mainLoop_, &mainOnMessageSignal_, reinterpret_cast<uv_async_cb>(PluginManager::MainOnMessage));
196 }
197 }
198
OnShowNative()199 void PluginManager::OnShowNative()
200 {
201 LOGD("PluginManager::OnShowNative");
202 }
OnHideNative()203 void PluginManager::OnHideNative()
204 {
205 LOGD("PluginManager::OnHideNative");
206 }
OnDestroyNative()207 void PluginManager::OnDestroyNative()
208 {
209 LOGD("PluginManager::OnDestroyNative");
210 }
211
NapiOnPageShow(napi_env env,napi_callback_info info)212 napi_value PluginManager::NapiOnPageShow(napi_env env, napi_callback_info info)
213 {
214 LOGD("PluginManager::NapiOnPageShow");
215 return nullptr;
216 }
217
NapiOnPageHide(napi_env env,napi_callback_info info)218 napi_value PluginManager::NapiOnPageHide(napi_env env, napi_callback_info info)
219 {
220 LOGD("PluginManager::NapiOnPageHide");
221 return nullptr;
222 }
223
OnPageShowNative()224 void PluginManager::OnPageShowNative()
225 {
226 LOGD("PluginManager::OnPageShowNative");
227 }
228
OnPageHideNative()229 void PluginManager::OnPageHideNative()
230 {
231 LOGD("PluginManager::OnPageHideNative");
232 }