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