1 /*
2 * Copyright (c) 2024 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 "platform.h"
17
18 // v8 header
19 #include "v8.h"
20
21 // OHOS API header
22 #include "hilog/log.h"
23 #include "hitrace_meter.h"
24 #include "init_param.h"
25 #include "res_sched_client.h"
26 #include "unistd.h"
27 #ifdef ENABLE_HISYSEVENT
28 #include "hisysevent.h"
29 #endif
30
31 namespace platform {
Abort()32 void OS::Abort()
33 {
34 std::abort();
35 }
36
GetUid()37 uint64_t OS::GetUid()
38 {
39 return static_cast<uint64_t>(getuid());
40 }
41
GetPid()42 uint64_t OS::GetPid()
43 {
44 return static_cast<uint64_t>(getprocpid());
45 }
46
GetTid()47 uint64_t OS::GetTid()
48 {
49 return static_cast<uint64_t>(getproctid());
50 }
51
52 #ifdef LOG_DOMAIN
53 #undef LOG_DOMAIN
54 #endif
55 #ifdef LOG_TAG
56 #undef LOG_TAG
57 #endif
58
59 #define LOG_DOMAIN 0xD003900
60 #define LOG_TAG "JSVM"
61
PrintString(LogLevel level,const char * string)62 void OS::PrintString(LogLevel level, const char* string)
63 {
64 // convert platform defined LogLevel to hilog LogLevel
65 static constexpr ::LogLevel convertArray[] = { ::LogLevel::LOG_DEBUG, ::LogLevel::LOG_INFO, ::LogLevel::LOG_WARN,
66 ::LogLevel::LOG_ERROR, ::LogLevel::LOG_FATAL };
67 static_assert(sizeof(convertArray) / sizeof(::LogLevel) == static_cast<uint64_t>(OS::LogLevel::LOG_FATAL) + 1);
68
69 HiLogPrint(LOG_APP, convertArray[static_cast<uint64_t>(level)], LOG_DOMAIN, LOG_TAG, "%{public}s", string);
70 }
71
Print(LogLevel level,const char * format,...)72 void OS::Print(LogLevel level, const char* format, ...)
73 {
74 constexpr size_t maxStringSize = 1024;
75 char string[maxStringSize];
76 va_list arguments;
77 va_start(arguments, format);
78 int len = vsnprintf_s(string, sizeof(string), sizeof(string) - 1, format, arguments);
79 va_end(arguments);
80
81 if (len < 0) {
82 PrintString(LogLevel::LOG_ERROR, "vsnprintf_s failed");
83 return;
84 }
85 PrintString(level, string);
86 }
87
88 #define JSVM_HITRACE_TAG HITRACE_TAG_OHOS
89
RunJsTrace(bool runJs)90 RunJsTrace::RunJsTrace(bool runJs) : runJs(runJs)
91 {
92 if (runJs) {
93 StartTrace(JSVM_HITRACE_TAG, "PureJS");
94 } else {
95 FinishTrace(JSVM_HITRACE_TAG);
96 }
97 }
98
RunJsTrace(const char * name)99 RunJsTrace::RunJsTrace(const char* name) : runJs(true)
100 {
101 StartTrace(JSVM_HITRACE_TAG, name);
102 }
103
~RunJsTrace()104 RunJsTrace::~RunJsTrace()
105 {
106 if (runJs) {
107 FinishTrace(JSVM_HITRACE_TAG);
108 } else {
109 StartTrace(JSVM_HITRACE_TAG, "PureJS");
110 }
111 }
112
113 namespace ohos {
ReportKeyThread(ThreadRole role)114 void ReportKeyThread(ThreadRole role)
115 {
116 static_assert(static_cast<int64_t>(ThreadRole::IMPORTANT_DISPLAY) ==
117 static_cast<int64_t>(OHOS::ResourceSchedule::ResType::IMPORTANT_DISPLAY));
118 static_assert(static_cast<int64_t>(ThreadRole::USER_INTERACT) ==
119 static_cast<int64_t>(OHOS::ResourceSchedule::ResType::USER_INTERACT));
120
121 uint64_t uid = OS::GetUid();
122 uint64_t tid = OS::GetTid();
123 uint64_t pid = OS::GetPid();
124 std::unordered_map<std::string, std::string> payLoad = { { "uid", std::to_string(uid) },
125 { "pid", std::to_string(pid) },
126 { "tid", std::to_string(tid) },
127 { "role", std::to_string(role) } };
128 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(
129 OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_KEY_THREAD,
130 OHOS::ResourceSchedule::ResType::ReportChangeStatus::CREATE, payLoad);
131 }
132
ReadSystemXpmState()133 inline bool ReadSystemXpmState()
134 {
135 constexpr size_t argBuffSize = 32;
136 char buffer[argBuffSize] = { 0 };
137 uint32_t buffSize = sizeof(buffer);
138
139 if (SystemGetParameter("ohos.boot.advsecmode.state", buffer, &buffSize) == 0 && strcmp(buffer, "0") != 0) {
140 return true;
141 }
142 return false;
143 }
144
SetSecurityMode()145 void SetSecurityMode()
146 {
147 constexpr size_t secArgCnt = 2;
148 if (ReadSystemXpmState()) {
149 int secArgc = secArgCnt;
150 constexpr bool removeFlag = false;
151 const char* secArgv[secArgCnt] = { "jsvm", "--jitless" };
152 v8::V8::SetFlagsFromCommandLine(&secArgc, const_cast<char**>(reinterpret_cast<const char**>(secArgv)),
153 removeFlag);
154 }
155 }
156
157 constexpr int MAX_FILE_LENGTH = 32 * 1024 * 1024;
158
LoadStringFromFile(const std::string & filePath,std::string & content)159 bool LoadStringFromFile(const std::string& filePath, std::string& content)
160 {
161 std::ifstream file(filePath.c_str());
162 if (!file.is_open()) {
163 return false;
164 }
165
166 file.seekg(0, std::ios::end);
167 const long fileLength = file.tellg();
168 if (fileLength > MAX_FILE_LENGTH) {
169 return false;
170 }
171
172 content.clear();
173 file.seekg(0, std::ios::beg);
174 std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(content));
175 return true;
176 }
177
ProcessBundleName(std::string & bundleName)178 bool ProcessBundleName(std::string& bundleName)
179 {
180 int pid = getprocpid();
181 std::string filePath = "/proc/" + std::to_string(pid) + "/cmdline";
182 if (!LoadStringFromFile(filePath, bundleName)) {
183 return false;
184 }
185 if (bundleName.empty()) {
186 return false;
187 }
188 auto pos = bundleName.find(":");
189 if (pos != std::string::npos) {
190 bundleName = bundleName.substr(0, pos);
191 }
192 bundleName = bundleName.substr(0, strlen(bundleName.c_str()));
193 return true;
194 }
195
WriteHisysevent()196 void WriteHisysevent()
197 {
198 #ifdef ENABLE_HISYSEVENT
199 std::string bundleName;
200 if (!ProcessBundleName(bundleName)) {
201 bundleName = "INVALID_BUNDLE_NAME";
202 }
203 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::JSVM_RUNTIME, "APP_STATS",
204 OHOS::HiviewDFX::HiSysEvent::EventType::STATISTIC, "BUNDLE_NAME", bundleName);
205 #endif
206 }
207 } // namespace ohos
208
209 } // namespace platform
210