• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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