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