1 /*
2 * Copyright (c) 2023 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 "JsAppImpl.h"
17
18 #include "engines/gfx/gfx_engine_manager.h"
19 #include "font/ui_font.h"
20 #include "font/ui_font_bitmap.h"
21 #include "font/ui_font_header.h"
22 #include "font/ui_font_vector.h"
23 #include "font/ui_line_break.h"
24 #include "font/ui_text_shaping.h"
25 #include "gfx_utils/color.h"
26 #include "gfx_utils/file.h"
27 #include "global.h"
28 #include "graphic_startup.h"
29 #include "input_device_manager.h"
30 #include "js_debugger_config.h"
31 #include "product_adapter.h"
32 #include "screen_device.h"
33
34 #include "AsyncWorkManager.h"
35 #include "CommandParser.h"
36 #include "CppTimerManager.h"
37 #include "FileSystem.h"
38 #include "LanguageManagerImpl.h"
39 #include "MouseInputImpl.h"
40 #include "MouseWheelImpl.h"
41 #include "PreviewerEngineLog.h"
42 #include "SharedData.h"
43 #include "TimerTaskHandler.h"
44 #include "TraceTool.h"
45 #include "VirtualScreenImpl.h"
46 #include "json.h"
47 #include "ui_text_language.h"
48
49 using namespace OHOS;
50 using namespace ACELite;
51 using namespace std;
52
53 static uint8_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH];
54 #if defined(LITEWEARABLE_SUPPORTED)
55 static uint8_t g_shapePsramBaseAddr[MIN_SHAPING_PSRAM_LENGTH];
56 #endif
InitSmartVisionFont(UIFont * font,const string fontPath)57 static void InitSmartVisionFont(UIFont* font, const string fontPath)
58 {
59 ProductAdapter::SetDefaultFontStyle("SourceHanSansSC-Regular.otf", JsAppImpl::FONT_SIZE_DEFAULT);
60 BaseFont* currentFont = new UIFontVector();
61 if (currentFont == nullptr) {
62 FLOG("InitSmartVisionFont currentFont memory allocation failed");
63 return;
64 }
65 font->SetFont(currentFont);
66 font->SetPsramMemory(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH);
67 int8_t ret = font->SetFontPath(fontPath.data(), BaseFont::DYNAMIC_FONT);
68 if (ret != 0) {
69 ELOG("The vector font path does not exist ! fontPath : %s", fontPath.data());
70 FLOG("InitFontEngine SetFontPath failed. vector fontPath: %s", fontPath.data());
71 }
72 font->RegisterFontInfo("SourceHanSansSC-Regular.otf");
73 font->RegisterFontInfo("HYQiHei-65S.otf");
74 font->RegisterFontInfo("RobotoCondensed-Regular.ttf");
75 }
76
InitLiteWearable(UIFont * font,const string fontPath)77 static void InitLiteWearable(UIFont* font, const string fontPath)
78 {
79 ProductAdapter::SetDefaultFontStyle("HYQiHei-65S", JsAppImpl::FONT_SIZE_DEFAULT);
80 BitmapFontInit();
81 BaseFont* currentFont = new UIFontBitmap();
82 if (currentFont == nullptr) {
83 FLOG("InitLiteWearable currentFont memory allocation failed");
84 return;
85 }
86 font->SetFont(currentFont);
87 font->SetPsramMemory(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH);
88 int8_t retDynamic = font->SetFontPath(string(fontPath + "font.bin").data(), BaseFont::DYNAMIC_FONT);
89 int8_t retStatic = font->SetFontPath(string(fontPath + "glyphs.bin").data(), BaseFont::STATIC_FONT);
90 if ((retDynamic != 0) || (retStatic != 0)) {
91 ELOG("The bitmap font path does not exist ! bitmap fontPath : %s",
92 string(fontPath + "font.bin").data());
93 FLOG("InitFontEngine SetFontPath failed. bitmap fontPath: %s", string(fontPath + "font.bin").data());
94 }
95 if (SharedData<string>::GetData(SharedDataType::LANGUAGE) == "zh-CN") {
96 font->SetCurrentLangId(LANGUAGE_CH);
97 }
98 if (SharedData<string>::GetData(SharedDataType::LANGUAGE) == "en-US") {
99 font->SetCurrentLangId(LANGUAGE_GB);
100 }
101 }
102
InitFontEngine()103 static void InitFontEngine()
104 {
105 UIFont* font = UIFont::GetInstance();
106 if (font == nullptr) {
107 ELOG("InitFontEngine:font is nullptr");
108 return;
109 }
110 std::string deviceType = CommandParser::GetInstance().GetDeviceType();
111 std::string separator = FileSystem::GetSeparator();
112 std::string fontPath = FileSystem::GetApplicationPath() + separator + ".." + separator + "config" + separator;
113 if (deviceType == "smartVision") {
114 InitSmartVisionFont(font, fontPath);
115 }
116 if (deviceType == "liteWearable") {
117 InitLiteWearable(font, fontPath);
118 }
119
120 #if defined(LITEWEARABLE_SUPPORTED)
121 UITextShaping* pShaping = UITextShaping::GetInstance();
122 int8_t ret = pShaping->SetPsramMemory(reinterpret_cast<uintptr_t>(g_shapePsramBaseAddr), MIN_SHAPING_PSRAM_LENGTH);
123 if (ret != INVALID_RET_VALUE) {
124 int32_t fp = 0;
125 string fileName = fontPath + "line_cj.brk";
126 #ifdef _WIN32
127 fp = open(fileName.c_str(), O_RDONLY | O_BINARY);
128 #else
129 fp = open(fileName.c_str(), O_RDONLY);
130 #endif
131 if (fp < 0) {
132 ELOG("Open font path failed.");
133 return;
134 }
135 uint32_t lineBrkSize = lseek(fp, 0, SEEK_END);
136 lseek(fp, 0, SEEK_SET);
137 UILineBreakEngine& lbEngine = UILineBreakEngine::GetInstance();
138 lbEngine.SetRuleBinInfo(fp, 0, lineBrkSize);
139 lbEngine.Init();
140 }
141 #endif
142 }
143
InitHalScreen()144 static void InitHalScreen()
145 {
146 InputDeviceManager::GetInstance()->Add(&MouseInputImpl::GetInstance());
147 InputDeviceManager::GetInstance()->Add(&MouseWheelImpl::GetInstance());
148 }
149
JsAppImpl()150 JsAppImpl::JsAppImpl()
151 : isInterrupt(false),
152 taskHandleTimer(nullptr),
153 deviceCheckTimer(nullptr),
154 jsCheckTimer(nullptr),
155 jsAbility(nullptr),
156 jsThread(nullptr)
157 {
158 }
159
~JsAppImpl()160 JsAppImpl::~JsAppImpl() {}
161
GetInstance()162 JsAppImpl& JsAppImpl::GetInstance()
163 {
164 static JsAppImpl instance;
165 return instance;
166 }
167
Start()168 void JsAppImpl::Start()
169 {
170 if (jsThread != nullptr) {
171 delete jsThread;
172 jsThread = nullptr;
173 }
174
175 isFinished = false;
176 isInterrupt = false;
177 jsThread = new thread(&JsAppImpl::ThreadCallBack, &JsAppImpl::GetInstance());
178 if (jsThread == nullptr) {
179 ELOG("JsApp::Start jsThread memory allocation failed");
180 }
181 jsThread->detach();
182 }
183
Restart()184 void JsAppImpl::Restart()
185 {
186 Stop();
187 Start();
188 }
189
Interrupt()190 void JsAppImpl::Interrupt()
191 {
192 AsyncWorkManager::GetInstance().ClearAllAsyncWork();
193 jsAbility->Hide();
194 jsAbility->TransferToDestroy();
195 jsAbility.reset();
196 isFinished = true;
197 isInterrupt = true;
198 ILOG("JsAppImpl::ThreadCallBack finished");
199 }
200
ThreadCallBack()201 void JsAppImpl::ThreadCallBack()
202 {
203 OHOS::GraphicStartUp::Init();
204 GLOBAL_ConfigLanguage(SharedData<string>::GetData(SharedDataType::LANGUAGE).data());
205 InitHalScreen();
206 InitFontEngine();
207 VirtualScreenImpl::GetInstance().InitAll(pipeName, pipePort);
208 StartJsApp();
209 InitTimer();
210
211 thread::id curThreadId = this_thread::get_id();
212 SharedData<string>::AppendNotify(SharedDataType::LANGUAGE, TimerTaskHandler::CheckLanguageChanged, curThreadId);
213
214 CppTimerManager& manager = CppTimerManager::GetTimerManager();
215 while (!isInterrupt) {
216 this_thread::sleep_for(chrono::milliseconds(1));
217 manager.RunTimerTick();
218 }
219 }
220
InitTimer()221 void JsAppImpl::InitTimer()
222 {
223 taskHandleTimer = make_unique<CppTimer>(TimerTaskHandler::TaskHandle);
224 if (taskHandleTimer == nullptr) {
225 ELOG("JsApp::InitTimer taskHandleTimer memory allocation failed.");
226 return;
227 }
228 CppTimerManager::GetTimerManager().AddCppTimer(*taskHandleTimer);
229 taskHandleTimer->Start(TASK_HANDLE_TIMER_INTERVAL);
230
231 deviceCheckTimer = make_unique<CppTimer>(TimerTaskHandler::CheckDevice);
232 if (deviceCheckTimer == nullptr) {
233 ELOG("JsApp::InitTimer deviceCheckTimer memory allocation failed.");
234 return;
235 }
236 CppTimerManager::GetTimerManager().AddCppTimer(*deviceCheckTimer);
237 deviceCheckTimer->Start(DEVICE_CHECK_TIMER_INTERVAL);
238
239 jsCheckTimer = make_unique<CppTimer>(TimerTaskHandler::CheckJsRunning);
240 if (jsCheckTimer == nullptr) {
241 ELOG("JsApp::InitTimer jsCheckTimer memory allocation failed.");
242 return;
243 }
244 CppTimerManager::GetTimerManager().AddCppTimer(*jsCheckTimer);
245 jsCheckTimer->Start(JS_CHECK_TIMER_INTERVAL);
246 }
247
StartJsApp()248 void JsAppImpl::StartJsApp()
249 {
250 if (jsAbility != nullptr) {
251 FLOG("JsApp::StartJsApp jsAbility is not null.");
252 return;
253 }
254
255 jsAbility = make_unique<OHOS::ACELite::JSAbility>();
256 if (jsAbility == nullptr) {
257 FLOG("JsApp::StartJsApp jsAbility memory allocation failed");
258 return;
259 }
260
261 DebuggerConfig config;
262 config.startDebuggerServer = isDebug;
263 ILOG("Launch JS APP.");
264 ILOG("Debug Server Enable: %d", config.startDebuggerServer);
265 config.snapshotMode = false;
266 config.heapSize = jsHeapSize;
267 if (isDebug && debugServerPort) {
268 config.port = debugServerPort;
269 config.startDebuggerServer = isDebug;
270 config.snapshotMode = false;
271 ILOG("Debug Server Port: %d", debugServerPort);
272 }
273 Debugger::GetInstance().ConfigEngineDebugger(config);
274 ILOG("Launch Js app");
275 TraceTool::GetInstance().HandleTrace("Launch Js app");
276 if (urlPath.empty()) {
277 jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0);
278 jsAbility->Show();
279 ILOG("JsApp::StartJsApp launch finished.");
280 return;
281 }
282 Json::Value val;
283 val["uri"] = urlPath;
284 string routerInfo = val.toStyledString();
285 jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0, routerInfo.data());
286 jsAbility->Show();
287 ILOG("JsApp::StartJsApp launch with single page mode finished.");
288 isFinished = false;
289 }
290