diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8393b4fe87cc66dbf940a31d80668a5fdfd3b73 --- /dev/null +++ b/src/platform/platform.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "platform/platform.h" + +#include + +#include "unistd.h" + +namespace platform { +void OS::Abort() +{ + std::abort(); +} + +uint64_t OS::GetUid() +{ + return static_cast(getuid()); +} + +uint64_t OS::GetPid() +{ + return static_cast(getppid()); +} + +uint64_t OS::GetTid() +{ + return static_cast(gettid()); +} + +void OS::PrintString(OS::LogLevel level, const char* str) +{ + (void)level; + printf("%s", str); +} + +void VPrint(const char* format, va_list args) +{ + vprintf(format, args); +} + +void VPrintError(const char* format, va_list args) +{ + (void)vfprintf(stderr, format, args); +} + +void OS::Print(OS::LogLevel level, const char* format, ...) +{ + va_list args; + va_start(args, format); + if (static_cast(level) > static_cast(OS::LogLevel::LOG_WARN)) { + VPrintError(format, args); + } else { + VPrint(format, args); + } + va_end(args); +} + +} // namespace platform diff --git a/src/platform/platform.h b/src/platform/platform.h new file mode 100644 index 0000000000000000000000000000000000000000..d417692593a4d810e6d9af950dca65a9ce71edc7 --- /dev/null +++ b/src/platform/platform.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSVM_PLATFORM_H +#define JSVM_PLATFORM_H +#include +#include +#include +#include +#include +#include + +#ifdef TARGET_OHOS +#include "platform/platform_ohos.h" +#define OHOS_API_CALL(api_call) api_call +#else +#define OHOS_API_CALL(api_call) +#endif + +namespace platform { +class OS { +public: + [[noreturn]] static void Abort(); + static uint64_t GetUid(); + static uint64_t GetPid(); + static uint64_t GetTid(); + + enum class LogLevel : uint64_t { LOG_DEBUG = 0, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL }; + + static void Print(LogLevel level, const char* format, ...) __attribute__((format(printf, 2, 3))); + static void PrintString(LogLevel level, const char* string); +}; + +class RunJsTrace { +public: + explicit RunJsTrace(bool runJs); + explicit RunJsTrace(const char* name); + + ~RunJsTrace(); + +private: + bool runJs; +}; +} // namespace platform + +#endif diff --git a/src/platform/platform_ohos.cpp b/src/platform/platform_ohos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b32eae4dbe191d6ed1e6b74db75c3a701ed1bdd2 --- /dev/null +++ b/src/platform/platform_ohos.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "platform.h" + +// v8 header +#include "v8.h" + +// OHOS API header +#include "hilog/log.h" +#include "hitrace_meter.h" +#include "init_param.h" +#include "res_sched_client.h" +#include "unistd.h" +#ifdef ENABLE_HISYSEVENT +#include "hisysevent.h" +#endif + +namespace platform { +void OS::Abort() +{ + std::abort(); +} + +uint64_t OS::GetUid() +{ + return static_cast(getuid()); +} + +uint64_t OS::GetPid() +{ + return static_cast(getprocpid()); +} + +uint64_t OS::GetTid() +{ + return static_cast(getproctid()); +} + +#ifdef LOG_DOMAIN +#undef LOG_DOMAIN +#endif +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_DOMAIN 0xD003900 +#define LOG_TAG "JSVM" + +void OS::PrintString(LogLevel level, const char* string) +{ + // convert platform defined LogLevel to hilog LogLevel + static constexpr ::LogLevel convertArray[] = { ::LogLevel::LOG_DEBUG, ::LogLevel::LOG_INFO, ::LogLevel::LOG_WARN, + ::LogLevel::LOG_ERROR, ::LogLevel::LOG_FATAL }; + static_assert(sizeof(convertArray) / sizeof(::LogLevel) == static_cast(OS::LogLevel::LOG_FATAL) + 1); + + HiLogPrint(LOG_APP, convertArray[static_cast(level)], LOG_DOMAIN, LOG_TAG, "%{public}s", string); +} + +void OS::Print(LogLevel level, const char* format, ...) +{ + constexpr size_t maxStringSize = 1024; + char string[maxStringSize]; + va_list arguments; + va_start(arguments, format); + int len = vsnprintf_s(string, maxStringSize, maxStringSize - 1, format, arguments); + va_end(arguments); + + if (len < 0) { + PrintString(LogLevel::LOG_ERROR, "vsnprintf_s failed"); + return; + } + PrintString(level, string); +} + +#define JSVM_HITRACE_TAG HITRACE_TAG_OHOS + +RunJsTrace::RunJsTrace(bool runJs) : runJs(runJs) +{ + if (runJs) { + StartTrace(JSVM_HITRACE_TAG, "PureJS"); + } else { + FinishTrace(JSVM_HITRACE_TAG); + } +} + +RunJsTrace::RunJsTrace(const char* name) : runJs(true) +{ + StartTrace(JSVM_HITRACE_TAG, name); +} + +RunJsTrace::~RunJsTrace() +{ + if (runJs) { + FinishTrace(JSVM_HITRACE_TAG); + } else { + StartTrace(JSVM_HITRACE_TAG, "PureJS"); + } +} + +namespace ohos { +void ReportKeyThread(ThreadRole role) +{ + static_assert(static_cast(ThreadRole::IMPORTANT_DISPLAY) == + static_cast(OHOS::ResourceSchedule::ResType::IMPORTANT_DISPLAY)); + static_assert(static_cast(ThreadRole::USER_INTERACT) == + static_cast(OHOS::ResourceSchedule::ResType::USER_INTERACT)); + + uint64_t uid = OS::GetUid(); + uint64_t tid = OS::GetTid(); + uint64_t pid = OS::GetPid(); + std::unordered_map payLoad = { { "uid", std::to_string(uid) }, + { "pid", std::to_string(pid) }, + { "tid", std::to_string(tid) }, + { "role", std::to_string(role) } }; + OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData( + OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_KEY_THREAD, + OHOS::ResourceSchedule::ResType::ReportChangeStatus::CREATE, payLoad); +} + +inline bool ReadSystemXpmState() +{ + constexpr size_t argBuffSize = 32; + char buffer[argBuffSize] = { 0 }; + uint32_t buffSize = sizeof(buffer); + + if (SystemGetParameter("ohos.boot.advsecmode.state", buffer, &buffSize) == 0 && strcmp(buffer, "0") != 0) { + return true; + } + return false; +} + +void SetSecurityMode() +{ + constexpr size_t SEC_ARG_CNT = 2; + if (ReadSystemXpmState()) { + int secArgc = SEC_ARG_CNT; + constexpr bool removeFlag = false; + const char* secArgv[SEC_ARG_CNT] = { "jsvm", "--jitless" }; + v8::V8::SetFlagsFromCommandLine(&secArgc, const_cast(reinterpret_cast(secArgv)), + removeFlag); + } +} + +constexpr int MAX_FILE_LENGTH = 32 * 1024 * 1024; + +bool LoadStringFromFile(const std::string& filePath, std::string& content) +{ + std::ifstream file(filePath.c_str()); + if (!file.is_open()) { + return false; + } + + file.seekg(0, std::ios::end); + const long fileLength = file.tellg(); + if (fileLength > MAX_FILE_LENGTH) { + return false; + } + + content.clear(); + file.seekg(0, std::ios::beg); + std::copy(std::istreambuf_iterator(file), std::istreambuf_iterator(), std::back_inserter(content)); + return true; +} + +bool ProcessBundleName(std::string& bundleName) +{ + int pid = getprocpid(); + std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline"; + if (!LoadStringFromFile(filePath, bundleName)) { + return false; + } + if (bundleName.empty()) { + return false; + } + auto pos = bundleName.find(":"); + if (pos != std::string::npos) { + bundleName = bundleName.substr(0, pos); + } + bundleName = bundleName.substr(0, strlen(bundleName.c_str())); + return true; +} + +void WriteHisysevent() +{ +#ifdef ENABLE_HISYSEVENT + std::string bundleName; + if (!ProcessBundleName(bundleName)) { + bundleName = "INVALID_BUNDLE_NAME"; + } + HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::JSVM_RUNTIME, "APP_STATS", + OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "BUNDLE_NAME", bundleName); +#endif +} +} // namespace ohos + +} // namespace platform diff --git a/src/platform/platform_ohos.h b/src/platform/platform_ohos.h new file mode 100644 index 0000000000000000000000000000000000000000..46628592b38704ad046c59979e6c73264665d548 --- /dev/null +++ b/src/platform/platform_ohos.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef JSVM_PLATFORM_OHOS_H +#define JSVM_PLATFORM_OHOS_H + +#ifndef TARGET_OHOS +#error "PLATFORM OHOS is required" +#endif + +#include +#include + +namespace platform { +namespace ohos { +enum ThreadRole : int64_t { + USER_INTERACT = 0, + IMPORTANT_DISPLAY = 2, +}; + +void ReportKeyThread(ThreadRole role); + +void SetSecurityMode(); + +void WriteHisysevent(); +} // namespace ohos +} // namespace platform +#endif \ No newline at end of file