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 "product_adapter.h"
17
18 #include "acelite_config.h"
19 #include "graphic_config.h"
20 #include "js_async_work.h"
21 #include "message_queue_utils.h"
22 #include "module_manager.h"
23 #include "securec.h"
24 #include "js_app_context.h"
25 #include "global.h"
26 #include "string_util.h"
27
28 namespace OHOS {
29 namespace ACELite {
30 /**
31 * Used for holding all the related dfx interfaces assigned from specific implementation.
32 */
33 struct DFXWrapper {
DFXWrapperOHOS::ACELite::DFXWrapper34 DFXWrapper()
35 : eventTag(0),
36 eventSubTag(0),
37 errCodeTag(0),
38 errCodeSubTag(0),
39 eventPrintHandler(nullptr),
40 errCodePrintHandler(nullptr),
41 jsLogOutputHandler(nullptr),
42 nativeMemInfoGetter(nullptr)
43 {
44 }
45 uint8_t eventTag;
46 uint8_t eventSubTag;
47 uint8_t errCodeTag;
48 uint8_t errCodeSubTag;
49 EventPrintHandler eventPrintHandler;
50 ErrCodePrintHandler errCodePrintHandler;
51 JSLogOutputHandler jsLogOutputHandler;
52 NativeMemInfoGetter nativeMemInfoGetter;
53 };
54
55 static DFXWrapper g_dfxWrapper;
56 static TEHandlingHooks g_teHandlingHooks = {nullptr, nullptr};
57 static TerminateAbilityHandler g_termiantingHandler = nullptr;
58 static SetScreenOnVisibleHandler g_setScreenOnHandler = nullptr;
59 static UpdateDefaultFontHandler g_updateDefaultFontHandler = nullptr;
60 static ExtraPresetModulesHook g_extraPresetModulesHooks = {nullptr, nullptr};
61 static RestoreSystemHandler g_restoreSystemHandler = nullptr;
62 static IsPNGSupportedHandler g_isPNGSupportedHandler = nullptr;
63 static SetViewsParaHandler g_setViewsParaHandler = nullptr;
64 // default font styles
65 static char *g_defaultFontFamilyName = nullptr;
66 static uint8_t g_defaultFontSize = 30;
67 static uint16_t g_screenWidth = 454;
68 static uint16_t g_screenHeight = 454;
69
70 // default app private data root path
71 const static char *DEFAULT_APP_DATA_PATH = "user/ace/data/";
72 static const char *DEFAULT_DATA_ROOT_PATH = DEFAULT_APP_DATA_PATH;
73
74 // default device info
75 const static uint8_t DEVICE_TYPE_STR_LEN = 24;
76 const static char *DEFAULT_DEVICE_TYPE_NAME = "smartVision";
77 // smartVision as default
78 static const char *DEVICE_TYPE = DEFAULT_DEVICE_TYPE_NAME;
79
80 // indicating if the ace application is on foreground
81 static bool g_isRenderTickAcceptable = false;
82
InitAceTags(uint8_t * aceTags,uint8_t tagCount)83 void ProductAdapter::InitAceTags(uint8_t *aceTags, uint8_t tagCount)
84 {
85 const uint8_t minCount = 4;
86 if (aceTags == nullptr || tagCount < minCount) {
87 return;
88 }
89 uint8_t index = 0;
90 g_dfxWrapper.eventTag = aceTags[index++];
91 g_dfxWrapper.eventSubTag = aceTags[index++];
92 g_dfxWrapper.errCodeTag = aceTags[index++];
93 g_dfxWrapper.errCodeSubTag = aceTags[index++];
94 }
95
InitTraceHandlers(EventPrintHandler eventHandler,ErrCodePrintHandler errCodeHandler)96 void ProductAdapter::InitTraceHandlers(EventPrintHandler eventHandler, ErrCodePrintHandler errCodeHandler)
97 {
98 g_dfxWrapper.eventPrintHandler = eventHandler;
99 g_dfxWrapper.errCodePrintHandler = errCodeHandler;
100 }
101
InitConsoleNativeHandler(JSLogOutputHandler handler)102 void ProductAdapter::InitConsoleNativeHandler(JSLogOutputHandler handler)
103 {
104 g_dfxWrapper.jsLogOutputHandler = handler;
105 }
106
InitNativeMemPoolHook(NativeMemInfoGetter getter)107 void ProductAdapter::InitNativeMemPoolHook(NativeMemInfoGetter getter)
108 {
109 g_dfxWrapper.nativeMemInfoGetter = getter;
110 }
111
InitExtraModulesGetter(ProductModulesGetter productModuleGetter,PrivateModulesGetter privateModuleGetter)112 void ProductAdapter::InitExtraModulesGetter(ProductModulesGetter productModuleGetter,
113 PrivateModulesGetter privateModuleGetter)
114 {
115 ModuleManager* moduleManager = ModuleManager::GetInstance();
116 if (moduleManager == nullptr) {
117 return;
118 }
119 moduleManager->SetProductModulesGetter(productModuleGetter);
120 moduleManager->SetPrivateModulesGetter(privateModuleGetter);
121 }
122
PrintEventTrace(uint8_t info2,uint8_t info3,uint8_t info4)123 void ProductAdapter::PrintEventTrace(uint8_t info2, uint8_t info3, uint8_t info4)
124 {
125 if (g_dfxWrapper.eventPrintHandler == nullptr || g_dfxWrapper.eventTag == 0 || g_dfxWrapper.eventSubTag == 0) {
126 return;
127 }
128
129 uint8_t subTag = (info2 == 0) ? g_dfxWrapper.eventSubTag : info2;
130 g_dfxWrapper.eventPrintHandler(g_dfxWrapper.eventTag, subTag, info3, info4);
131 }
132
PrintErrCode(uint8_t info2,uint16_t rfu)133 void ProductAdapter::PrintErrCode(uint8_t info2, uint16_t rfu)
134 {
135 if (g_dfxWrapper.errCodePrintHandler == nullptr || g_dfxWrapper.errCodeTag == 0 ||
136 g_dfxWrapper.errCodeSubTag == 0) {
137 return;
138 }
139 g_dfxWrapper.errCodePrintHandler(g_dfxWrapper.errCodeTag, g_dfxWrapper.errCodeSubTag, info2, rfu);
140 }
141
OutputJSConsoleLog(uint8_t level,const char * content)142 void ProductAdapter::OutputJSConsoleLog(uint8_t level, const char *content)
143 {
144 if (g_dfxWrapper.jsLogOutputHandler == nullptr) {
145 return;
146 }
147 g_dfxWrapper.jsLogOutputHandler(level, content);
148 }
149
GetNativeMemInfo(NativeMemInfo * memInfo)150 void ProductAdapter::GetNativeMemInfo(NativeMemInfo *memInfo)
151 {
152 if (g_dfxWrapper.nativeMemInfoGetter == nullptr) {
153 return;
154 }
155
156 g_dfxWrapper.nativeMemInfoGetter(memInfo);
157 }
158
RegTerminatingHandler(TerminateAbilityHandler handler)159 void ProductAdapter::RegTerminatingHandler(TerminateAbilityHandler handler)
160 {
161 g_termiantingHandler = handler;
162 }
163
RegTEHandlers(const TEHandlingHooks & teHandlingHooks)164 void ProductAdapter::RegTEHandlers(const TEHandlingHooks &teHandlingHooks)
165 {
166 g_teHandlingHooks.renderTEHandler = teHandlingHooks.renderTEHandler;
167 g_teHandlingHooks.renderEndHandler = teHandlingHooks.renderEndHandler;
168 }
169
RegRestoreSystemHandler(RestoreSystemHandler handler)170 void ProductAdapter::RegRestoreSystemHandler(RestoreSystemHandler handler)
171 {
172 g_restoreSystemHandler = handler;
173 }
174
RegIsPNGSupportedHandler(IsPNGSupportedHandler handler)175 void ProductAdapter::RegIsPNGSupportedHandler(IsPNGSupportedHandler handler)
176 {
177 g_isPNGSupportedHandler = handler;
178 }
179
RegSetViewsParaHandler(SetViewsParaHandler handler)180 void ProductAdapter::RegSetViewsParaHandler(SetViewsParaHandler handler)
181 {
182 g_setViewsParaHandler = handler;
183 }
184 // NOTE: This TE function will be called in VSYNC interrupt, and
185 // as no any task can be switched to during an interrupt, so it's safe to
186 // read the global value directly here.
DispatchTEMessage()187 TEDispatchingResult ProductAdapter::DispatchTEMessage()
188 {
189 #if (OHOS_ACELITE_PRODUCT_WATCH == 1) // only some specific products support TE dispatching
190 if (!g_isRenderTickAcceptable) {
191 return TEDispatchingResult::REFUSED;
192 }
193
194 if (JsAsyncWork::DispatchToLoop(TE_EVENT, nullptr)) {
195 return TEDispatchingResult::ACCEPTED;
196 }
197 // if the ACE application is on foreground and the dispatching failed, should retry sending to ACE again
198 return TEDispatchingResult::ACCEPT_FAILED;
199 #else
200 return TEDispatchingResult::REFUSED;
201 #endif // OHOS_ACELITE_PRODUCT_WATCH
202 }
203
SendTerminatingRequest(uint32_t token,bool forceStop)204 void ProductAdapter::SendTerminatingRequest(uint32_t token, bool forceStop)
205 {
206 if (g_termiantingHandler != nullptr) {
207 g_termiantingHandler(token, forceStop);
208 }
209 }
210
IsTEHandlersRegisted()211 bool ProductAdapter::IsTEHandlersRegisted()
212 {
213 return (g_teHandlingHooks.renderTEHandler != nullptr);
214 }
215
ProcessOneTE()216 void ProductAdapter::ProcessOneTE()
217 {
218 if (g_teHandlingHooks.renderTEHandler != nullptr) {
219 (void)(g_teHandlingHooks.renderTEHandler());
220 }
221 }
222
NotifyRenderEnd()223 void ProductAdapter::NotifyRenderEnd()
224 {
225 if (g_teHandlingHooks.renderEndHandler != nullptr) {
226 g_teHandlingHooks.renderEndHandler();
227 }
228 }
229
SetDefaultFontStyle(const char * defaultFontFamily,uint8_t defaultFontSize)230 void ProductAdapter::SetDefaultFontStyle(const char *defaultFontFamily, uint8_t defaultFontSize)
231 {
232 g_defaultFontFamilyName = const_cast<char *>(defaultFontFamily);
233 g_defaultFontSize = defaultFontSize;
234 }
235
GetDefaultFontFamilyName()236 const char *ProductAdapter::GetDefaultFontFamilyName()
237 {
238 return (g_defaultFontFamilyName != nullptr) ? g_defaultFontFamilyName : DEFAULT_VECTOR_FONT_FILENAME;
239 }
240
GetDefaultFontSize()241 uint8_t ProductAdapter::GetDefaultFontSize()
242 {
243 return g_defaultFontSize;
244 }
245
UpdateRenderTickAcceptable(bool acceptable)246 void ProductAdapter::UpdateRenderTickAcceptable(bool acceptable)
247 {
248 g_isRenderTickAcceptable = acceptable;
249 }
250
SetScreenSize(uint16_t width,uint16_t height)251 void ProductAdapter::SetScreenSize(uint16_t width, uint16_t height)
252 {
253 g_screenWidth = width;
254 g_screenHeight = height;
255 }
256
GetScreenSize(uint16_t & width,uint16_t & height)257 void ProductAdapter::GetScreenSize(uint16_t &width, uint16_t &height)
258 {
259 width = g_screenWidth;
260 height = g_screenHeight;
261 }
262
RegSetScreenOnVisibleHandler(SetScreenOnVisibleHandler handler)263 void ProductAdapter::RegSetScreenOnVisibleHandler(SetScreenOnVisibleHandler handler)
264 {
265 g_setScreenOnHandler = handler;
266 }
267
RegUpdateDefaultFontHandler(UpdateDefaultFontHandler handler)268 void ProductAdapter::RegUpdateDefaultFontHandler(UpdateDefaultFontHandler handler)
269 {
270 g_updateDefaultFontHandler = handler;
271 }
272
SetScreenOnVisible(bool visible)273 bool ProductAdapter::SetScreenOnVisible(bool visible)
274 {
275 return (g_setScreenOnHandler != nullptr) ? g_setScreenOnHandler(visible) : false;
276 }
277
UpdateDefaultFont()278 bool ProductAdapter::UpdateDefaultFont()
279 {
280 if (g_updateDefaultFontHandler == nullptr) {
281 return false;
282 }
283 char *currentLanguage = static_cast<char *>(ace_malloc(MAX_LANGUAGE_LENGTH));
284 char *currentOrigion = static_cast<char *>(ace_malloc(MAX_REGION_LENGTH));
285 if ((currentLanguage == nullptr) || (currentOrigion == nullptr)) {
286 ACE_FREE(currentLanguage);
287 ACE_FREE(currentOrigion);
288 return false;
289 }
290 GLOBAL_GetLanguage(currentLanguage, MAX_LANGUAGE_LENGTH);
291 GLOBAL_GetRegion(currentOrigion, MAX_REGION_LENGTH);
292
293 uint8_t addedLen = 7; // the length of '-', ".json" and '\0'
294 uint8_t langLen = strlen(currentLanguage);
295 size_t fileLen = langLen + strlen(currentOrigion) + addedLen;
296 char *languageFileName = StringUtil::Malloc(fileLen);
297 if (languageFileName == nullptr) {
298 ACE_FREE(languageFileName);
299 ACE_FREE(currentLanguage);
300 ACE_FREE(currentOrigion);
301 return false;
302 }
303
304 errno_t error = strcpy_s(languageFileName, fileLen, currentLanguage);
305 languageFileName[langLen] = '-';
306 languageFileName[langLen + 1] = '\0';
307 error += strcat_s(languageFileName, fileLen, currentOrigion);
308 error += strcat_s(languageFileName, fileLen, ".json");
309 if (error > 0) {
310 ACE_FREE(languageFileName);
311 ACE_FREE(currentLanguage);
312 ACE_FREE(currentOrigion);
313 return false;
314 }
315 const char * const filePath = JsAppContext::GetInstance()->GetCurrentAbilityPath();
316 const char * const folderName = "i18n";
317 char *curLanguageFilePath = RelocateResourceFilePath(filePath, folderName);
318 curLanguageFilePath = RelocateResourceFilePath(curLanguageFilePath, languageFileName);
319 ACE_FREE(languageFileName);
320
321 bool hasJson = IsFileExisted(curLanguageFilePath);
322 ACE_FREE(curLanguageFilePath);
323 g_updateDefaultFontHandler(currentLanguage, currentOrigion, hasJson);
324 ACE_FREE(currentLanguage);
325 ACE_FREE(currentOrigion);
326 return true;
327 }
328
RegExtraPresetModulesHook(ExtraPresetModulesHook hook)329 void ProductAdapter::RegExtraPresetModulesHook(ExtraPresetModulesHook hook)
330 {
331 g_extraPresetModulesHooks.loadingHandler = hook.loadingHandler;
332 g_extraPresetModulesHooks.unloadingHandler = hook.unloadingHandler;
333 }
334
LoadExtraPresetModules()335 void ProductAdapter::LoadExtraPresetModules()
336 {
337 if (g_extraPresetModulesHooks.loadingHandler != nullptr) {
338 g_extraPresetModulesHooks.loadingHandler();
339 }
340 }
341
UnloadExtraPresetModules()342 void ProductAdapter::UnloadExtraPresetModules()
343 {
344 if (g_extraPresetModulesHooks.unloadingHandler != nullptr) {
345 g_extraPresetModulesHooks.unloadingHandler();
346 }
347 }
348
ConfigPrivateDataRootPath(const char * appDataRoot)349 void ProductAdapter::ConfigPrivateDataRootPath(const char *appDataRoot)
350 {
351 if (appDataRoot == nullptr) {
352 return;
353 }
354 size_t pathLen = strlen(appDataRoot);
355 if (pathLen == 0 || pathLen >= UINT8_MAX) {
356 return;
357 }
358 DEFAULT_DATA_ROOT_PATH = appDataRoot;
359 }
360
GetPrivateDataRootPath()361 const char *ProductAdapter::GetPrivateDataRootPath()
362 {
363 return DEFAULT_DATA_ROOT_PATH;
364 }
365
InitDeviceInfo(const char * deviceType)366 void ProductAdapter::InitDeviceInfo(const char *deviceType)
367 {
368 if (deviceType == nullptr || (strlen(deviceType) == 0) || strlen(deviceType) >= DEVICE_TYPE_STR_LEN) {
369 return;
370 }
371 DEVICE_TYPE = deviceType;
372 }
373
GetDeviceType()374 const char *ProductAdapter::GetDeviceType()
375 {
376 return DEVICE_TYPE;
377 }
378
RestoreSystemWrapper(const char * crashMessage)379 void ProductAdapter::RestoreSystemWrapper(const char *crashMessage)
380 {
381 if (g_restoreSystemHandler != nullptr) {
382 g_restoreSystemHandler(crashMessage);
383 }
384 }
385
IsPNGSupportedWrapper(const char * imagePath,const char * bundleName)386 bool ProductAdapter::IsPNGSupportedWrapper(const char *imagePath, const char *bundleName)
387 {
388 return (g_isPNGSupportedHandler != nullptr) ? g_isPNGSupportedHandler(imagePath, bundleName) : false;
389 }
390
SetViewsParaWrapper(void * ComponentHandler)391 void ProductAdapter::SetViewsParaWrapper(void *ComponentHandler)
392 {
393 if (g_setViewsParaHandler != nullptr) {
394 g_setViewsParaHandler(ComponentHandler);
395 }
396 }
397 } // namespace ACELite
398 } // namespace OHOS
399