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
48 using namespace OHOS;
49 using namespace ACELite;
50 using namespace std;
51
52 static uint8_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH];
53
InitVectorFont(UIFont * font,const string fontPath)54 static void InitVectorFont(UIFont* font, const string fontPath)
55 {
56 ProductAdapter::SetDefaultFontStyle("SourceHanSansSC-Regular.otf", JsAppImpl::FONT_SIZE_DEFAULT);
57 BaseFont* currentFont = new UIFontVector();
58 if (currentFont == nullptr) {
59 FLOG("InitVectorFont currentFont memory allocation failed");
60 return;
61 }
62 font->SetFont(currentFont);
63 font->SetPsramMemory(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH);
64 int8_t ret = font->SetFontPath(fontPath.data(), BaseFont::DYNAMIC_FONT);
65 if (ret != 0) {
66 ELOG("The vector font path does not exist ! fontPath : %s", fontPath.data());
67 FLOG("InitFontEngine SetFontPath failed. vector fontPath: %s", fontPath.data());
68 }
69 font->RegisterFontInfo("SourceHanSansSC-Regular.otf");
70 font->SetCurrentLangId(0);
71 }
72
InitFontEngine()73 static void InitFontEngine()
74 {
75 UIFont* font = UIFont::GetInstance();
76 if (font == nullptr) {
77 ELOG("InitFontEngine:font is nullptr");
78 return;
79 }
80 std::string deviceType = CommandParser::GetInstance().GetDeviceType();
81 std::string separator = FileSystem::GetSeparator();
82 std::string fontPath = FileSystem::GetApplicationPath() + separator + ".." + separator + "config" + separator;
83 InitVectorFont(font, fontPath);
84
85 int32_t fp = 0;
86 string fileName = fontPath + "line_cj.brk";
87 #ifdef _WIN32
88 fp = open(fileName.c_str(), O_RDONLY | O_BINARY);
89 #else
90 fp = open(fileName.c_str(), O_RDONLY);
91 #endif
92 if (fp < 0) {
93 ELOG("Open font path failed.");
94 return;
95 }
96 uint32_t lineBrkSize = lseek(fp, 0, SEEK_END);
97 lseek(fp, 0, SEEK_SET);
98 UILineBreakEngine& lbEngine = UILineBreakEngine::GetInstance();
99 lbEngine.SetRuleBinInfo(fp, 0, lineBrkSize);
100 lbEngine.Init();
101 }
102
InitHalScreen()103 static void InitHalScreen()
104 {
105 InputDeviceManager::GetInstance()->Add(&MouseInputImpl::GetInstance());
106 InputDeviceManager::GetInstance()->Add(&MouseWheelImpl::GetInstance());
107 }
108
JsAppImpl()109 JsAppImpl::JsAppImpl()
110 : isInterrupt(false),
111 taskHandleTimer(nullptr),
112 deviceCheckTimer(nullptr),
113 jsCheckTimer(nullptr),
114 jsAbility(nullptr),
115 jsThread(nullptr)
116 {
117 }
118
~JsAppImpl()119 JsAppImpl::~JsAppImpl() {}
120
GetInstance()121 JsAppImpl& JsAppImpl::GetInstance()
122 {
123 static JsAppImpl instance;
124 return instance;
125 }
126
Start()127 void JsAppImpl::Start()
128 {
129 isFinished = false;
130 isInterrupt = false;
131 jsThread = std::make_unique<std::thread>(&JsAppImpl::ThreadCallBack, &JsAppImpl::GetInstance());
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<string>::GetData(SharedDataType::LANGUAGE).data());
159 InitHalScreen();
160 InitFontEngine();
161 VirtualScreenImpl::GetInstance().InitAll(pipeName, pipePort);
162 StartJsApp();
163 InitTimer();
164
165 thread::id curThreadId = 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<string>::AppendNotify(SharedDataType::LANGUAGE, TimerTaskHandler::CheckLanguageChanged,
177 curThreadId);
178
179 CppTimerManager& manager = CppTimerManager::GetTimerManager();
180 while (!isInterrupt) {
181 this_thread::sleep_for(chrono::milliseconds(1));
182 manager.RunTimerTick();
183 }
184 }
185
InitTimer()186 void JsAppImpl::InitTimer()
187 {
188 taskHandleTimer = 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 = 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 = 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 = 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 Json::Value val;
248 val["uri"] = urlPath;
249 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