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 "test_server_service.h" 17 18 #include "iremote_object.h" 19 #include "system_ability_definition.h" 20 #include "hilog/log.h" 21 #include "parameters.h" 22 #include "iservice_registry.h" 23 #include "test_server_error_code.h" 24 #include "pasteboard_client.h" 25 #include "session_manager_lite.h" 26 #include "wm_common.h" 27 #include "ws_common.h" 28 #include "socperf_client.h" 29 #include <nlohmann/json.hpp> 30 #include <sstream> 31 #include "accesstoken_kit.h" 32 #include "tokenid_kit.h" 33 #include "memory_collector.h" 34 35 namespace OHOS::testserver { 36 // TEST_SERVER_SA_ID 37 REGISTER_SYSTEM_ABILITY_BY_ID(TestServerService, TEST_SERVER_SA_ID, false); // SA run on demand 38 39 using namespace std; 40 using namespace OHOS::HiviewDFX; 41 using namespace OHOS::HiviewDFX::UCollectUtil; 42 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL_SERVICE = {LOG_CORE, 0xD003110, "TestServerService"}; 43 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL_TIMER = {LOG_CORE, 0xD003110, "CallerDetectTimer"}; 44 static const int CALLER_DETECT_DURING = 10000; 45 static const int START_SPDAEMON_PROCESS = 1; 46 static const int KILL_SPDAEMON_PROCESS = 2; 47 static const int PARA_START_POSITION = 0; 48 static const int PARA_END_POSITION = 4; 49 TestServerService(int32_t saId,bool runOnCreate)50 TestServerService::TestServerService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) 51 { 52 HiLog::Debug(LABEL_SERVICE, "%{public}s called. saId=%{public}d, runOnCreate=%{public}d", 53 __func__, saId, runOnCreate); 54 StartCallerDetectTimer(); 55 } 56 ~TestServerService()57 TestServerService::~TestServerService() 58 { 59 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 60 if (callerDetectTimer_ == nullptr) { 61 HiLog::Error(LABEL_SERVICE, "%{public}s. callerDetectTimer_ is nullptr.", __func__); 62 return; 63 } 64 callerDetectTimer_->Cancel(); 65 } 66 OnStart()67 void TestServerService::OnStart() 68 { 69 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 70 if (!IsRootVersion() && !IsDeveloperMode()) { 71 HiLog::Error(LABEL_SERVICE, "%{public}s. System mode is unsatisfied.", __func__); 72 return; 73 } 74 bool res = Publish(this); 75 if (!res) { 76 HiLog::Error(LABEL_SERVICE, "%{public}s. Publish failed", __func__); 77 } 78 } 79 OnStop()80 void TestServerService::OnStop() 81 { 82 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 83 IsDeveloperMode(); 84 } 85 IsRootVersion()86 bool TestServerService::IsRootVersion() 87 { 88 bool debugmode = OHOS::system::GetBoolParameter("const.debuggable", false); 89 HiLog::Debug(LABEL_SERVICE, "%{public}s. debugmode=%{public}d", __func__, debugmode); 90 return debugmode; 91 } 92 IsDeveloperMode()93 bool TestServerService::IsDeveloperMode() 94 { 95 bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false); 96 HiLog::Debug(LABEL_SERVICE, "%{public}s. developerMode=%{public}d", __func__, developerMode); 97 return developerMode; 98 } 99 StartCallerDetectTimer()100 void TestServerService::StartCallerDetectTimer() 101 { 102 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 103 callerDetectTimer_ = new CallerDetectTimer(this); 104 callerDetectTimer_->Start(); 105 } 106 CreateSession(const SessionToken & sessionToken)107 ErrCode TestServerService::CreateSession(const SessionToken &sessionToken) 108 { 109 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 110 bool result = true; 111 try { 112 result = sessionToken.AddDeathRecipient( 113 sptr<TestServerProxyDeathRecipient>(new TestServerProxyDeathRecipient(this))); 114 } catch(...) { 115 result = false; 116 } 117 if (!result) { 118 HiLog::Error(LABEL_SERVICE, "%{public}s. AddDeathRecipient FAILD.", __func__); 119 DestorySession(); 120 return TEST_SERVER_ADD_DEATH_RECIPIENT_FAILED; 121 } 122 AddCaller(); 123 HiLog::Debug(LABEL_SERVICE, "%{public}s. Create session SUCCESS. callerCount=%{public}d", 124 __func__, GetCallerCount()); 125 return TEST_SERVER_OK; 126 } 127 SetPasteData(const std::string & text)128 ErrCode TestServerService::SetPasteData(const std::string& text) 129 { 130 HiLog::Info(LABEL_SERVICE, "%{public}s called.", __func__); 131 auto pasteBoardMgr = MiscServices::PasteboardClient::GetInstance(); 132 pasteBoardMgr->Clear(); 133 auto pasteData = pasteBoardMgr->CreatePlainTextData(text); 134 if (pasteData == nullptr) { 135 return TEST_SERVER_CREATE_PASTE_DATA_FAILED; 136 } 137 int32_t ret = pasteBoardMgr->SetPasteData(*pasteData); 138 int32_t successErrCode = 27787264; 139 return ret == successErrCode ? TEST_SERVER_OK : TEST_SERVER_SET_PASTE_DATA_FAILED; 140 } 141 PublishCommonEvent(const EventFwk::CommonEventData & event,bool & re)142 ErrCode TestServerService::PublishCommonEvent(const EventFwk::CommonEventData &event, bool &re) 143 { 144 if (!EventFwk::CommonEventManager::PublishCommonEvent(event)) { 145 HiLog::Info(LABEL_SERVICE, "%{public}s Pulbish commonEvent.", __func__); 146 re = false; 147 } 148 re = true; 149 int32_t ret = re ? TEST_SERVER_OK : TEST_SERVER_PUBLISH_EVENT_FAILED; 150 return ret; 151 } 152 AddCaller()153 void TestServerService::AddCaller() 154 { 155 callerCount_++; 156 } 157 RemoveCaller()158 void TestServerService::RemoveCaller() 159 { 160 callerCount_--; 161 } 162 GetCallerCount()163 int TestServerService::GetCallerCount() 164 { 165 return callerCount_.load(); 166 } 167 DestorySession()168 void TestServerService::DestorySession() 169 { 170 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 171 if (callerCount_ == 0) { 172 HiLog::Debug(LABEL_SERVICE, "%{public}s. No proxy exists. Remove the TestServer", __func__); 173 RemoveTestServer(); 174 } else { 175 HiLog::Debug(LABEL_SERVICE, "%{public}s. Other proxys exist. Can not remove the TestServer", __func__); 176 } 177 } 178 RemoveTestServer()179 bool TestServerService::RemoveTestServer() 180 { 181 HiLog::Debug(LABEL_SERVICE, "%{public}s called. ", __func__); 182 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 183 if (samgr == nullptr) { 184 HiLog::Error(LABEL_SERVICE, "%{public}s. Get SystemAbility Manager failed!", __func__); 185 return false; 186 } 187 auto res = samgr->UnloadSystemAbility(TEST_SERVER_SA_ID); 188 return res == ERR_OK; 189 } 190 OnRemoteDied(const wptr<IRemoteObject> & object)191 void TestServerService::TestServerProxyDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object) 192 { 193 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 194 if (object == nullptr) { 195 HiLog::Error(LABEL_SERVICE, "%{public}s. IRemoteObject is NULL.", __func__); 196 return; 197 } 198 testServerService_->RemoveCaller(); 199 testServerService_->DestorySession(); 200 } 201 Start()202 void TestServerService::CallerDetectTimer::Start() 203 { 204 HiLog::Debug(LABEL_TIMER, "%{public}s called.", __func__); 205 thread_ = thread([this] { 206 this_thread::sleep_for(chrono::milliseconds(CALLER_DETECT_DURING)); 207 HiLog::Debug(LABEL_TIMER, "%{public}s. Timer is done.", __func__); 208 if (!testServerExit_) { 209 testServerService_->DestorySession(); 210 } 211 }); 212 thread_.detach(); 213 } 214 Cancel()215 void TestServerService::CallerDetectTimer::Cancel() 216 { 217 HiLog::Debug(LABEL_TIMER, "%{public}s called.", __func__); 218 testServerExit_ = true; 219 } 220 FrequencyLock()221 ErrCode TestServerService::FrequencyLock() 222 { 223 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 224 int performanceModeId = 9100; 225 OHOS::SOCPERF::SocPerfClient::GetInstance().PerfRequest(performanceModeId, ""); 226 return TEST_SERVER_OK; 227 } 228 ParseDaemonCommand(const std::string & extraInfo)229 static std::string ParseDaemonCommand(const std::string& extraInfo) 230 { 231 try { 232 nlohmann::json json = nlohmann::json::parse(extraInfo); 233 std::vector<int> paraIndices; 234 for (auto it = json.begin(); it != json.end(); ++it) { 235 const std::string& key = it.key(); 236 if (key.compare(PARA_START_POSITION, PARA_END_POSITION, "para") != 0) { 237 continue; 238 } 239 try { 240 int index = std::stoi(key.substr(PARA_END_POSITION)); 241 paraIndices.push_back(index); 242 } catch (const std::exception&) { 243 HiLog::Error(LABEL_SERVICE, "Daemon receive an error param: %{public}s", key.c_str()); 244 } 245 } 246 std::sort(paraIndices.begin(), paraIndices.end()); 247 std::ostringstream oss; 248 249 for (int index : paraIndices) { 250 std::string paraKey = "para" + std::to_string(index); 251 std::string valueKey = "value" + std::to_string(index); 252 if (json.contains(paraKey)) { 253 std::string param = json[paraKey].get<std::string>(); 254 std::string value = json.contains(valueKey) ? json[valueKey].get<std::string>() : ""; 255 oss << " " << param << " " << value; 256 } 257 } 258 return oss.str(); 259 } catch (const nlohmann::json::exception& e) { 260 HiLog::Error(LABEL_SERVICE, "JSON parse error: %{public}s", e.what()); 261 return ""; 262 } 263 } 264 SpDaemonProcess(int daemonCommand,const std::string & extraInfo)265 ErrCode TestServerService::SpDaemonProcess(int daemonCommand, const std::string& extraInfo) 266 { 267 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 268 if (extraInfo == "") { 269 HiLog::Error(LABEL_SERVICE, "%{public}s called. but extraInfo is empty", __func__); 270 return TEST_SERVER_SPDAEMON_PROCESS_FAILED; 271 } 272 std::string params = ParseDaemonCommand(extraInfo); 273 274 if (daemonCommand == START_SPDAEMON_PROCESS) { 275 std::string command = std::string("./system/bin/SP_daemon " + params + " &"); 276 std::system(command.c_str()); 277 } else if (daemonCommand == KILL_SPDAEMON_PROCESS) { 278 const std::string spDaemonProcessName = "SP_daemon"; 279 KillProcess(spDaemonProcessName); 280 } 281 return TEST_SERVER_OK; 282 } 283 KillProcess(const std::string & processName)284 void TestServerService::KillProcess(const std::string& processName) 285 { 286 std::string cmd = "ps -ef | grep -v grep | grep " + processName; 287 if (cmd.empty()) { 288 return; 289 } 290 FILE *fd = popen(cmd.c_str(), "r"); 291 if (fd == nullptr) { 292 return; 293 } 294 char buf[4096] = {'\0'}; 295 while ((fgets(buf, sizeof(buf), fd)) != nullptr) { 296 std::string line(buf); 297 HiLog::Debug(LABEL_SERVICE, "line %s", line.c_str()); 298 std::istringstream iss(line); 299 std::string field; 300 std::string pid = "-1"; 301 int count = 0; 302 while (iss >> field) { 303 if (count == 1) { 304 pid = field; 305 break; 306 } 307 count++; 308 } 309 HiLog::Debug(LABEL_SERVICE, "pid %s", pid.c_str()); 310 cmd = "kill " + pid; 311 FILE *fpd = popen(cmd.c_str(), "r"); 312 if (pclose(fpd) == -1) { 313 HiLog::Debug(LABEL_SERVICE, "Error: Failed to close file"); 314 return; 315 } 316 } 317 if (pclose(fd) == -1) { 318 HiLog::Debug(LABEL_SERVICE, "Error: Failed to close file"); 319 return; 320 } 321 } 322 CollectProcessMemory(const int32_t pid,ProcessMemoryInfo & processMemoryInfo)323 ErrCode TestServerService::CollectProcessMemory(const int32_t pid, ProcessMemoryInfo &processMemoryInfo) 324 { 325 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 326 shared_ptr<MemoryCollector> collector = MemoryCollector::Create(); 327 CollectResult<ProcessMemory> processMemory = collector->CollectProcessMemory(pid); 328 if (processMemory.retCode != 0) { 329 HiLog::Error(LABEL_SERVICE, "%{public}s. Collect process memory failed.", __func__); 330 return TEST_SERVER_COLLECT_PROCESS_INFO_FAILED; 331 } 332 processMemoryInfo.pid = processMemory.data.pid; 333 processMemoryInfo.name = processMemory.data.name; 334 processMemoryInfo.rss = processMemory.data.rss; 335 processMemoryInfo.pss = processMemory.data.pss; 336 processMemoryInfo.swapPss = processMemory.data.swapPss; 337 processMemoryInfo.adj = processMemory.data.adj; 338 processMemoryInfo.sharedDirty = processMemory.data.sharedDirty; 339 processMemoryInfo.privateDirty = processMemory.data.privateDirty; 340 processMemoryInfo.sharedClean = processMemory.data.sharedClean; 341 processMemoryInfo.privateClean = processMemory.data.privateClean; 342 processMemoryInfo.procState = processMemory.data.procState; 343 HiLog::Debug(LABEL_SERVICE, "%{public}s. Collect process memory success.", __func__); 344 return TEST_SERVER_OK; 345 } 346 CollectProcessCpu(const int32_t pid,bool isNeedUpdate,ProcessCpuInfo & processCpuInfo)347 ErrCode TestServerService::CollectProcessCpu(const int32_t pid, bool isNeedUpdate, ProcessCpuInfo &processCpuInfo) 348 { 349 HiLog::Debug(LABEL_SERVICE, "%{public}s called.", __func__); 350 if (cpuCollector_ == nullptr) { 351 cpuCollector_ = CpuCollector::Create(); 352 } 353 CollectResult<ProcessCpuStatInfo> processCpuStatInfo = 354 cpuCollector_->CollectProcessCpuStatInfo(pid, isNeedUpdate); 355 if (processCpuStatInfo.retCode != 0) { 356 // Retry to avoid CPU collection failed caused by non-existent process during cpucollactor_ initialization 357 processCpuStatInfo = cpuCollector_->CollectProcessCpuStatInfo(pid, isNeedUpdate); 358 if (processCpuStatInfo.retCode != 0) { 359 HiLog::Error(LABEL_SERVICE, "%{public}s. Collect process cpu failed.", __func__); 360 return TEST_SERVER_COLLECT_PROCESS_INFO_FAILED; 361 } 362 HiLog::Debug(LABEL_SERVICE, "%{public}s. Retry to collect success.", __func__); 363 } 364 processCpuInfo.startTime = processCpuStatInfo.data.startTime; 365 processCpuInfo.endTime = processCpuStatInfo.data.endTime; 366 processCpuInfo.pid = processCpuStatInfo.data.pid; 367 processCpuInfo.minFlt = processCpuStatInfo.data.minFlt; 368 processCpuInfo.majFlt = processCpuStatInfo.data.majFlt; 369 processCpuInfo.cpuLoad = processCpuStatInfo.data.cpuLoad; 370 processCpuInfo.uCpuUsage = processCpuStatInfo.data.uCpuUsage; 371 processCpuInfo.sCpuUsage = processCpuStatInfo.data.sCpuUsage; 372 processCpuInfo.cpuUsage = processCpuStatInfo.data.cpuUsage; 373 processCpuInfo.procName = processCpuStatInfo.data.procName; 374 processCpuInfo.threadCount = processCpuStatInfo.data.threadCount; 375 HiLog::Debug(LABEL_SERVICE, "%{public}s. Collect process cpu success.", __func__); 376 return TEST_SERVER_OK; 377 } 378 ChangeWindowMode(int windowId,uint32_t mode)379 ErrCode TestServerService::ChangeWindowMode(int windowId, uint32_t mode) 380 { 381 HiLog::Info(LABEL_SERVICE, "%{public}s called.", __func__); 382 auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); 383 HiLog::Info(LABEL_SERVICE, "Begin to updateWindowModeById %{public}d, mode: %{public}d.", windowId, mode); 384 auto ret = sceneSessionManager->UpdateWindowModeByIdForUITest(windowId, mode); 385 HiLog::Info(LABEL_SERVICE, "updateWindowModeById over, ret: %{public}d", ret); 386 return ret == OHOS::Rosen::WMError::WM_OK ? TEST_SERVER_OK : TEST_SERVER_OPERATE_WINDOW_FAILED; 387 } 388 TerminateWindow(int windowId)389 ErrCode TestServerService::TerminateWindow(int windowId) 390 { 391 HiLog::Info(LABEL_SERVICE, "%{public}s called.", __func__); 392 auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); 393 HiLog::Info(LABEL_SERVICE, "Begin to terminateWindow %{public}d", windowId); 394 auto ret = sceneSessionManager->TerminateSessionByPersistentId(windowId); 395 HiLog::Info(LABEL_SERVICE, "TerminateWindow over, ret: %{public}d", ret); 396 return ret == OHOS::Rosen::WMError::WM_OK ? TEST_SERVER_OK : TEST_SERVER_OPERATE_WINDOW_FAILED; 397 } 398 MinimizeWindow(int windowId)399 ErrCode TestServerService::MinimizeWindow(int windowId) 400 { 401 HiLog::Info(LABEL_SERVICE, "%{public}s called.", __func__); 402 auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy(); 403 HiLog::Info(LABEL_SERVICE, "Begin to minimizeWindow %{public}d", windowId); 404 auto ret = sceneSessionManager->PendingSessionToBackgroundByPersistentId(windowId); 405 HiLog::Info(LABEL_SERVICE, "MinimizeWindow over, ret: %{public}d", ret); 406 return ret == OHOS::Rosen::WSError::WS_OK ? TEST_SERVER_OK : TEST_SERVER_OPERATE_WINDOW_FAILED; 407 } 408 } // namespace OHOS::testserver