17c804472Sopenharmony_ci/*
27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
47c804472Sopenharmony_ci * you may not use this file except in compliance with the License.
57c804472Sopenharmony_ci * You may obtain a copy of the License at
67c804472Sopenharmony_ci *
77c804472Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
87c804472Sopenharmony_ci *
97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127c804472Sopenharmony_ci * See the License for the specific language governing permissions and
137c804472Sopenharmony_ci * limitations under the License.
147c804472Sopenharmony_ci */
157c804472Sopenharmony_ci
167c804472Sopenharmony_ci#include "JsAppImpl.h"
177c804472Sopenharmony_ci
187c804472Sopenharmony_ci#include "engines/gfx/gfx_engine_manager.h"
197c804472Sopenharmony_ci#include "font/ui_font.h"
207c804472Sopenharmony_ci#include "font/ui_font_bitmap.h"
217c804472Sopenharmony_ci#include "font/ui_font_header.h"
227c804472Sopenharmony_ci#include "font/ui_font_vector.h"
237c804472Sopenharmony_ci#include "font/ui_line_break.h"
247c804472Sopenharmony_ci#include "font/ui_text_shaping.h"
257c804472Sopenharmony_ci#include "gfx_utils/color.h"
267c804472Sopenharmony_ci#include "gfx_utils/file.h"
277c804472Sopenharmony_ci#include "global.h"
287c804472Sopenharmony_ci#include "graphic_startup.h"
297c804472Sopenharmony_ci#include "input_device_manager.h"
307c804472Sopenharmony_ci#include "js_debugger_config.h"
317c804472Sopenharmony_ci#include "product_adapter.h"
327c804472Sopenharmony_ci#include "screen_device.h"
337c804472Sopenharmony_ci
347c804472Sopenharmony_ci#include "AsyncWorkManager.h"
357c804472Sopenharmony_ci#include "CommandParser.h"
367c804472Sopenharmony_ci#include "CppTimerManager.h"
377c804472Sopenharmony_ci#include "FileSystem.h"
387c804472Sopenharmony_ci#include "LanguageManagerImpl.h"
397c804472Sopenharmony_ci#include "MouseInputImpl.h"
407c804472Sopenharmony_ci#include "MouseWheelImpl.h"
417c804472Sopenharmony_ci#include "PreviewerEngineLog.h"
427c804472Sopenharmony_ci#include "SharedData.h"
437c804472Sopenharmony_ci#include "TimerTaskHandler.h"
447c804472Sopenharmony_ci#include "TraceTool.h"
457c804472Sopenharmony_ci#include "VirtualScreenImpl.h"
467c804472Sopenharmony_ci
477c804472Sopenharmony_ciusing namespace OHOS;
487c804472Sopenharmony_ciusing namespace ACELite;
497c804472Sopenharmony_ci
507c804472Sopenharmony_cistatic uint8_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH];
517c804472Sopenharmony_ci
527c804472Sopenharmony_cistatic void InitVectorFont(UIFont* font, const std::string fontPath)
537c804472Sopenharmony_ci{
547c804472Sopenharmony_ci    ProductAdapter::SetDefaultFontStyle("SourceHanSansSC-Regular.otf", JsAppImpl::FONT_SIZE_DEFAULT);
557c804472Sopenharmony_ci    BaseFont* currentFont = new UIFontVector();
567c804472Sopenharmony_ci    if (currentFont == nullptr) {
577c804472Sopenharmony_ci        FLOG("InitVectorFont currentFont memory allocation failed");
587c804472Sopenharmony_ci        return;
597c804472Sopenharmony_ci    }
607c804472Sopenharmony_ci    font->SetFont(currentFont);
617c804472Sopenharmony_ci    font->SetPsramMemory(reinterpret_cast<uintptr_t>(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH);
627c804472Sopenharmony_ci    int8_t ret = font->SetFontPath(fontPath.data(), BaseFont::DYNAMIC_FONT);
637c804472Sopenharmony_ci    if (ret != 0) {
647c804472Sopenharmony_ci        ELOG("The vector font path does not exist ! fontPath : %s", fontPath.data());
657c804472Sopenharmony_ci        FLOG("InitFontEngine SetFontPath failed. vector fontPath: %s", fontPath.data());
667c804472Sopenharmony_ci    }
677c804472Sopenharmony_ci    font->RegisterFontInfo("SourceHanSansSC-Regular.otf");
687c804472Sopenharmony_ci    font->SetCurrentLangId(0);
697c804472Sopenharmony_ci}
707c804472Sopenharmony_ci
717c804472Sopenharmony_cistatic void InitFontEngine()
727c804472Sopenharmony_ci{
737c804472Sopenharmony_ci    UIFont* font = UIFont::GetInstance();
747c804472Sopenharmony_ci    if (font == nullptr) {
757c804472Sopenharmony_ci        ELOG("InitFontEngine:font is nullptr");
767c804472Sopenharmony_ci        return;
777c804472Sopenharmony_ci    }
787c804472Sopenharmony_ci    std::string deviceType = CommandParser::GetInstance().GetDeviceType();
797c804472Sopenharmony_ci    std::string separator = FileSystem::GetSeparator();
807c804472Sopenharmony_ci    std::string fontPath = FileSystem::GetApplicationPath() + separator + ".." + separator + "config" + separator;
817c804472Sopenharmony_ci    InitVectorFont(font, fontPath);
827c804472Sopenharmony_ci
837c804472Sopenharmony_ci    int32_t fp = 0;
847c804472Sopenharmony_ci    std::string fileName = fontPath + "line_cj.brk";
857c804472Sopenharmony_ci#ifdef _WIN32
867c804472Sopenharmony_ci    fp = open(fileName.c_str(), O_RDONLY | O_BINARY);
877c804472Sopenharmony_ci#else
887c804472Sopenharmony_ci    fp = open(fileName.c_str(), O_RDONLY);
897c804472Sopenharmony_ci#endif
907c804472Sopenharmony_ci    if (fp < 0) {
917c804472Sopenharmony_ci        ELOG("Open font path failed.");
927c804472Sopenharmony_ci        return;
937c804472Sopenharmony_ci    }
947c804472Sopenharmony_ci    uint32_t lineBrkSize = lseek(fp, 0, SEEK_END);
957c804472Sopenharmony_ci    lseek(fp, 0, SEEK_SET);
967c804472Sopenharmony_ci    UILineBreakEngine& lbEngine = UILineBreakEngine::GetInstance();
977c804472Sopenharmony_ci    lbEngine.SetRuleBinInfo(fp, 0, lineBrkSize);
987c804472Sopenharmony_ci    lbEngine.Init();
997c804472Sopenharmony_ci}
1007c804472Sopenharmony_ci
1017c804472Sopenharmony_cistatic void InitHalScreen()
1027c804472Sopenharmony_ci{
1037c804472Sopenharmony_ci    InputDeviceManager::GetInstance()->Add(&MouseInputImpl::GetInstance());
1047c804472Sopenharmony_ci    InputDeviceManager::GetInstance()->Add(&MouseWheelImpl::GetInstance());
1057c804472Sopenharmony_ci}
1067c804472Sopenharmony_ci
1077c804472Sopenharmony_ciJsAppImpl::JsAppImpl()
1087c804472Sopenharmony_ci    : isInterrupt(false),
1097c804472Sopenharmony_ci      taskHandleTimer(nullptr),
1107c804472Sopenharmony_ci      deviceCheckTimer(nullptr),
1117c804472Sopenharmony_ci      jsCheckTimer(nullptr),
1127c804472Sopenharmony_ci      jsAbility(nullptr),
1137c804472Sopenharmony_ci      jsThread(nullptr)
1147c804472Sopenharmony_ci{
1157c804472Sopenharmony_ci}
1167c804472Sopenharmony_ci
1177c804472Sopenharmony_ciJsAppImpl::~JsAppImpl() {}
1187c804472Sopenharmony_ci
1197c804472Sopenharmony_ciJsAppImpl& JsAppImpl::GetInstance()
1207c804472Sopenharmony_ci{
1217c804472Sopenharmony_ci    static JsAppImpl instance;
1227c804472Sopenharmony_ci    return instance;
1237c804472Sopenharmony_ci}
1247c804472Sopenharmony_ci
1257c804472Sopenharmony_civoid JsAppImpl::Start()
1267c804472Sopenharmony_ci{
1277c804472Sopenharmony_ci    isFinished = false;
1287c804472Sopenharmony_ci    isInterrupt = false;
1297c804472Sopenharmony_ci    jsThread = std::make_unique<std::thread>([this]() {
1307c804472Sopenharmony_ci        this->ThreadCallBack();
1317c804472Sopenharmony_ci    });
1327c804472Sopenharmony_ci    if (jsThread == nullptr) {
1337c804472Sopenharmony_ci        ELOG("JsApp::Start jsThread memory allocation failed");
1347c804472Sopenharmony_ci    }
1357c804472Sopenharmony_ci    jsThread->detach();
1367c804472Sopenharmony_ci}
1377c804472Sopenharmony_ci
1387c804472Sopenharmony_civoid JsAppImpl::Restart()
1397c804472Sopenharmony_ci{
1407c804472Sopenharmony_ci    Stop();
1417c804472Sopenharmony_ci    Start();
1427c804472Sopenharmony_ci}
1437c804472Sopenharmony_ci
1447c804472Sopenharmony_civoid JsAppImpl::Interrupt()
1457c804472Sopenharmony_ci{
1467c804472Sopenharmony_ci    AsyncWorkManager::GetInstance().ClearAllAsyncWork();
1477c804472Sopenharmony_ci    jsAbility->Hide();
1487c804472Sopenharmony_ci    jsAbility->TransferToDestroy();
1497c804472Sopenharmony_ci    jsAbility.reset();
1507c804472Sopenharmony_ci    isFinished = true;
1517c804472Sopenharmony_ci    isInterrupt = true;
1527c804472Sopenharmony_ci    ILOG("JsAppImpl::ThreadCallBack finished");
1537c804472Sopenharmony_ci}
1547c804472Sopenharmony_ci
1557c804472Sopenharmony_civoid JsAppImpl::ThreadCallBack()
1567c804472Sopenharmony_ci{
1577c804472Sopenharmony_ci    OHOS::GraphicStartUp::Init();
1587c804472Sopenharmony_ci    GLOBAL_ConfigLanguage(SharedData<std::string>::GetData(SharedDataType::LANGUAGE).data());
1597c804472Sopenharmony_ci    InitHalScreen();
1607c804472Sopenharmony_ci    InitFontEngine();
1617c804472Sopenharmony_ci    VirtualScreenImpl::GetInstance().InitAll(pipeName, pipePort);
1627c804472Sopenharmony_ci    StartJsApp();
1637c804472Sopenharmony_ci    InitTimer();
1647c804472Sopenharmony_ci
1657c804472Sopenharmony_ci    std::thread::id curThreadId = std::this_thread::get_id();
1667c804472Sopenharmony_ci#if defined(LITEWEARABLE_SUPPORTED) && LITEWEARABLE_SUPPORTED
1677c804472Sopenharmony_ci    SharedData<uint8_t>::AppendNotify(SharedDataType::HEARTBEAT_VALUE, TimerTaskHandler::CheckHeartRateChanged,
1687c804472Sopenharmony_ci        curThreadId, 50); // Duration:50 x 100 ms
1697c804472Sopenharmony_ci    SharedData<uint32_t>::AppendNotify(SharedDataType::PRESSURE_VALUE, TimerTaskHandler::CheckBarometerChanged,
1707c804472Sopenharmony_ci        curThreadId);
1717c804472Sopenharmony_ci    SharedData<uint32_t>::AppendNotify(SharedDataType::SUMSTEP_VALUE, TimerTaskHandler::CheckStepCountChanged,
1727c804472Sopenharmony_ci        curThreadId);
1737c804472Sopenharmony_ci    SharedData<bool>::AppendNotify(SharedDataType::WEARING_STATE, TimerTaskHandler::CheckOnBodyStateChanged,
1747c804472Sopenharmony_ci        curThreadId);
1757c804472Sopenharmony_ci#endif
1767c804472Sopenharmony_ci    SharedData<std::string>::AppendNotify(SharedDataType::LANGUAGE, TimerTaskHandler::CheckLanguageChanged,
1777c804472Sopenharmony_ci        curThreadId);
1787c804472Sopenharmony_ci
1797c804472Sopenharmony_ci    CppTimerManager& manager = CppTimerManager::GetTimerManager();
1807c804472Sopenharmony_ci    while (!isInterrupt) {
1817c804472Sopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(1));
1827c804472Sopenharmony_ci        manager.RunTimerTick();
1837c804472Sopenharmony_ci    }
1847c804472Sopenharmony_ci}
1857c804472Sopenharmony_ci
1867c804472Sopenharmony_civoid JsAppImpl::InitTimer()
1877c804472Sopenharmony_ci{
1887c804472Sopenharmony_ci    taskHandleTimer = std::make_unique<CppTimer>(TimerTaskHandler::TaskHandle);
1897c804472Sopenharmony_ci    if (taskHandleTimer == nullptr) {
1907c804472Sopenharmony_ci        ELOG("JsApp::InitTimer taskHandleTimer memory allocation failed.");
1917c804472Sopenharmony_ci        return;
1927c804472Sopenharmony_ci    }
1937c804472Sopenharmony_ci    CppTimerManager::GetTimerManager().AddCppTimer(*taskHandleTimer);
1947c804472Sopenharmony_ci    taskHandleTimer->Start(TASK_HANDLE_TIMER_INTERVAL);
1957c804472Sopenharmony_ci
1967c804472Sopenharmony_ci    deviceCheckTimer = std::make_unique<CppTimer>(TimerTaskHandler::CheckDevice);
1977c804472Sopenharmony_ci    if (deviceCheckTimer == nullptr) {
1987c804472Sopenharmony_ci        ELOG("JsApp::InitTimer deviceCheckTimer memory allocation failed.");
1997c804472Sopenharmony_ci        return;
2007c804472Sopenharmony_ci    }
2017c804472Sopenharmony_ci    CppTimerManager::GetTimerManager().AddCppTimer(*deviceCheckTimer);
2027c804472Sopenharmony_ci    deviceCheckTimer->Start(DEVICE_CHECK_TIMER_INTERVAL);
2037c804472Sopenharmony_ci
2047c804472Sopenharmony_ci    jsCheckTimer = std::make_unique<CppTimer>(TimerTaskHandler::CheckJsRunning);
2057c804472Sopenharmony_ci    if (jsCheckTimer == nullptr) {
2067c804472Sopenharmony_ci        ELOG("JsApp::InitTimer jsCheckTimer memory allocation failed.");
2077c804472Sopenharmony_ci        return;
2087c804472Sopenharmony_ci    }
2097c804472Sopenharmony_ci    CppTimerManager::GetTimerManager().AddCppTimer(*jsCheckTimer);
2107c804472Sopenharmony_ci    jsCheckTimer->Start(JS_CHECK_TIMER_INTERVAL);
2117c804472Sopenharmony_ci}
2127c804472Sopenharmony_ci
2137c804472Sopenharmony_civoid JsAppImpl::StartJsApp()
2147c804472Sopenharmony_ci{
2157c804472Sopenharmony_ci    if (jsAbility != nullptr) {
2167c804472Sopenharmony_ci        FLOG("JsApp::StartJsApp jsAbility is not null.");
2177c804472Sopenharmony_ci        return;
2187c804472Sopenharmony_ci    }
2197c804472Sopenharmony_ci
2207c804472Sopenharmony_ci    jsAbility = std::make_unique<OHOS::ACELite::JSAbility>();
2217c804472Sopenharmony_ci    if (jsAbility == nullptr) {
2227c804472Sopenharmony_ci        FLOG("JsApp::StartJsApp jsAbility memory allocation failed");
2237c804472Sopenharmony_ci        return;
2247c804472Sopenharmony_ci    }
2257c804472Sopenharmony_ci
2267c804472Sopenharmony_ci    DebuggerConfig config;
2277c804472Sopenharmony_ci    config.startDebuggerServer = isDebug;
2287c804472Sopenharmony_ci    ILOG("Launch JS APP.");
2297c804472Sopenharmony_ci    ILOG("Debug Server Enable: %d", config.startDebuggerServer);
2307c804472Sopenharmony_ci    config.snapshotMode = false;
2317c804472Sopenharmony_ci    config.heapSize = jsHeapSize;
2327c804472Sopenharmony_ci    if (isDebug && debugServerPort) {
2337c804472Sopenharmony_ci        config.port = debugServerPort;
2347c804472Sopenharmony_ci        config.startDebuggerServer = isDebug;
2357c804472Sopenharmony_ci        config.snapshotMode = false;
2367c804472Sopenharmony_ci        ILOG("Debug Server Port: %d", debugServerPort);
2377c804472Sopenharmony_ci    }
2387c804472Sopenharmony_ci    Debugger::GetInstance().ConfigEngineDebugger(config);
2397c804472Sopenharmony_ci    ILOG("Launch Js app");
2407c804472Sopenharmony_ci    TraceTool::GetInstance().HandleTrace("Launch Js app");
2417c804472Sopenharmony_ci    if (urlPath.empty()) {
2427c804472Sopenharmony_ci        jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0);
2437c804472Sopenharmony_ci        jsAbility->Show();
2447c804472Sopenharmony_ci        ILOG("JsApp::StartJsApp launch finished.");
2457c804472Sopenharmony_ci        return;
2467c804472Sopenharmony_ci    }
2477c804472Sopenharmony_ci    Json2::Value val = JsonReader::CreateObject();
2487c804472Sopenharmony_ci    val.Add("uri", urlPath.c_str());
2497c804472Sopenharmony_ci    std::string routerInfo = val.ToStyledString();
2507c804472Sopenharmony_ci    jsAbility->Launch(jsAppPath.c_str(), bundleName.c_str(), 0, routerInfo.data());
2517c804472Sopenharmony_ci    jsAbility->Show();
2527c804472Sopenharmony_ci    ILOG("JsApp::StartJsApp launch with single page mode finished.");
2537c804472Sopenharmony_ci    isFinished = false;
2547c804472Sopenharmony_ci}
2557c804472Sopenharmony_ci
2567c804472Sopenharmony_civoid JsAppImpl::InitJsApp()
2577c804472Sopenharmony_ci{
2587c804472Sopenharmony_ci    CommandParser& parser = CommandParser::GetInstance();
2597c804472Sopenharmony_ci    // Initialize Image Pipeline Name
2607c804472Sopenharmony_ci    if (parser.IsSet("s")) {
2617c804472Sopenharmony_ci        SetPipeName(parser.Value("s"));
2627c804472Sopenharmony_ci    }
2637c804472Sopenharmony_ci    if (parser.IsSet("lws")) {
2647c804472Sopenharmony_ci        SetPipePort(parser.Value("lws"));
2657c804472Sopenharmony_ci    }
2667c804472Sopenharmony_ci    // Set the application name.
2677c804472Sopenharmony_ci    SetBundleName(parser.GetAppName());
2687c804472Sopenharmony_ci    // Processing JSheap
2697c804472Sopenharmony_ci    SetJSHeapSize(parser.GetJsHeapSize());
2707c804472Sopenharmony_ci    // Start JSApp
2717c804472Sopenharmony_ci    if (!parser.IsSet("t")) {
2727c804472Sopenharmony_ci        if (parser.IsSet("d")) {
2737c804472Sopenharmony_ci            SetIsDebug(true);
2747c804472Sopenharmony_ci            if (parser.IsSet("p")) {
2757c804472Sopenharmony_ci                SetDebugServerPort(static_cast<uint16_t>(atoi(parser.Value("p").c_str())));
2767c804472Sopenharmony_ci            }
2777c804472Sopenharmony_ci        }
2787c804472Sopenharmony_ci        SetJsAppPath(parser.Value("j"));
2797c804472Sopenharmony_ci        if (parser.IsSet("url")) {
2807c804472Sopenharmony_ci            SetUrlPath(parser.Value("url"));
2817c804472Sopenharmony_ci        }
2827c804472Sopenharmony_ci        Start();
2837c804472Sopenharmony_ci    }
2847c804472Sopenharmony_ci}
285