• 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 "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