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 #define MLOG_TAG "DfxReporter"
16 
17 #include "dfx_reporter.h"
18 
19 #include <vector>
20 
21 #include "dfx_const.h"
22 #include "dfx_utils.h"
23 #include "dfx_database_utils.h"
24 #include "medialibrary_errno.h"
25 #include "media_file_utils.h"
26 #include "media_log.h"
27 #include "hisysevent.h"
28 #include "preferences.h"
29 #include "preferences_helper.h"
30 #include "medialibrary_data_manager_utils.h"
31 #include "medialibrary_inotify.h"
32 
33 using namespace std;
34 namespace OHOS {
35 namespace Media {
36 static constexpr char MEDIA_LIBRARY[] = "MEDIALIBRARY";
37 
DfxReporter()38 DfxReporter::DfxReporter()
39 {
40 }
41 
~DfxReporter()42 DfxReporter::~DfxReporter()
43 {
44 }
45 
ReportTimeOutOperation(std::string & bundleName,int32_t type,int32_t object,int32_t time)46 void DfxReporter::ReportTimeOutOperation(std::string &bundleName, int32_t type, int32_t object, int32_t time)
47 {
48     int ret = HiSysEventWrite(
49         MEDIA_LIBRARY,
50         "MEDIALIB_TIMEOUT_ERROR",
51         HiviewDFX::HiSysEvent::EventType::FAULT,
52         "BUNDLE_NAME", bundleName,
53         "OPERATION_TYPE", type,
54         "OPERATION_OBJECT", object,
55         "TIME", time);
56     if (ret != 0) {
57         MEDIA_ERR_LOG("ReportTimeoutOperation error:%{public}d", ret);
58     }
59 }
60 
ReportHighMemoryImageThumbnail(std::string & path,std::string & suffix,int32_t width,int32_t height)61 int32_t DfxReporter::ReportHighMemoryImageThumbnail(std::string &path, std::string &suffix, int32_t width,
62     int32_t height)
63 {
64     if (suffix != "jpg" && suffix != "jpeg" && suffix != "jpe") {
65         MEDIA_WARN_LOG("image %{public}s is %{public}s, width: %{public}d, height: %{public}d", path.c_str(),
66             suffix.c_str(), width, height);
67         return OTHER_FORMAT_IMAGE;
68     } else if (width > IMAGE_MIN && height > IMAGE_MIN) {
69         MEDIA_WARN_LOG("image %{public}s is too large, width: %{public}d, height: %{public}d", path.c_str(), width,
70             height);
71         return BIG_IMAGE;
72     }
73     return COMMON_IMAGE;
74 }
75 
ReportHighMemoryVideoThumbnail(std::string & path,std::string & suffix,int32_t width,int32_t height)76 int32_t DfxReporter::ReportHighMemoryVideoThumbnail(std::string &path, std::string &suffix, int32_t width,
77     int32_t height)
78 {
79     if (width >= VIDEO_8K_MIN || height >= VIDEO_8K_MIN) {
80         MEDIA_WARN_LOG("video %{public}s is too large, width: %{public}d, height: %{public}d", path.c_str(), width,
81             height);
82         return BIG_VIDEO;
83     }
84     return COMMON_VIDEO;
85 }
86 
ReportThumbnailError()87 void DfxReporter::ReportThumbnailError()
88 {
89     int32_t errCode;
90     shared_ptr<NativePreferences::Preferences> prefs =
91         NativePreferences::PreferencesHelper::GetPreferences(THUMBNAIL_ERROR_XML, errCode);
92     if (!prefs) {
93         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
94         return;
95     }
96     map<string, NativePreferences::PreferencesValue> errorMap = prefs->GetAll();
97     for (auto &erroInfo : errorMap) {
98         string key = erroInfo.first;
99         string value = erroInfo.second;
100         vector<string> thumbnailInfo = DfxUtils::Split(key, SPLIT_CHAR);
101         if (thumbnailInfo.empty() || thumbnailInfo.size() < 3) { // 3 means length of key
102             continue;
103         }
104         // 0 means index of path
105         string path = thumbnailInfo[0];
106         // 1 means index of method
107         int32_t method = MediaLibraryDataManagerUtils::IsNumber(thumbnailInfo[1]) ? stoi(thumbnailInfo[1]) : 0;
108         // 2 means index of error code
109         int32_t errorCode = MediaLibraryDataManagerUtils::IsNumber(thumbnailInfo[2]) ? stoi(thumbnailInfo[2]) : 0;
110         int64_t time = MediaLibraryDataManagerUtils::IsNumber(value) ? stol(value) : 0;
111         int ret = HiSysEventWrite(
112             MEDIA_LIBRARY,
113             "MEDIALIB_THUMBNAIL_ERROR",
114             HiviewDFX::HiSysEvent::EventType::FAULT,
115             "PATH", path,
116             "METHOD", method,
117             "ERROR_CODE", errorCode,
118             "TIME", time);
119         if (ret != 0) {
120             MEDIA_ERR_LOG("ReportThumbnailError error:%{public}d", ret);
121         }
122     }
123     prefs->Clear();
124     prefs->FlushSync();
125 }
126 
ReportCommonBehavior()127 void DfxReporter::ReportCommonBehavior()
128 {
129     int32_t errCode;
130     shared_ptr<NativePreferences::Preferences> prefs =
131         NativePreferences::PreferencesHelper::GetPreferences(COMMON_BEHAVIOR_XML, errCode);
132     if (!prefs) {
133         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
134         return;
135     }
136     map<string, NativePreferences::PreferencesValue> errorMap = prefs->GetAll();
137     for (auto &erroInfo : errorMap) {
138         string bundleName = erroInfo.first;
139         int32_t times = static_cast<int32_t>(erroInfo.second);
140         int ret = HiSysEventWrite(
141             MEDIA_LIBRARY,
142             "MEDIALIB_COMMON_STATISTIC",
143             HiviewDFX::HiSysEvent::EventType::STATISTIC,
144             "BUNDLE_NAME", bundleName,
145             "TIMES", times);
146         if (ret != 0) {
147             MEDIA_ERR_LOG("ReportCommonBehavior error:%{public}d", ret);
148         }
149     }
150     prefs->Clear();
151     prefs->FlushSync();
152 }
153 
ReportDeleteStatistic()154 void DfxReporter::ReportDeleteStatistic()
155 {
156     int32_t errCode;
157     shared_ptr<NativePreferences::Preferences> prefs =
158         NativePreferences::PreferencesHelper::GetPreferences(DELETE_BEHAVIOR_XML, errCode);
159     if (!prefs) {
160         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
161         return;
162     }
163     map<string, NativePreferences::PreferencesValue> deleteMap = prefs->GetAll();
164     for (auto &info : deleteMap) {
165         string key = info.first;
166         vector<string> deleteInfo = DfxUtils::Split(key, SPLIT_CHAR);
167         if (deleteInfo.empty() || deleteInfo.size() < 2) { // 2 means length of key
168             continue;
169         }
170         // 0 means index of bundleName
171         string bundleName = deleteInfo[0];
172         // 1 means index of type
173         int32_t type = MediaLibraryDataManagerUtils::IsNumber(deleteInfo[1]) ? stoi(deleteInfo[1]) : 0;
174         int32_t times = static_cast<int32_t>(info.second);
175         int ret = HiSysEventWrite(
176             MEDIA_LIBRARY,
177             "MEDIALIB_DELETE_STATISTIC",
178             HiviewDFX::HiSysEvent::EventType::STATISTIC,
179             "BUNDLE_NAME", bundleName,
180             "TYPE", type,
181             "TIMES", times);
182         if (ret != 0) {
183             MEDIA_ERR_LOG("ReportDeleteBehavior error:%{public}d", ret);
184         }
185     }
186     prefs->Clear();
187     prefs->FlushSync();
188 }
189 
ReportDeleteBehavior(string bundleName,int32_t type,std::string path)190 void DfxReporter::ReportDeleteBehavior(string bundleName, int32_t type, std::string path)
191 {
192     if (bundleName == "" || path == "") {
193         return;
194     }
195     MEDIA_WARN_LOG("%{public}s do %{public}d on %{public}s", bundleName.c_str(), type, path.c_str());
196     int ret = HiSysEventWrite(
197         MEDIA_LIBRARY,
198         "MEDIALIB_DELETE_BEHAVIOR",
199         HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
200         "BUNDLE_NAME", bundleName,
201         "TYPE", type,
202         "PATH", path);
203     if (ret != 0) {
204         MEDIA_ERR_LOG("ReportDeleteBehavior error:%{public}d", ret);
205     }
206 }
207 
ReportThumbnailGeneration(const ThumbnailData::GenerateStats & stats)208 void DfxReporter::ReportThumbnailGeneration(const ThumbnailData::GenerateStats &stats)
209 {
210     int ret = HiSysEventWrite(
211         MEDIA_LIBRARY,
212         "MEDIALIB_THUMBNAIL_GENERATION",
213         HiviewDFX::HiSysEvent::EventType::STATISTIC,
214         "URI", stats.uri,
215         "SCENE", static_cast<int32_t>(stats.scene),
216         "OPEN_THUMB_COST", stats.openThumbCost,
217         "OPEN_LCD_COST", stats.openLcdCost,
218         "SOURCE_TYPE", static_cast<int32_t>(stats.sourceType),
219         "SOURCE_WIDTH", stats.sourceWidth,
220         "SOURCE_HEIGHT", stats.sourceHeight,
221         "TOTAL_COST", static_cast<int32_t>(stats.totalCost),
222         "ERROR_CODE", stats.errorCode);
223     if (ret != 0) {
224         MEDIA_ERR_LOG("ReportThumbnailGeneration error:%{public}d", ret);
225     }
226 }
227 
ReportPhotoInfo(const PhotoStatistics & stats)228 void DfxReporter::ReportPhotoInfo(const PhotoStatistics& stats)
229 {
230     int ret = HiSysEventWrite(
231         MEDIA_LIBRARY,
232         "MEDIALIB_PHOTO_INFO",
233         HiviewDFX::HiSysEvent::EventType::STATISTIC,
234         "LOCAL_IMAGE_COUNT", stats.localImageCount,
235         "LOCAL_VIDEO_COUNT", stats.localVideoCount,
236         "CLOUD_IMAGE_COUNT", stats.cloudImageCount,
237         "CLOUD_VIDEO_COUNT", stats.cloudVideoCount,
238         "SHARED_IMAGE_COUNT", stats.sharedImageCount,
239         "SHARED_VIDEO_COUNT", stats.sharedVideoCount);
240     if (ret != 0) {
241         MEDIA_ERR_LOG("ReportPhotoInfo error:%{public}d", ret);
242     }
243 }
244 
ReportAlbumInfo(const std::string & albumName,int32_t albumImageCount,int32_t albumVideoCount,bool isLocal)245 void DfxReporter::ReportAlbumInfo(const std::string &albumName, int32_t albumImageCount, int32_t albumVideoCount,
246     bool isLocal)
247 {
248     int ret = HiSysEventWrite(
249         MEDIA_LIBRARY,
250         "MEDIALIB_ALBUM_INFO",
251         HiviewDFX::HiSysEvent::EventType::STATISTIC,
252         "ALBUM_NAME", albumName,
253         "ALBUM_IMAGE_COUNT", albumImageCount,
254         "ALBUM_VIDEO_COUNT", albumVideoCount,
255         "IS_LOCAL", isLocal);
256     if (ret != 0) {
257         MEDIA_ERR_LOG("ReportAlbumInfo error:%{public}d", ret);
258     }
259 }
260 
ReportDirtyCloudPhoto(const std::string & data,int32_t dirty,int32_t cloudVersion)261 void DfxReporter::ReportDirtyCloudPhoto(const std::string &data, int32_t dirty, int32_t cloudVersion)
262 {
263     int ret = HiSysEventWrite(
264         MEDIA_LIBRARY,
265         "MEDIALIB_DIRTY_CLOUD_PHOTO",
266         HiviewDFX::HiSysEvent::EventType::STATISTIC,
267         "PATH", data,
268         "DIRTY", dirty,
269         "CLOUD_VERSION", cloudVersion);
270     if (ret != 0) {
271         MEDIA_ERR_LOG("ReportDirtyCloudPhoto error:%{public}d", ret);
272     }
273 }
274 
ReportCommonVersion(int32_t dbVersion)275 void DfxReporter::ReportCommonVersion(int32_t dbVersion)
276 {
277     MEDIA_INFO_LOG("dbVersion: %{public}d, thumbnailVersion: %{public}d", dbVersion, THUMBNAIL_VERSION);
278     int ret = HiSysEventWrite(
279         MEDIA_LIBRARY,
280         "MEDIALIB_COMMON_VERSION",
281         HiviewDFX::HiSysEvent::EventType::STATISTIC,
282         "DB_VERSION", dbVersion,
283         "THUMBNAIL_VERSION", THUMBNAIL_VERSION);
284     if (ret != 0) {
285         MEDIA_ERR_LOG("ReportCommonVersion error:%{public}d", ret);
286     }
287 }
288 
ReportAnalysisVersion(const std::string & analysisName,int32_t version)289 void DfxReporter::ReportAnalysisVersion(const std::string &analysisName, int32_t version)
290 {
291     int ret = HiSysEventWrite(
292         MEDIA_LIBRARY,
293         "MEDIALIB_ANALYSIS_VERSION",
294         HiviewDFX::HiSysEvent::EventType::STATISTIC,
295         "NAME", analysisName,
296         "VERSION", version);
297     if (ret != 0) {
298         MEDIA_ERR_LOG("ReportAnalysisVersion error:%{public}d", ret);
299     }
300 }
301 
ReportAdaptationToMovingPhoto()302 void DfxReporter::ReportAdaptationToMovingPhoto()
303 {
304     int32_t errCode;
305     shared_ptr<NativePreferences::Preferences> prefs =
306         NativePreferences::PreferencesHelper::GetPreferences(ADAPTATION_TO_MOVING_PHOTO_XML, errCode);
307     if (!prefs) {
308         MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
309         return;
310     }
311 
312     string date = DfxUtils::GetCurrentDate();
313     string unadaptedAppPackages = prefs->GetString(MOVING_PHOTO_KEY_UNADAPTED_PACKAGE);
314     string adaptedAppPackages = prefs->GetString(MOVING_PHOTO_KEY_ADAPTED_PACKAGE);
315     int32_t unadaptedAppNum = prefs->GetInt(MOVING_PHOTO_KEY_UNADAPTED_NUM);
316     int32_t adaptedAppNum = prefs->GetInt(MOVING_PHOTO_KEY_ADAPTED_NUM);
317 
318     int ret = HiSysEventWrite(
319         MEDIA_LIBRARY,
320         "MEDIALIB_MOVING_PHOTO_ADAPT",
321         HiviewDFX::HiSysEvent::EventType::STATISTIC,
322         "DATE", date,
323         "UNADAPTED_APP_NUM", unadaptedAppNum,
324         "UNADAPTED_APP_PACKAGE", unadaptedAppPackages,
325         "ADAPTED_APP_NUM", adaptedAppNum,
326         "ADAPTED_APP_PACKAGE", adaptedAppPackages);
327     if (ret != 0) {
328         MEDIA_ERR_LOG("Report adaptation to moving photo error:%{public}d", ret);
329     }
330 
331     prefs->Clear();
332     prefs->FlushSync();
333 }
334 
ReportStartResult(int32_t scene,int32_t error,int32_t start)335 void DfxReporter::ReportStartResult(int32_t scene, int32_t error, int32_t start)
336 {
337     int32_t cost = static_cast<int32_t>(MediaFileUtils::UTCTimeMilliSeconds() - start);
338     MEDIA_ERR_LOG("SCENE:%{public}d, ERROR:%{public}d, TIME:%{public}d", scene, error, cost);
339     int ret = HiSysEventWrite(
340         MEDIA_LIBRARY,
341         "MEDIALIB_START_RESULT",
342         HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
343         "SCENE", scene,
344         "ERROR", error,
345         "TIME", cost);
346     if (ret != 0) {
347         MEDIA_ERR_LOG("Report startResult error:%{public}d", ret);
348     }
349 }
350 
SecondsToTime(const int64_t & seconds)351 std::string SecondsToTime(const int64_t& seconds)
352 {
353     int32_t remain_seconds = seconds;
354     int32_t hour = seconds / ONE_HOUR;
355     remain_seconds = seconds - ONE_HOUR * hour;
356     int32_t minute = remain_seconds / ONE_MINUTE;
357     remain_seconds = remain_seconds - minute * ONE_MINUTE;
358     return std::to_string(hour) + "_h_" + std::to_string(minute) + "_m_" + std::to_string(remain_seconds) + "_s";
359 }
360 
ReportCloudSyncThumbGenerationStatus(const int32_t & downloadedThumb,const int32_t & generatedThumb,const int32_t & totalDownload)361 int32_t DfxReporter::ReportCloudSyncThumbGenerationStatus(const int32_t& downloadedThumb,
362     const int32_t& generatedThumb, const int32_t& totalDownload)
363 {
364     if (totalDownload == 0) {
365         return 0;
366     }
367     int32_t errCode;
368     shared_ptr<NativePreferences::Preferences> prefs =
369         NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
370     if (!prefs) {
371         MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
372         return 0;
373     }
374     int64_t start = prefs->GetLong(CLOUD_SYNC_START_TIME, 0);
375     int64_t now = MediaFileUtils::UTCTimeSeconds();
376     int64_t cost = now - start;
377     time_t startTime = start + ONE_HOUR * 8;
378     std::string astcStartTime = asctime(gmtime(&startTime));
379     float total = static_cast<float>(totalDownload);
380     int ret = HiSysEventWrite(
381         MEDIA_LIBRARY,
382         "CLOUD_THUMB_GENERATE_STATISTIC",
383         HiviewDFX::HiSysEvent::EventType::STATISTIC,
384         "CLOUD_DOWN_START", astcStartTime,
385         "DOWNLOADED_THUMB_NUM", downloadedThumb,
386         "DOWNLOADED_THUMB_RATIO", downloadedThumb / total,
387         "GENERATED_THUMB_NUM", generatedThumb,
388         "GENERATED_THUMB_RATIO", generatedThumb / total,
389         "CLOUD_DOWN_TOTAL_DURATION", SecondsToTime(cost));
390     if (ret != 0) {
391         MEDIA_ERR_LOG("Report CloudSyncThumbGenerationStatus error:%{public}d", ret);
392     }
393     return ret;
394 }
395 
GetWatchListInfo()396 static string GetWatchListInfo()
397 {
398     auto watch = MediaLibraryInotify::GetInstance();
399     if (watch == nullptr) {
400         MEDIA_ERR_LOG("MediaLibraryInotify GetInstance fail");
401         return "";
402     }
403     return watch->BuildDfxInfo();
404 }
405 
ReportPhotoRecordInfo()406 void DfxReporter::ReportPhotoRecordInfo()
407 {
408     PhotoRecordInfo photoRecordInfo;
409     int32_t result = DfxDatabaseUtils::QueryPhotoRecordInfo(photoRecordInfo);
410     if (result != 0) {
411         MEDIA_ERR_LOG("QueryPhotoRecordInfo error:%{public}d", result);
412         return;
413     }
414     int32_t imageCount = photoRecordInfo.imageCount;
415     int32_t videoCount = photoRecordInfo.videoCount;
416     int32_t abnormalSizeCount = photoRecordInfo.abnormalSizeCount;
417     int32_t abnormalWidthOrHeightCount = photoRecordInfo.abnormalWidthOrHeightCount;
418     int32_t abnormalVideoDurationCount = photoRecordInfo.abnormalVideoDurationCount;
419     int32_t toBeUpdatedRecordCount = photoRecordInfo.toBeUpdatedRecordCount;
420     int64_t dbFileSize = photoRecordInfo.dbFileSize;
421     int32_t duplicateLpathCount = photoRecordInfo.duplicateLpathCount;
422     int32_t abnormalLpathCount = photoRecordInfo.abnormalLpathCount;
423     int ret = HiSysEventWrite(
424         MEDIA_LIBRARY,
425         "MEDIALIB_DATABASE_INFO",
426         HiviewDFX::HiSysEvent::EventType::STATISTIC,
427         "DB_FILE_SIZE", dbFileSize,
428         "REPLICA_DB_FILE_SIZE", photoRecordInfo.slaveDbFileSize,
429         "IMAGE_COUNT", imageCount,
430         "VIDEO_COUNT", videoCount,
431         "ABNORMAL_SIZE_COUNT", abnormalSizeCount,
432         "ABNORMAL_WIDTH_OR_HEIGHT_COUNT", abnormalWidthOrHeightCount,
433         "ABNORMAL_VIDEO_DURATION_COUNT", abnormalVideoDurationCount,
434         "ABNORMAL_COUNT_TO_UPDATE", toBeUpdatedRecordCount,
435         "DUPLICATE_LPATH_COUNT", duplicateLpathCount,
436         "ABNORMAL_LPATH_COUNT", abnormalLpathCount,
437         "WATCH_LIST_INFO", GetWatchListInfo());
438     if (ret != 0) {
439         MEDIA_ERR_LOG("ReportPhotoRecordInfo error:%{public}d", ret);
440     }
441 }
442 
ReportMedialibraryAPI(const string & callerPackage,const string & saveUri)443 int32_t DfxReporter::ReportMedialibraryAPI(const string& callerPackage, const string& saveUri)
444 {
445     string currentDate = DfxUtils::GetCurrentDate();
446     int ret = HiSysEventWrite(
447         MEDIA_LIBRARY,
448         "MEDIALIB_DEPRECATED_API_USAGE",
449         HiviewDFX::HiSysEvent::EventType::STATISTIC,
450         "DATE", currentDate,
451         "CALLER_APP_PACKAGE", callerPackage,
452         "SAVE_URI", saveUri,
453         "READ_URI", "");
454     if (ret != 0) {
455         MEDIA_ERR_LOG("ReportMedialibraryAPI failed, ret: %{public}d", ret);
456         return E_FAIL;
457     }
458     return E_SUCCESS;
459 }
460 
ReportAlbumFusion(const AlbumFusionDfxDataPoint & reportData)461 int32_t DfxReporter::ReportAlbumFusion(const AlbumFusionDfxDataPoint& reportData)
462 {
463     int ret = HiSysEventWrite(
464         MEDIA_LIBRARY,
465         "MEDIALIB_ALBUM_FUSION_SINGLE",
466         HiviewDFX::HiSysEvent::EventType::STATISTIC,
467         "ALBUM_FUSION_TAG", reportData.albumFusionTag,
468         "REPORT_TIME_STAMP", reportData.reportTimeStamp,
469         "ALBUM_FUSION_STATE", reportData.albumFusionState,
470         "IMAGE_ASSET_COUNT", reportData.imageAssetCount,
471         "VIDEO_ASSET_COUNT", reportData.videoAssetCount,
472         "NUMBER_OF_SOURCE_ALBUM", reportData.numberOfSourceAlbum,
473         "NUMBER_OF_USER_ALBUM", reportData.numberOfUserAlbum,
474         "TOTAL_ASSETS_IN_SOURCE_ALBUMS", reportData.totalAssetsInSourceAlbums,
475         "TOTAL_ASSETS_IN_USER_ALBUMS", reportData.totalAssetsInUserAlbums,
476         "ALBUM_DETAILS", reportData.albumDetails,
477         "HIDDEN_ASSET_COUNT", reportData.hiddenAssetInfo);
478     if (ret != 0) {
479         MEDIA_ERR_LOG("ALBUM FUSION report data failed, ret: %{public}d", ret);
480         return E_FAIL;
481     }
482     return E_SUCCESS;
483 }
484 } // namespace Media
485 } // namespace OHOS