1 /*
2  * Copyright (c) 2021-2023 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 "hiview_service_ability_proxy.h"
17 
18 #include "ash_memory_utils.h"
19 #include "collect_result.h"
20 #include "hiview_logger.h"
21 
22 namespace OHOS {
23 namespace HiviewDFX {
24 namespace {
25 DEFINE_LOG_TAG("HiviewServiceAbilityProxy");
26 }
27 
List(const std::string & logType,std::vector<HiviewFileInfo> & fileInfos)28 int32_t HiviewServiceAbilityProxy::List(const std::string& logType, std::vector<HiviewFileInfo>& fileInfos)
29 {
30     HIVIEW_LOGI("type = %{public}s.", logType.c_str());
31     auto remote = Remote();
32     if (remote == nullptr) {
33         HIVIEW_LOGE("remote service is null.");
34         return HiviewNapiErrCode::ERR_DEFAULT;
35     }
36     MessageParcel data;
37     if (!data.WriteInterfaceToken(HiviewServiceAbilityProxy::GetDescriptor())
38         || !data.WriteString(logType)) {
39         HIVIEW_LOGE("write data failed.");
40         return HiviewNapiErrCode::ERR_DEFAULT;
41     }
42     MessageParcel reply;
43     MessageOption option;
44     int32_t res = remote->SendRequest(
45         static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_LIST), data, reply, option);
46     if (res != ERR_OK) {
47         HIVIEW_LOGE("send request failed, error is %{public}d.", res);
48         return res;
49     }
50     std::vector<uint32_t> allSize;
51     if (!reply.ReadUInt32Vector(&allSize)) {
52         HIVIEW_LOGE("read size error.");
53         return HiviewNapiErrCode::ERR_DEFAULT;
54     }
55     sptr<Ashmem> ashmem = reply.ReadAshmem();
56     if (ashmem == nullptr) {
57         HIVIEW_LOGE("read ashmem failed.");
58         return HiviewNapiErrCode::ERR_DEFAULT;
59     }
60     if (!ashmem->MapReadAndWriteAshmem()) {
61         HIVIEW_LOGE("map ash failed.");
62         return HiviewNapiErrCode::ERR_DEFAULT;
63     }
64     if (!AshMemoryUtils::ReadBulkData<HiviewFileInfo>(ashmem, allSize, fileInfos)) {
65         HIVIEW_LOGE("ReadBulkData failed");
66         return HiviewNapiErrCode::ERR_DEFAULT;
67     }
68     HIVIEW_LOGW("file list num:%{public}zu", fileInfos.size());
69     return ERR_OK;
70 }
71 
Copy(const std::string & logType,const std::string & logName,const std::string & dest)72 int32_t HiviewServiceAbilityProxy::Copy(const std::string& logType, const std::string& logName,
73     const std::string& dest)
74 {
75     return CopyOrMoveFile(logType, logName, dest, false);
76 }
77 
Move(const std::string & logType,const std::string & logName,const std::string & dest)78 int32_t HiviewServiceAbilityProxy::Move(const std::string& logType, const std::string& logName,
79     const std::string& dest)
80 {
81     return CopyOrMoveFile(logType, logName, dest, true);
82 }
83 
CopyOrMoveFile(const std::string & logType,const std::string & logName,const std::string & dest,bool isMove)84 int32_t HiviewServiceAbilityProxy::CopyOrMoveFile(
85     const std::string& logType, const std::string& logName, const std::string& dest, bool isMove)
86 {
87     auto remote = Remote();
88     if (remote == nullptr) {
89         HIVIEW_LOGE("remote service is null.");
90         return HiviewNapiErrCode::ERR_DEFAULT;
91     }
92     MessageParcel data;
93     if (!data.WriteInterfaceToken(HiviewServiceAbilityProxy::GetDescriptor())
94         || !data.WriteString(logType) || !data.WriteString(logName) || !data.WriteString(dest)) {
95         HIVIEW_LOGE("write data failed.");
96         return HiviewNapiErrCode::ERR_DEFAULT;
97     }
98     MessageParcel reply;
99     MessageOption option;
100     int32_t res = remote->SendRequest(
101         isMove ? static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_MOVE) :
102         static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_COPY), data, reply, option);
103     if (res != ERR_OK) {
104         HIVIEW_LOGE("send request failed, error is %{public}d.", res);
105         return res;
106     }
107     int32_t result = 0;
108     if (!reply.ReadInt32(result)) {
109         HIVIEW_LOGE("parcel read result failed.");
110         return HiviewNapiErrCode::ERR_DEFAULT;
111     }
112     return result;
113 }
114 
Remove(const std::string & logType,const std::string & logName)115 int32_t HiviewServiceAbilityProxy::Remove(const std::string& logType, const std::string& logName)
116 {
117     auto remote = Remote();
118     if (remote == nullptr) {
119         HIVIEW_LOGE("remote service is null.");
120         return HiviewNapiErrCode::ERR_DEFAULT;
121     }
122     MessageParcel data;
123     if (!data.WriteInterfaceToken(HiviewServiceAbilityProxy::GetDescriptor())
124         || !data.WriteString(logType) || !data.WriteString(logName)) {
125         HIVIEW_LOGE("write data failed.");
126         return HiviewNapiErrCode::ERR_DEFAULT;
127     }
128     MessageParcel reply;
129     MessageOption option;
130     int32_t res = remote->SendRequest(
131         static_cast<uint32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_REMOVE), data, reply, option);
132     if (res != ERR_OK) {
133         HIVIEW_LOGE("send request failed, error is %{public}d.", res);
134         return res;
135     }
136     int32_t result = 0;
137     if (!reply.ReadInt32(result)) {
138         HIVIEW_LOGE("parcel read result failed.");
139         return HiviewNapiErrCode::ERR_DEFAULT;
140     }
141     return result;
142 }
143 
OpenSnapshotTrace(const std::vector<std::string> & tagGroups)144 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::OpenSnapshotTrace(
145     const std::vector<std::string>& tagGroups)
146 {
147     auto parcelHandler = [&tagGroups] (MessageParcel& data) {
148         return data.WriteStringVector(tagGroups);
149     };
150     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_SNAPSHOT_TRACE,
151         parcelHandler);
152 }
153 
DumpSnapshotTrace(int32_t caller)154 CollectResultParcelable<std::vector<std::string>> HiviewServiceAbilityProxy::DumpSnapshotTrace(int32_t caller)
155 {
156     auto parcelHandler = [caller] (MessageParcel& data) {
157         return data.WriteInt32(caller);
158     };
159     return SendTraceRequest<std::vector<std::string>>(
160         HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_DUMP_SNAPSHOT_TRACE, parcelHandler);
161 }
162 
OpenRecordingTrace(const std::string & tags)163 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::OpenRecordingTrace(const std::string& tags)
164 {
165     auto parcelHandler = [&tags] (MessageParcel& data) {
166         return data.WriteString(tags);
167     };
168     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_OPEN_RECORDING_TRACE,
169         parcelHandler);
170 }
171 
RecordingTraceOn()172 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::RecordingTraceOn()
173 {
174     auto parcelHandler = [] (MessageParcel& data) {
175         return true;
176     };
177     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_ON,
178         parcelHandler);
179 }
180 
RecordingTraceOff()181 CollectResultParcelable<std::vector<std::string>> HiviewServiceAbilityProxy::RecordingTraceOff()
182 {
183     auto parcelHandler = [] (MessageParcel& data) {
184         return true;
185     };
186     return SendTraceRequest<std::vector<std::string>>(
187         HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECORDING_TRACE_OFF, parcelHandler);
188 }
189 
CloseTrace()190 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::CloseTrace()
191 {
192     auto parcelHandler = [] (MessageParcel& data) {
193         return true;
194     };
195     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_CLOSE_TRACE,
196         parcelHandler);
197 }
198 
RecoverTrace()199 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::RecoverTrace()
200 {
201     auto parcelHandler = [] (MessageParcel& data) {
202         return true;
203     };
204     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_RECOVER_TRACE,
205         parcelHandler);
206 }
207 
WriteAppCallerBase(MessageParcel & data,UCollectClient::AppCaller & appCaller,std::string & errField)208 static bool WriteAppCallerBase(MessageParcel& data, UCollectClient::AppCaller &appCaller, std::string &errField)
209 {
210     if (!data.WriteInt32(appCaller.actionId)) {
211         errField = "actionId";
212         return false;
213     }
214 
215     if (!data.WriteString(appCaller.bundleName)) {
216         errField = "bundleName";
217         return false;
218     }
219 
220     if (!data.WriteString(appCaller.bundleVersion)) {
221         errField = "bundleVersion";
222         return false;
223     }
224 
225     if (!data.WriteString(appCaller.threadName)) {
226         errField = "threadName";
227         return false;
228     }
229 
230     if (!data.WriteInt32(appCaller.foreground)) {
231         errField = "foreground";
232         return false;
233     }
234     return true;
235 }
236 
WriteAppCallerExternal(MessageParcel & data,UCollectClient::AppCaller & appCaller,std::string & errField)237 static bool WriteAppCallerExternal(MessageParcel& data, UCollectClient::AppCaller &appCaller, std::string &errField)
238 {
239     if (!data.WriteInt32(appCaller.uid)) {
240         errField = "uid";
241         return false;
242     }
243 
244     if (!data.WriteInt32(appCaller.pid)) {
245         errField = "pid";
246         return false;
247     }
248 
249     if (!data.WriteInt64(appCaller.happenTime)) {
250         errField = "happenTime";
251         return false;
252     }
253 
254     if (!data.WriteInt64(appCaller.beginTime)) {
255         errField = "beginTime";
256         return false;
257     }
258 
259     if (!data.WriteInt64(appCaller.endTime)) {
260         errField = "endTime";
261         return false;
262     }
263 
264     if (!data.WriteBool(appCaller.isBusinessJank)) {
265         errField = "isBusinessJank";
266         return false;
267     }
268     return true;
269 }
270 
CaptureDurationTrace(UCollectClient::AppCaller & appCaller)271 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::CaptureDurationTrace(UCollectClient::AppCaller &appCaller)
272 {
273     auto parcelHandler = [&appCaller] (MessageParcel& data) {
274         std::string errField;
275         do {
276             if (!WriteAppCallerBase(data, appCaller, errField)) {
277                 break;
278             }
279             if (!WriteAppCallerExternal(data, appCaller, errField)) {
280                 break;
281             }
282         } while (0);
283 
284         if (!errField.empty()) {
285             HIVIEW_LOGE("write field %{public}s failed", errField.c_str());
286             return false;
287         }
288         return true;
289     };
290     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_GET_APP_TRACE,
291         parcelHandler);
292 }
293 
GetSysCpuUsage()294 CollectResultParcelable<double> HiviewServiceAbilityProxy::GetSysCpuUsage()
295 {
296     auto parcelHandler = [] (MessageParcel& data) {
297         return true;
298     };
299     return SendTraceRequest<double>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_GET_SYSTEM_CPU_USAGE,
300         parcelHandler);
301 }
302 
SetAppResourceLimit(UCollectClient::MemoryCaller & memoryCaller)303 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::SetAppResourceLimit(
304     UCollectClient::MemoryCaller& memoryCaller)
305 {
306     auto parcelHandler = [&memoryCaller] (MessageParcel& data) {
307         if (!data.WriteInt32(memoryCaller.pid)) {
308             HIVIEW_LOGE("SetAppResourceLimit failed. write pid failed");
309             return false;
310         }
311 
312         if (!data.WriteString(memoryCaller.resourceType)) {
313             HIVIEW_LOGE("SetAppResourceLimit failed. write type failed");
314             return false;
315         }
316 
317         if (!data.WriteInt32(memoryCaller.limitValue)) {
318             HIVIEW_LOGE("SetAppResourceLimit failed. write value failed");
319             return false;
320         }
321 
322         if (!data.WriteBool(memoryCaller.enabledDebugLog)) {
323             HIVIEW_LOGE("SetAppResourceLimit failed. write enabledDebugLog failed");
324             return false;
325         }
326         return true;
327     };
328     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_SET_APPRESOURCE_LIMIT,
329         parcelHandler);
330 }
331 
GetGraphicUsage()332 CollectResultParcelable<int32_t> HiviewServiceAbilityProxy::GetGraphicUsage()
333 {
334     auto parcelHandler = [] (MessageParcel& data) {
335         return true;
336     };
337     return SendTraceRequest<int32_t>(HiviewServiceInterfaceCode::HIVIEW_SERVICE_ID_GET_GRAPHIC_USAGE, parcelHandler);
338 }
339 } // namespace HiviewDFX
340 } // namespace OHOS
341