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