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
47 using namespace OHOS;
48 using namespace ACELite;
49
50 static uint8_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH];
51
InitVectorFont(UIFont * font,const std::string fontPath)52 static void InitVectorFont(UIFont* font, const std::string fontPath)
53 {
54 ProductAdapter::SetDefaultFontStyle("SourceHanSansSC-Regular.otf", JsAppImpl::FONT_SIZE_DEFAULT);
55 BaseFont* currentFont = new UIFontVector();
56 if (currentFont == nullptr) {
57 FLOG("InitVectorFont currentFont memory allocation failed");
58 return;
59 }
60 font->SetFont(currentFont);
61 font->SetPsramMemory(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH);
62 int8_t ret = font->SetFontPath(fontPath.data(), BaseFont::DYNAMIC_FONT);
63 if (ret != 0) {
64 ELOG("The vector font path does not exist ! fontPath : %s", fontPath.data());
65 FLOG("InitFontEngine SetFontPath failed. vector fontPath: %s", fontPath.data());
66 }
67 font->RegisterFontInfo("SourceHanSansSC-Regular.otf");
68 font->SetCurrentLangId(0);
69 }
70
InitFontEngine()71 static void InitFontEngine()
72 {
73 UIFont* font = UIFont::GetInstance();
74 if (font == nullptr) {
75 ELOG("InitFontEngine:font is nullptr");
76 return;
77 }
78 std::string deviceType = CommandParser::GetInstance().GetDeviceType();
79 std::string separator = FileSystem::GetSeparator();
80 std::string fontPath = FileSystem::GetApplicationPath() + separator + ".." + separator + "config" + separator;
81 InitVectorFont(font, fontPath);
82
83 int32_t fp = 0;
84 std::string fileName = fontPath + "line_cj.brk";
85 #ifdef _WIN32
86 fp = open(fileName.c_str(), O_RDONLY | O_BINARY);
87 #else
88 fp = open(fileName.c_str(), O_RDONLY);
89 #endif
90 if (fp < 0) {
91 ELOG("Open font path failed.");
92 return;
93 }
94 uint32_t lineBrkSize = lseek(fp, 0, SEEK_END);
95 lseek(fp, 0, SEEK_SET);
96 UILineBreakEngine& lbEngine = UILineBreakEngine::GetInstance();
97 lbEngine.SetRuleBinInfo(fp, 0, lineBrkSize);
98 lbEngine.Init();
99 }
100
InitHalScreen()101 static void InitHalScreen()
102 {
103 InputDeviceManager::GetInstance()->Add(&MouseInputImpl::GetInstance());
104 InputDeviceManager::GetInstance()->Add(&MouseWheelImpl::GetInstance());
105 }
106
JsAppImpl()107 JsAppImpl::JsAppImpl()
108 : isInterrupt(false),
109 taskHandleTimer(nullptr),
110 deviceCheckTimer(nullptr),
111 jsCheckTimer(nullptr),
112 jsAbility(nullptr),
113 jsThread(nullptr)
114 {
115 }
116
~JsAppImpl()117 JsAppImpl::~JsAppImpl() {}
118
GetInstance()119 JsAppImpl& JsAppImpl::GetInstance()
120 {
121 static JsAppImpl instance;
122 return instance;
123 }
124
Start()125 void JsAppImpl::Start()
126 {
127 isFinished = false;
128 isInterrupt = false;
129 jsThread = std::make_unique<std::thread>([this]() {
130 this->ThreadCallBack();
131 });
132 if (jsThread == nullptr) {
133 ELOG("JsApp::Start jsThread memory allocation failed");
134 }
135 jsThread->detach();
136 }
137
Restart()138 void JsAppImpl::Restart()
139 {
140 Stop();
141 Start();
142 }
143
Interrupt()144 void JsAppImpl::Interrupt()
145 {
146 AsyncWorkManager::GetInstance().ClearAllAsyncWork();
147 jsAbility->Hide();
148 jsAbility->TransferToDestroy();
149 jsAbility.reset();
150 isFinished = true;
151 isInterrupt = true;
152 ILOG("JsAppImpl::ThreadCallBack finished");
153 }
154
ThreadCallBack()155 void JsAppImpl::ThreadCallBack()
156 {
157 OHOS::GraphicStartUp::Init();
158 GLOBAL_ConfigLanguage(SharedData<std::string>::GetData(SharedDataType::LANGUAGE).data());
159 InitHalScreen();
160 InitFontEngine();
161 VirtualScreenImpl::GetInstance().InitAll(pipeName, pipePort);
162 StartJsApp();
163 InitTimer();
164
165 std::thread::id curThreadId = std::this_thread::get_id();
166 #if defined(LITEWEARABLE_SUPPORTED) && LITEWEARABLE_SUPPORTED
167 SharedData<uint8_t>::AppendNotify(SharedDataType::HEARTBEAT_VALUE, TimerTaskHandler::CheckHeartRateChanged,
168 curThreadId, 50); // Duration:50 x 100 ms
169 SharedData<uint32_t>::AppendNotify(SharedDataType::PRESSURE_VALUE, TimerTaskHandler::CheckBarometerChanged,
170 curThreadId);
171 SharedData<uint32_t>::AppendNotify(SharedDataType::SUMSTEP_VALUE, TimerTaskHandler::CheckStepCountChanged,
172 curThreadId);
173 SharedData<bool>::AppendNotify(SharedDataType::WEARING_STATE, TimerTaskHandler::CheckOnBodyStateChanged,
174 curThreadId);
175 #endif
176 SharedData<std::string>::AppendNotify(SharedDataType::LANGUAGE, TimerTaskHandler::CheckLanguageChanged,
177 curThreadId);
178
179 CppTimerManager& manager = CppTimerManager::GetTimerManager();
180 while (!isInterrupt) {
181 std::this_thread::sleep_for(std::chrono::milliseconds(1));
182 manager.RunTimerTick();
183 }
184 }
185
InitTimer()186 void JsAppImpl::InitTimer()
187 {
188 taskHandleTimer = std::make_unique<CppTimer>(TimerTaskHandler::TaskHandle);
189 if (taskHandleTimer == nullptr) {
190 ELOG("JsApp::InitTimer taskHandleTimer memory allocation failed.");
191 return;
192 }
193 CppTimerManager::GetTimerManager().AddCppTimer(*taskHandleTimer);
194 taskHandleTimer->Start(TASK_HANDLE_TIMER_INTERVAL);
195
196 deviceCheckTimer = std::make_unique<CppTimer>(TimerTaskHandler::CheckDevice);
197 if (deviceCheckTimer == nullptr) {
198 ELOG("JsApp::InitTimer deviceCheckTimer memory allocation failed.");
199 return;
200 }
201 CppTimerManager::GetTimerManager().AddCppTimer(*deviceCheckTimer);
202 deviceCheckTimer->Start(DEVICE_CHECK_TIMER_INTERVAL);
203
204 jsCheckTimer = std::make_unique<CppTimer>(TimerTaskHandler::CheckJsRunning);
205 if (jsCheckTimer == nullptr) {
206 ELOG("JsApp::InitTimer jsCheckTimer memory allocation failed.");
207 return;
208 }
209 CppTimerManager::GetTimerManager().AddCppTimer(*jsCheckTimer);
210 jsCheckTimer->Start(JS_CHECK_TIMER_INTERVAL);
211 }
212
StartJsApp()213 void JsAppImpl::StartJsApp()
214 {
215 if (jsAbility != nullptr) {
216 FLOG("JsApp::StartJsApp jsAbility is not null.");
217 return;
218 }
219
220 jsAbility = std::make_unique<OHOS::ACELite::JSAbility>();
221 if (jsAbility == nullptr) {
222 FLOG("JsApp::StartJsApp jsAbility memory allocation failed");
223 return;
224 }
225
226 DebuggerConfig config;
227 config.startDebuggerServer = isDebug;
228 ILOG("Launch JS APP.");
229 ILOG("Debug Server Enable: %d", config.startDebuggerServer);
230 config.snapshotMode = false;
231 config.heapSize = jsHeapSize;
232 if (isDebug && debugServerPort) {
233 config.port = debugServerPort;
234 config.startDebuggerServer = isDebug;
235 config.snapshotMode = false;
236 ILOG("Debug Server Port: %d", debugServerPort);
237 }
238 Debugger::GetInstance().ConfigEngineDebugger(config);
239 ILOG("Launch Js app");
240 TraceTool::GetInstance().HandleTrace("Launch Js app");
241 if (urlPath.empty()) {
242 jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0);
243 jsAbility->Show();
244 ILOG("JsApp::StartJsApp launch finished.");
245 return;
246 }
247 Json2::Value val = JsonReader::CreateObject();
248 val.Add("uri", urlPath.c_str());
249 std::string routerInfo = val.ToStyledString();
250 jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0, routerInfo.data());
251 jsAbility->Show();
252 ILOG("JsApp::StartJsApp launch with single page mode finished.");
253 isFinished = false;
254 }
255
InitJsApp()256 void JsAppImpl::InitJsApp()
257 {
258 CommandParser& parser = CommandParser::GetInstance();
259 // Initialize Image Pipeline Name
260 if (parser.IsSet("s")) {
261 SetPipeName(parser.Value("s"));
262 }
263 if (parser.IsSet("lws")) {
264 SetPipePort(parser.Value("lws"));
265 }
266 // Set the application name.
267 SetBundleName(parser.GetAppName());
268 // Processing JSheap
269 SetJSHeapSize(parser.GetJsHeapSize());
270 // Start JSApp
271 if (!parser.IsSet("t")) {
272 if (parser.IsSet("d")) {
273 SetIsDebug(true);
274 if (parser.IsSet("p")) {
275 SetDebugServerPort(static_cast<uint16_t>(atoi(parser.Value("p").c_str())));
276 }
277 }
278 SetJsAppPath(parser.Value("j"));
279 if (parser.IsSet("url")) {
280 SetUrlPath(parser.Value("url"));
281 }
282 Start();
283 }
284 }
285