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 <mutex>
17 #include <cinttypes>
18 #include <unordered_map>
19 #include "bms_adapter.h"
20 #include "camera_report_uitls.h"
21 
22 #include "camera_util.h"
23 #include "camera_log.h"
24 #include "hisysevent.h"
25 #include "ipc_skeleton.h"
26 #include "steady_clock.h"
27 
28 namespace OHOS {
29 namespace CameraStandard {
30 using namespace std;
31 
SetOpenCamPerfPreInfo(const string & cameraId,CallerInfo caller)32 void CameraReportUtils::SetOpenCamPerfPreInfo(const string& cameraId, CallerInfo caller)
33 {
34     MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfPreInfo");
35     unique_lock<mutex> lock(mutex_);
36     {
37         if (IsCallerChanged(caller_, caller)) {
38             MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfPreInfo caller changed");
39             isModeChanging_ = false;
40         }
41         openCamPerfStartTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
42         isPrelaunching_ = true;
43         cameraId_ = cameraId;
44         caller_ = caller;
45     }
46 }
47 
SetOpenCamPerfStartInfo(const string & cameraId,CallerInfo caller)48 void CameraReportUtils::SetOpenCamPerfStartInfo(const string& cameraId, CallerInfo caller)
49 {
50     MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfStartInfo");
51     unique_lock<mutex> lock(mutex_);
52     {
53         if (IsCallerChanged(caller_, caller)) {
54             MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfStartInfo caller changed");
55             isModeChanging_ = false;
56         }
57         if (!isPrelaunching_) {
58             openCamPerfStartTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
59             isOpening_ = true;
60             MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfStartInfo update start time");
61         }
62         preCameraId_ = cameraId_;
63         cameraId_ = cameraId;
64         caller_ = caller;
65     }
66 }
67 
SetOpenCamPerfEndInfo()68 void CameraReportUtils::SetOpenCamPerfEndInfo()
69 {
70     MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfEndInfo");
71     unique_lock<mutex> lock(mutex_);
72     {
73         if (!isPrelaunching_ && !isOpening_) {
74             MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfEndInfo not ready");
75             return;
76         }
77         if (isSwitching_) {
78             MEDIA_DEBUG_LOG("CameraReportUtils::SetOpenCamPerfEndInfo cancel report");
79             isOpening_ = false;
80             isPrelaunching_ = false;
81             return;
82         }
83         openCamPerfEndTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
84         string startType = isPrelaunching_ ? "preLaunch" : "open";
85         isOpening_ = false;
86         isPrelaunching_ = false;
87         ReportOpenCameraPerf(openCamPerfEndTime_ - openCamPerfStartTime_, startType);
88     }
89 }
90 
ReportOpenCameraPerf(uint64_t costTime,const string & startType)91 void CameraReportUtils::ReportOpenCameraPerf(uint64_t costTime, const string& startType)
92 {
93     MEDIA_DEBUG_LOG("CameraReportUtils::ReportOpenCameraPerf costTime: %{public}" PRIu64 "", costTime);
94     HiSysEventWrite(
95         HiviewDFX::HiSysEvent::Domain::CAMERA,
96         "PERFORMANCE_START",
97         HiviewDFX::HiSysEvent::EventType::STATISTIC,
98         "CALLER_PID", caller_.pid,
99         "CALLER_UID", caller_.uid,
100         "CALLER_TOKENID", caller_.tokenID,
101         "CALLER_BUNDLE_NAME", caller_.bundleName,
102         "COST_TIME", costTime,
103         "CUR_CAMERA_ID", cameraId_,
104         "START_TYPE", startType,
105         "CUR_MODE", curMode_);
106 }
107 
SetModeChangePerfStartInfo(int32_t preMode,CallerInfo caller)108 void CameraReportUtils::SetModeChangePerfStartInfo(int32_t preMode, CallerInfo caller)
109 {
110     MEDIA_DEBUG_LOG("CameraReportUtils::SetModeChangePerfStartInfo");
111     unique_lock<mutex> lock(mutex_);
112     {
113         modeChangeStartTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
114         isModeChanging_ = true;
115         preMode_ = preMode;
116         caller_ = caller;
117         ResetImagingValue();
118     }
119 }
120 
updateModeChangePerfInfo(int32_t curMode,CallerInfo caller)121 void CameraReportUtils::updateModeChangePerfInfo(int32_t curMode, CallerInfo caller)
122 {
123     MEDIA_DEBUG_LOG("CameraReportUtils::updateModeChangePerfInfo");
124     unique_lock<mutex> lock(mutex_);
125     {
126         if (IsCallerChanged(caller_, caller)) {
127             MEDIA_DEBUG_LOG("updateModeChangePerfInfo caller changed, cancle mode change report");
128             isModeChanging_ = false;
129         }
130         caller_ = caller;
131         curMode_ = curMode;
132     }
133 }
134 
SetModeChangePerfEndInfo()135 void CameraReportUtils::SetModeChangePerfEndInfo()
136 {
137     MEDIA_DEBUG_LOG("CameraReportUtils::SetModeChangePerfEndInfo");
138     unique_lock<mutex> lock(mutex_);
139     {
140         if (!isModeChanging_) {
141             MEDIA_DEBUG_LOG("CameraReportUtils::SetModeChangePerfEndInfo cancel report");
142             return;
143         }
144         if (curMode_ == preMode_ || isSwitching_) {
145             MEDIA_DEBUG_LOG("CameraReportUtils::SetModeChangePerfEndInfo mode not changed");
146             isModeChanging_ = false;
147             return;
148         }
149 
150         modeChangeEndTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
151         isModeChanging_ = false;
152         ReportModeChangePerf(modeChangeEndTime_ - modeChangeStartTime_);
153     }
154 }
155 
ReportModeChangePerf(uint64_t costTime)156 void CameraReportUtils::ReportModeChangePerf(uint64_t costTime)
157 {
158     MEDIA_DEBUG_LOG("CameraReportUtils::ReportModeChangePerf costTime:  %{public}" PRIu64 "", costTime);
159     HiSysEventWrite(
160         HiviewDFX::HiSysEvent::Domain::CAMERA,
161         "PERFORMANCE_MODE_CHANGE",
162         HiviewDFX::HiSysEvent::EventType::STATISTIC,
163         "CALLER_PID", caller_.pid,
164         "CALLER_UID", caller_.uid,
165         "CALLER_TOKENID", caller_.tokenID,
166         "CALLER_BUNDLE_NAME", caller_.bundleName,
167         "COST_TIME", costTime,
168         "PRE_MODE", preMode_,
169         "CUR_MODE", curMode_,
170         "PRE_CAMERA_ID", preCameraId_,
171         "CUR_CAMERA_ID", cameraId_);
172 }
173 
SetCapturePerfStartInfo(DfxCaptureInfo captureInfo)174 void CameraReportUtils::SetCapturePerfStartInfo(DfxCaptureInfo captureInfo)
175 {
176     MEDIA_DEBUG_LOG("CameraReportUtils::SetCapturePerfStartInfo captureID: %{public}d", captureInfo.captureId);
177     captureInfo.captureStartTime = DeferredProcessing::SteadyClock::GetTimestampMilli();
178     unique_lock<mutex> lock(mutex_);
179     captureList_.insert(pair<int32_t, DfxCaptureInfo>(captureInfo.captureId, captureInfo));
180 }
181 
SetCapturePerfEndInfo(int32_t captureId)182 void CameraReportUtils::SetCapturePerfEndInfo(int32_t captureId)
183 {
184     MEDIA_DEBUG_LOG("CameraReportUtils::SetCapturePerfEndInfo start");
185     unique_lock<mutex> lock(mutex_);
186     {
187         map<int32_t, DfxCaptureInfo>::iterator iter = captureList_.find(captureId);
188         if (iter != captureList_.end()) {
189             MEDIA_DEBUG_LOG("CameraReportUtils::SetCapturePerfEndInfo");
190             auto dfxCaptureInfo = iter->second;
191             dfxCaptureInfo.captureEndTime = DeferredProcessing::SteadyClock::GetTimestampMilli();
192             ReportCapturePerf(dfxCaptureInfo);
193             ReportImagingInfo(dfxCaptureInfo);
194             captureList_.erase(captureId);
195         }
196     }
197 }
198 
ReportCapturePerf(DfxCaptureInfo captureInfo)199 void CameraReportUtils::ReportCapturePerf(DfxCaptureInfo captureInfo)
200 {
201     MEDIA_DEBUG_LOG("CameraReportUtils::ReportCapturePerf captureInfo");
202     HiSysEventWrite(
203         HiviewDFX::HiSysEvent::Domain::CAMERA,
204         "PERFORMANCE_CAPTURE",
205         HiviewDFX::HiSysEvent::EventType::STATISTIC,
206         "CALLER_PID", captureInfo.caller.pid,
207         "CALLER_UID", captureInfo.caller.uid,
208         "CALLER_TOKENID", captureInfo.caller.tokenID,
209         "CALLER_BUNDLE_NAME", captureInfo.caller.bundleName,
210         "COST_TIME", captureInfo.captureEndTime - captureInfo.captureStartTime,
211         "CAPTURE_ID", captureInfo.captureId,
212         "CUR_MODE", curMode_,
213         "CUR_CAMERA_ID", cameraId_);
214 }
215 
SetSwitchCamPerfStartInfo(CallerInfo caller)216 void CameraReportUtils::SetSwitchCamPerfStartInfo(CallerInfo caller)
217 {
218     MEDIA_DEBUG_LOG("CameraReportUtils::SetSwitchCamPerfStartInfo");
219     unique_lock<mutex> lock(mutex_);
220     {
221         switchCamPerfStartTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
222         isSwitching_ = true;
223         caller_ = caller;
224     }
225 }
226 
SetSwitchCamPerfEndInfo()227 void CameraReportUtils::SetSwitchCamPerfEndInfo()
228 {
229     MEDIA_DEBUG_LOG("CameraReportUtils::SetSwitchCamPerfEndInfo");
230     unique_lock<mutex> lock(mutex_);
231     {
232         if (!isSwitching_) {
233             MEDIA_DEBUG_LOG("CameraReportUtils::SetSwitchCamPerfEndInfo cancel report");
234             return;
235         }
236 
237         switchCamPerfEndTime_ = DeferredProcessing::SteadyClock::GetTimestampMilli();
238         isSwitching_ = false;
239         ReportSwitchCameraPerf(switchCamPerfEndTime_ - switchCamPerfStartTime_);
240     }
241 }
242 
ReportSwitchCameraPerf(uint64_t costTime)243 void CameraReportUtils::ReportSwitchCameraPerf(uint64_t costTime)
244 {
245     MEDIA_DEBUG_LOG("CameraReportUtils::ReportSwitchCameraPerf costTime:  %{public}" PRIu64 "", costTime);
246     HiSysEventWrite(
247         HiviewDFX::HiSysEvent::Domain::CAMERA,
248         "PERFORMANCE_SWITCH_CAMERA",
249         HiviewDFX::HiSysEvent::EventType::STATISTIC,
250         "CALLER_PID", caller_.pid,
251         "CALLER_UID", caller_.uid,
252         "CALLER_TOKENID", caller_.tokenID,
253         "CALLER_BUNDLE_NAME", caller_.bundleName,
254         "COST_TIME", costTime,
255         "PRE_MODE", preMode_,
256         "CUR_MODE", curMode_,
257         "PRE_CAMERA_ID", preCameraId_,
258         "CUR_CAMERA_ID", cameraId_);
259 }
260 
GetCallerInfo()261 CallerInfo CameraReportUtils::GetCallerInfo()
262 {
263     CallerInfo callerInfo;
264     callerInfo.pid = IPCSkeleton::GetCallingPid();
265     callerInfo.uid = IPCSkeleton::GetCallingUid();
266     callerInfo.tokenID = IPCSkeleton::GetCallingTokenID();
267     callerInfo.bundleName = BmsAdapter::GetInstance()->GetBundleName(callerInfo.uid);
268     MEDIA_DEBUG_LOG("CameraReportUtils::GetCallerInfo pid:%{public}d uid:%{public}d", callerInfo.pid, callerInfo.uid);
269     return callerInfo;
270 }
271 
IsCallerChanged(CallerInfo preCaller,CallerInfo curCaller)272 bool CameraReportUtils::IsCallerChanged(CallerInfo preCaller, CallerInfo curCaller)
273 {
274     if (preCaller.pid != curCaller.pid ||
275         preCaller.uid != curCaller.uid ||
276         preCaller.tokenID != curCaller.tokenID
277     ) {
278         return true;
279     }
280     return false;
281 }
282 
ReportCameraError(string funcName,int32_t errCode,bool isHdiErr,CallerInfo callerInfo)283 void CameraReportUtils::ReportCameraError(string funcName,
284                                           int32_t errCode,
285                                           bool isHdiErr,
286                                           CallerInfo callerInfo)
287 {
288     string str = funcName;
289     if (isHdiErr) {
290         str += " faild, hdi errCode:" + to_string(errCode);
291     } else {
292         str += " faild, errCode:" + to_string(errCode);
293     }
294     str += " caller pid:" + to_string(callerInfo.pid)
295         + " uid:" + to_string(callerInfo.uid)
296         + " tokenID:" + to_string(callerInfo.tokenID)
297         + " bundleName:" + callerInfo.bundleName;
298     HiSysEventWrite(
299         HiviewDFX::HiSysEvent::Domain::CAMERA,
300         "CAMERA_ERR",
301         HiviewDFX::HiSysEvent::EventType::FAULT,
302         "MSG", str);
303 }
304 
ReportUserBehavior(string behaviorName,string value,CallerInfo callerInfo)305 void CameraReportUtils::ReportUserBehavior(string behaviorName,
306                                            string value,
307                                            CallerInfo callerInfo)
308 {
309     unique_lock<mutex> lock(mutex_);
310     {
311         if (!IsBehaviorNeedReport(behaviorName, value)) {
312             MEDIA_DEBUG_LOG("CameraReportUtils::ReportUserBehavior cancle");
313             return;
314         }
315         MEDIA_DEBUG_LOG("CameraReportUtils::ReportUserBehavior");
316         stringstream ss;
317         ss << S_BEHAVIORNAME << behaviorName
318         << S_VALUE << value
319         << S_CUR_MODE << curMode_
320         << S_CUR_CAMERAID << cameraId_
321         << S_CPID << callerInfo.pid
322         << S_CUID << callerInfo.uid
323         << S_CTOKENID << callerInfo.tokenID
324         << S_CBUNDLENAME << callerInfo.bundleName;
325 
326         HiSysEventWrite(
327             HiviewDFX::HiSysEvent::Domain::CAMERA,
328             "USER_BEHAVIOR",
329             HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
330             "MSG", ss.str());
331     }
332 }
333 
ReportImagingInfo(DfxCaptureInfo dfxCaptureInfo)334 void CameraReportUtils::ReportImagingInfo(DfxCaptureInfo dfxCaptureInfo)
335 {
336     MEDIA_DEBUG_LOG("CameraReportUtils::ReportImagingInfo");
337     stringstream ss;
338     ss << "CurMode:" << curMode_ << ",CameraId:" << cameraId_ << ",Profile:" << profile_;
339     for (auto it = imagingValueList_.begin(); it != imagingValueList_.end(); it++) {
340         ss << "," << it->first << ":" << it->second;
341     }
342 
343     HiSysEventWrite(
344         HiviewDFX::HiSysEvent::Domain::CAMERA,
345         "IMAGING_INFO",
346         HiviewDFX::HiSysEvent::EventType::STATISTIC,
347         "MSG", ss.str());
348 }
349 
UpdateProfileInfo(const string & profileStr)350 void CameraReportUtils::UpdateProfileInfo(const string& profileStr)
351 {
352     profile_ = profileStr;
353 }
354 
UpdateImagingInfo(const string & imagingKey,const string & value)355 void CameraReportUtils::UpdateImagingInfo(const string& imagingKey, const string& value)
356 {
357     auto it = imagingValueList_.find(imagingKey);
358     if (it != imagingValueList_.end()) {
359         it->second = value;
360     } else {
361         imagingValueList_.emplace(imagingKey, value);
362     }
363 }
364 
IsBehaviorNeedReport(const string & behaviorName,const string & value)365 bool CameraReportUtils::IsBehaviorNeedReport(const string& behaviorName, const string& value)
366 {
367     auto it = mapBehaviorImagingKey.find(behaviorName);
368     if (it == mapBehaviorImagingKey.end()) {
369         MEDIA_ERR_LOG("IsBehaviorNeedReport error imagingKey not found.");
370         return true;
371     }
372     const string& imagingKey = it->second;
373     auto valueIt = imagingValueList_.find(imagingKey);
374     if (valueIt != imagingValueList_.end()) {
375         if (valueIt->second == value) {
376             return false;
377         } else {
378             valueIt->second = value;
379             return true;
380         }
381     } else {
382         imagingValueList_.emplace(imagingKey, value);
383         return true;
384     }
385 }
386 
ResetImagingValue()387 void CameraReportUtils::ResetImagingValue()
388 {
389     imagingValueList_.clear();
390 }
391 
SetVideoStartInfo(DfxCaptureInfo captureInfo)392 void CameraReportUtils::SetVideoStartInfo(DfxCaptureInfo captureInfo)
393 {
394     MEDIA_DEBUG_LOG("CameraReportUtils::SetVideoStartInfo captureID: %{public}d", captureInfo.captureId);
395     captureInfo.captureStartTime = DeferredProcessing::SteadyClock::GetTimestampMilli();
396     unique_lock<mutex> lock(mutex_);
397     captureList_.insert(pair<int32_t, DfxCaptureInfo>(captureInfo.captureId, captureInfo));
398 }
399 
SetVideoEndInfo(int32_t captureId)400 void CameraReportUtils::SetVideoEndInfo(int32_t captureId)
401 {
402     MEDIA_DEBUG_LOG("CameraReportUtils::SetVideoEndInfo start");
403     unique_lock<mutex> lock(mutex_);
404     {
405         map<int32_t, DfxCaptureInfo>::iterator iter = captureList_.find(captureId);
406         if (iter != captureList_.end()) {
407             MEDIA_DEBUG_LOG("CameraReportUtils::SetVideoEndInfo");
408             auto dfxCaptureInfo = iter->second;
409             dfxCaptureInfo.captureEndTime = DeferredProcessing::SteadyClock::GetTimestampMilli();
410             imagingValueList_.emplace("VideoDuration",
411                 to_string(dfxCaptureInfo.captureEndTime - dfxCaptureInfo.captureStartTime));
412             ReportImagingInfo(dfxCaptureInfo);
413             captureList_.erase(captureId);
414         }
415     }
416 }
417 } // namespace CameraStandard
418 } // namespace OHOS
419