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 "DfxManager"
16
17 #include "dfx_manager.h"
18
19 #include "dfx_cloud_manager.h"
20 #include "dfx_utils.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23 #include "userfile_manager_types.h"
24 #include "medialibrary_bundle_manager.h"
25 #ifdef META_RECOVERY_SUPPORT
26 #include "medialibrary_meta_recovery.h"
27 #endif
28 #include "dfx_database_utils.h"
29 #include "vision_aesthetics_score_column.h"
30 #include "parameters.h"
31 #include "preferences.h"
32 #include "preferences_helper.h"
33 #include "hi_audit.h"
34 #include "medialibrary_errno.h"
35
36 using namespace std;
37
38 namespace OHOS {
39 namespace Media {
40
41 shared_ptr<DfxManager> DfxManager::dfxManagerInstance_{nullptr};
42 mutex DfxManager::instanceLock_;
43
44 struct QueryParams {
45 MediaType mediaType;
46 PhotoPositionType positionType;
47 };
48
GetInstance()49 shared_ptr<DfxManager> DfxManager::GetInstance()
50 {
51 lock_guard<mutex> lockGuard(instanceLock_);
52 if (dfxManagerInstance_ == nullptr) {
53 dfxManagerInstance_ = make_shared<DfxManager>();
54 if (dfxManagerInstance_ != nullptr) {
55 dfxManagerInstance_->Init();
56 }
57 }
58 return dfxManagerInstance_;
59 }
60
DfxManager()61 DfxManager::DfxManager() : isInitSuccess_(false)
62 {
63 }
64
~DfxManager()65 DfxManager::~DfxManager()
66 {
67 }
68
Init()69 void DfxManager::Init()
70 {
71 MEDIA_INFO_LOG("Init DfxManager");
72 dfxCollector_ = make_shared<DfxCollector>();
73 dfxAnalyzer_ = make_shared<DfxAnalyzer>();
74 dfxReporter_ = make_shared<DfxReporter>();
75 dfxWorker_ = DfxWorker::GetInstance();
76 dfxWorker_->Init();
77 isInitSuccess_ = true;
78 }
79
HandleTimeOutOperation(std::string & bundleName,int32_t type,int32_t object,int32_t time)80 void DfxManager::HandleTimeOutOperation(std::string &bundleName, int32_t type, int32_t object, int32_t time)
81 {
82 if (!isInitSuccess_) {
83 MEDIA_WARN_LOG("DfxManager not init");
84 return;
85 }
86 dfxReporter_->ReportTimeOutOperation(bundleName, type, object, time);
87 }
88
HandleHighMemoryThumbnail(std::string & path,int32_t mediaType,int32_t width,int32_t height)89 int32_t DfxManager::HandleHighMemoryThumbnail(std::string &path, int32_t mediaType, int32_t width,
90 int32_t height)
91 {
92 if (!isInitSuccess_) {
93 MEDIA_WARN_LOG("DfxManager not init");
94 return NOT_INIT;
95 }
96 string suffix = MediaFileUtils::GetExtensionFromPath(path);
97 if (mediaType == MEDIA_TYPE_IMAGE) {
98 return dfxReporter_->ReportHighMemoryImageThumbnail(path, suffix, width, height);
99 } else {
100 return dfxReporter_->ReportHighMemoryVideoThumbnail(path, suffix, width, height);
101 }
102 }
103
HandleThumbnailError(const std::string & path,int32_t method,int32_t errorCode)104 void DfxManager::HandleThumbnailError(const std::string &path, int32_t method, int32_t errorCode)
105 {
106 string safePath = DfxUtils::GetSafePath(path);
107 MEDIA_ERR_LOG("Failed to %{public}d, path: %{public}s, err: %{public}d", method, safePath.c_str(), errorCode);
108 if (!isInitSuccess_) {
109 MEDIA_WARN_LOG("DfxManager not init");
110 return;
111 }
112 dfxCollector_->CollectThumbnailError(safePath, method, errorCode);
113 }
114
HandleThumbnailGeneration(const ThumbnailData::GenerateStats & stats)115 void DfxManager::HandleThumbnailGeneration(const ThumbnailData::GenerateStats &stats)
116 {
117 if (!isInitSuccess_) {
118 MEDIA_WARN_LOG("DfxManager not init");
119 return;
120 }
121 dfxReporter_->ReportThumbnailGeneration(stats);
122 }
123
HandleCommonBehavior(string bundleName,int32_t type)124 void DfxManager::HandleCommonBehavior(string bundleName, int32_t type)
125 {
126 if (!isInitSuccess_) {
127 MEDIA_WARN_LOG("DfxManager not init");
128 return;
129 }
130 dfxCollector_->AddCommonBahavior(bundleName, type);
131 }
132
LogDelete(DfxData * data)133 static void LogDelete(DfxData *data)
134 {
135 if (data == nullptr) {
136 return;
137 }
138 auto *taskData = static_cast<DeleteBehaviorTask *>(data);
139 string id = taskData->id_;
140 int32_t type = taskData->type_;
141 int32_t size = taskData->size_;
142 std::shared_ptr<DfxReporter> dfxReporter = taskData->dfxReporter_;
143 MEDIA_INFO_LOG("id: %{public}s, type: %{public}d, size: %{public}d", id.c_str(), type, size);
144
145 std::vector<std::string> uris = taskData->uris_;
146 if (!uris.empty()) {
147 for (auto& uri: uris) {
148 string::size_type pos = uri.find_last_of('/');
149 if (pos == string::npos) {
150 continue;
151 }
152 string halfUri = uri.substr(0, pos);
153 string::size_type pathPos = halfUri.find_last_of('/');
154 if (pathPos == string::npos) {
155 continue;
156 }
157 AuditLog auditLog = { true, "USER BEHAVIOR", "DELETE", "io", 1, "running", "ok",
158 id, type, size, (halfUri.substr(pathPos + 1)).c_str()};
159 HiAudit::GetInstance().Write(auditLog);
160 dfxReporter->ReportDeleteBehavior(id, type, halfUri.substr(pathPos + 1));
161 }
162 }
163 }
164
HandleNoPermmison(int32_t type,int32_t object,int32_t error)165 void DfxManager::HandleNoPermmison(int32_t type, int32_t object, int32_t error)
166 {
167 MEDIA_INFO_LOG("permission deny: {%{public}d, %{public}d, %{public}d}", type, object, error);
168 }
169
HandleDeleteBehavior(int32_t type,int32_t size,std::vector<std::string> & uris,string bundleName)170 void DfxManager::HandleDeleteBehavior(int32_t type, int32_t size, std::vector<std::string> &uris, string bundleName)
171 {
172 if (bundleName == "") {
173 bundleName = MediaLibraryBundleManager::GetInstance()->GetClientBundleName();
174 }
175 dfxCollector_->CollectDeleteBehavior(bundleName, type, size);
176 if (dfxWorker_ == nullptr) {
177 MEDIA_ERR_LOG("Can not get dfxWork_");
178 return;
179 }
180 string id = bundleName == "" ? to_string(IPCSkeleton::GetCallingUid()) : bundleName;
181 auto *taskData = new (nothrow) DeleteBehaviorTask(id, type, size, uris, dfxReporter_);
182 if (taskData == nullptr) {
183 MEDIA_ERR_LOG("Failed to new taskData");
184 return;
185 }
186 auto deleteBehaviorTask = make_shared<DfxTask>(LogDelete, taskData);
187 if (deleteBehaviorTask == nullptr) {
188 MEDIA_ERR_LOG("Failed to create async task for deleteBehaviorTask.");
189 return;
190 }
191 dfxWorker_->AddTask(deleteBehaviorTask);
192 }
193
HandlePhotoInfo(std::shared_ptr<DfxReporter> & dfxReporter)194 static void HandlePhotoInfo(std::shared_ptr<DfxReporter>& dfxReporter)
195 {
196 const std::vector<QueryParams> queryParamsList = {
197 {MediaType::MEDIA_TYPE_IMAGE, PhotoPositionType::LOCAL},
198 {MediaType::MEDIA_TYPE_VIDEO, PhotoPositionType::LOCAL},
199 {MediaType::MEDIA_TYPE_IMAGE, PhotoPositionType::CLOUD},
200 {MediaType::MEDIA_TYPE_VIDEO, PhotoPositionType::CLOUD},
201 {MediaType::MEDIA_TYPE_IMAGE, PhotoPositionType::LOCAL_AND_CLOUD},
202 {MediaType::MEDIA_TYPE_VIDEO, PhotoPositionType::LOCAL_AND_CLOUD}
203 };
204
205 PhotoStatistics stats = {};
206 int32_t* countPtrs[] = {
207 &stats.localImageCount,
208 &stats.localVideoCount,
209 &stats.cloudImageCount,
210 &stats.cloudVideoCount,
211 &stats.sharedImageCount,
212 &stats.sharedVideoCount
213 };
214
215 for (size_t i = 0; i < queryParamsList.size(); i++) {
216 const auto& params = queryParamsList[i];
217 *countPtrs[i] = DfxDatabaseUtils::QueryFromPhotos(params.mediaType, static_cast<int32_t>(params.positionType));
218 }
219
220 MEDIA_INFO_LOG("localImageCount: %{public}d, localVideoCount: %{public}d, "
221 "cloudImageCount: %{public}d, cloudVideoCount: %{public}d, "
222 "sharedImageCount: %{public}d, sharedVideoCount: %{public}d",
223 stats.localImageCount, stats.localVideoCount,
224 stats.cloudImageCount, stats.cloudVideoCount,
225 stats.sharedImageCount, stats.sharedVideoCount);
226
227 dfxReporter->ReportPhotoInfo(stats);
228 }
229
HandleAlbumInfoBySubtype(std::shared_ptr<DfxReporter> & dfxReporter,int32_t albumSubType)230 static void HandleAlbumInfoBySubtype(std::shared_ptr<DfxReporter> &dfxReporter, int32_t albumSubType)
231 {
232 AlbumInfo albumInfo = DfxDatabaseUtils::QueryAlbumInfoBySubtype(albumSubType);
233 string albumName = ALBUM_MAP.at(albumSubType);
234 MEDIA_INFO_LOG("album %{public}s: {count:%{public}d, imageCount:%{public}d, videoCount:%{public}d, \
235 isLocal:%{public}d}", albumName.c_str(), albumInfo.count, albumInfo.imageCount, albumInfo.videoCount,
236 albumInfo.isLocal);
237 dfxReporter->ReportAlbumInfo(albumName.c_str(), albumInfo.imageCount, albumInfo.videoCount, albumInfo.isLocal);
238 }
239
HandleAlbumInfo(std::shared_ptr<DfxReporter> & dfxReporter)240 static void HandleAlbumInfo(std::shared_ptr<DfxReporter> &dfxReporter)
241 {
242 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::IMAGE));
243 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::VIDEO));
244 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::FAVORITE));
245 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::HIDDEN));
246 HandleAlbumInfoBySubtype(dfxReporter, static_cast<int32_t>(PhotoAlbumSubType::TRASH));
247 }
248
HandleDirtyCloudPhoto(std::shared_ptr<DfxReporter> & dfxReporter)249 static void HandleDirtyCloudPhoto(std::shared_ptr<DfxReporter> &dfxReporter)
250 {
251 vector<PhotoInfo> photoInfoList = DfxDatabaseUtils::QueryDirtyCloudPhoto();
252 if (photoInfoList.empty()) {
253 return;
254 }
255 for (auto& photoInfo: photoInfoList) {
256 dfxReporter->ReportDirtyCloudPhoto(photoInfo.data, photoInfo.dirty, photoInfo.cloudVersion);
257 }
258 }
259
HandleLocalVersion(std::shared_ptr<DfxReporter> & dfxReporter)260 static void HandleLocalVersion(std::shared_ptr<DfxReporter> &dfxReporter)
261 {
262 int32_t dbVersion = DfxDatabaseUtils::QueryDbVersion();
263 dfxReporter->ReportCommonVersion(dbVersion);
264 int32_t aestheticsVersion = DfxDatabaseUtils::QueryAnalysisVersion("tab_analysis_aesthetics_score",
265 AESTHETICS_VERSION);
266 dfxReporter->ReportAnalysisVersion("tab_analysis_aesthetics_score", aestheticsVersion);
267 }
268
HandleAstcInfo(std::shared_ptr<DfxReporter> & dfxReporter)269 void HandleAstcInfo(std::shared_ptr<DfxReporter>& dfxReporter)
270 {
271 LcdAndAstcCount count = {};
272 count.localAstcCount = DfxDatabaseUtils::QueryASTCThumb(true);
273 count.cloudAstcCount = DfxDatabaseUtils::QueryASTCThumb(false);
274 count.localLcdCount = DfxDatabaseUtils::QueryLCDThumb(true);
275 count.cloudLcdCount = DfxDatabaseUtils::QueryLCDThumb(false);
276
277 MEDIA_INFO_LOG("localLcdCount: %{public}d, localAstcCount: %{public}d, "
278 "cloudLcdCount: %{public}d, cloudAstcCount: %{public}d",
279 count.localLcdCount, count.localAstcCount,
280 count.cloudLcdCount, count.cloudAstcCount);
281
282 dfxReporter->ReportAstcInfo(count);
283 }
284
HandleStatistic(DfxData * data)285 static void HandleStatistic(DfxData *data)
286 {
287 if (data == nullptr) {
288 return;
289 }
290 auto *taskData = static_cast<StatisticData *>(data);
291 std::shared_ptr<DfxReporter> dfxReporter = taskData->dfxReporter_;
292 HandlePhotoInfo(dfxReporter);
293 HandleAlbumInfo(dfxReporter);
294 HandleDirtyCloudPhoto(dfxReporter);
295 HandleLocalVersion(dfxReporter);
296 HandleAstcInfo(dfxReporter);
297 #ifdef META_RECOVERY_SUPPORT
298 MediaLibraryMetaRecovery::GetInstance().RecoveryStatistic();
299 #endif
300 }
301
HandleHalfDayMissions()302 void DfxManager::HandleHalfDayMissions()
303 {
304 if (!isInitSuccess_) {
305 MEDIA_WARN_LOG("DfxManager not init");
306 return;
307 }
308 int32_t errCode;
309 shared_ptr<NativePreferences::Preferences> prefs =
310 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
311 if (!prefs) {
312 MEDIA_ERR_LOG("get preferences error: %{public}d", errCode);
313 return;
314 }
315 int64_t lastReportTime = prefs->GetLong(LAST_HALF_DAY_REPORT_TIME, 0);
316 if (MediaFileUtils::UTCTimeSeconds() - lastReportTime > HALF_DAY && dfxWorker_ != nullptr) {
317 MEDIA_INFO_LOG("start handle statistic behavior");
318 auto *taskData = new (nothrow) StatisticData(dfxReporter_);
319 if (taskData == nullptr) {
320 MEDIA_ERR_LOG("Failed to alloc async data for Handle Half Day Missions!");
321 return;
322 }
323 auto statisticTask = make_shared<DfxTask>(HandleStatistic, taskData);
324 if (statisticTask == nullptr) {
325 MEDIA_ERR_LOG("Failed to create statistic task.");
326 return;
327 }
328 dfxWorker_->AddTask(statisticTask);
329 int64_t time = MediaFileUtils::UTCTimeSeconds();
330 prefs->PutLong(LAST_HALF_DAY_REPORT_TIME, time);
331 prefs->FlushSync();
332 }
333 }
334
IsDirectoryExist(const string & dirName)335 void DfxManager::IsDirectoryExist(const string& dirName)
336 {
337 struct stat statInfo {};
338 if (stat(dirName.c_str(), &statInfo) == E_SUCCESS) {
339 if (statInfo.st_mode & S_IFDIR) {
340 return;
341 }
342 MEDIA_ERR_LOG("Not Is DIR, errno is %{public}d", errno);
343 return;
344 }
345 MEDIA_ERR_LOG("Directory Not Exist, errno is %{public}d", errno);
346 return;
347 }
348
CheckStatus()349 void DfxManager::CheckStatus()
350 {
351 const std::string CLOUD_FILE_PATH = "/storage/cloud/files";
352 IsDirectoryExist(CLOUD_FILE_PATH);
353 }
354
HandleFiveMinuteTask()355 void DfxManager::HandleFiveMinuteTask()
356 {
357 if (!isInitSuccess_) {
358 MEDIA_WARN_LOG("DfxManager not init");
359 return;
360 }
361 std::unordered_map<string, CommonBehavior> commonBehavior = dfxCollector_->GetCommonBehavior();
362 dfxAnalyzer_->FlushCommonBehavior(commonBehavior);
363 HandleDeleteBehaviors();
364 std::unordered_map<std::string, ThumbnailErrorInfo> result = dfxCollector_->GetThumbnailError();
365 dfxAnalyzer_->FlushThumbnail(result);
366 AdaptationToMovingPhotoInfo adaptationInfo = dfxCollector_->GetAdaptationToMovingPhotoInfo();
367 dfxAnalyzer_->FlushAdaptationToMovingPhoto(adaptationInfo);
368 CheckStatus();
369 }
370
HandleDeleteBehaviors()371 void DfxManager::HandleDeleteBehaviors()
372 {
373 std::unordered_map<string, int32_t> deleteAssetToTrash =
374 dfxCollector_->GetDeleteBehavior(DfxType::TRASH_PHOTO);
375 dfxAnalyzer_->FlushDeleteBehavior(deleteAssetToTrash, DfxType::TRASH_PHOTO);
376 std::unordered_map<string, int32_t> deleteAssetFromDisk =
377 dfxCollector_->GetDeleteBehavior(DfxType::ALBUM_DELETE_ASSETS);
378 dfxAnalyzer_->FlushDeleteBehavior(deleteAssetToTrash, DfxType::ALBUM_DELETE_ASSETS);
379 std::unordered_map<string, int32_t> removeAssets =
380 dfxCollector_->GetDeleteBehavior(DfxType::ALBUM_REMOVE_PHOTOS);
381 dfxAnalyzer_->FlushDeleteBehavior(removeAssets, DfxType::ALBUM_REMOVE_PHOTOS);
382 }
383
HandleMiddleReport()384 int64_t DfxManager::HandleMiddleReport()
385 {
386 if (!isInitSuccess_) {
387 MEDIA_WARN_LOG("DfxManager not init");
388 return MediaFileUtils::UTCTimeSeconds();
389 }
390 dfxReporter_->ReportCommonBehavior();
391 dfxReporter_->ReportDeleteStatistic();
392 return MediaFileUtils::UTCTimeSeconds();
393 }
394
HandleOneDayReport()395 int64_t DfxManager::HandleOneDayReport()
396 {
397 if (!isInitSuccess_) {
398 MEDIA_WARN_LOG("DfxManager not init");
399 return MediaFileUtils::UTCTimeSeconds();
400 }
401 dfxReporter_->ReportThumbnailError();
402 dfxReporter_->ReportAdaptationToMovingPhoto();
403 dfxReporter_->ReportPhotoRecordInfo();
404 return MediaFileUtils::UTCTimeSeconds();
405 }
406
HandleAdaptationToMovingPhoto(const string & appName,bool adapted)407 void DfxManager::HandleAdaptationToMovingPhoto(const string &appName, bool adapted)
408 {
409 if (!isInitSuccess_) {
410 MEDIA_WARN_LOG("DfxManager not init");
411 return;
412 }
413 dfxCollector_->CollectAdaptationToMovingPhotoInfo(appName, adapted);
414 }
415
IsReported()416 bool IsReported()
417 {
418 int32_t errCode;
419 shared_ptr<NativePreferences::Preferences> prefs =
420 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
421 if (!prefs) {
422 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
423 return false;
424 }
425 return prefs->GetBool(IS_REPORTED, false);
426 }
427
SetReported(bool isReported)428 void SetReported(bool isReported)
429 {
430 int32_t errCode;
431 shared_ptr<NativePreferences::Preferences> prefs =
432 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
433 if (!prefs) {
434 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
435 return;
436 }
437 prefs->PutBool(IS_REPORTED, isReported);
438 }
439
~CloudSyncDfxManager()440 CloudSyncDfxManager::~CloudSyncDfxManager()
441 {
442 ShutDownTimer();
443 }
444
GetInstance()445 CloudSyncDfxManager& CloudSyncDfxManager::GetInstance()
446 {
447 static CloudSyncDfxManager cloudSyncDfxManager;
448 return cloudSyncDfxManager;
449 }
450
GetCloudSyncStatus()451 CloudSyncStatus GetCloudSyncStatus()
452 {
453 return static_cast<CloudSyncStatus>(system::GetParameter(CLOUDSYNC_STATUS_KEY, "0").at(0) - '0');
454 }
455
CloudSyncDfxManager()456 CloudSyncDfxManager::CloudSyncDfxManager()
457 {
458 InitSyncState();
459 uint16_t newState = static_cast<uint16_t>(syncState_);
460 stateProcessFuncs_[newState].Process(*this);
461 }
462
InitSyncState()463 void CloudSyncDfxManager::InitSyncState()
464 {
465 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
466 switch (cloudSyncStatus) {
467 case CloudSyncStatus::BEGIN:
468 case CloudSyncStatus::SYNC_SWITCHED_OFF:
469 syncState_ = SyncState::INIT_STATE;
470 return;
471 case CloudSyncStatus::FIRST_FIVE_HUNDRED:
472 case CloudSyncStatus::TOTAL_DOWNLOAD:
473 syncState_ = SyncState::START_STATE;
474 return;
475 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
476 syncState_ = SyncState::END_STATE;
477 return;
478 default:
479 return;
480 }
481 }
482
StateSwitch(CloudSyncDfxManager & manager)483 bool InitState::StateSwitch(CloudSyncDfxManager& manager)
484 {
485 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
486 switch (cloudSyncStatus) {
487 case CloudSyncStatus::FIRST_FIVE_HUNDRED:
488 case CloudSyncStatus::TOTAL_DOWNLOAD:
489 manager.syncState_ = SyncState::START_STATE;
490 return true;
491 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
492 manager.syncState_ = SyncState::END_STATE;
493 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
494 return true;
495 default:
496 return false;
497 }
498 }
499
Process(CloudSyncDfxManager & manager)500 void InitState::Process(CloudSyncDfxManager& manager)
501 {
502 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
503 manager.ResetStartTime();
504 manager.ShutDownTimer();
505 SetReported(false);
506 }
507
RunDfx()508 void CloudSyncDfxManager::RunDfx()
509 {
510 uint16_t oldState = static_cast<uint16_t>(syncState_);
511 if (stateProcessFuncs_[oldState].StateSwitch(*this)) {
512 uint16_t newState = static_cast<uint16_t>(syncState_);
513 stateProcessFuncs_[newState].Process(*this);
514 }
515 }
516
StateSwitch(CloudSyncDfxManager & manager)517 bool StartState::StateSwitch(CloudSyncDfxManager& manager)
518 {
519 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
520 switch (cloudSyncStatus) {
521 case CloudSyncStatus::BEGIN:
522 case CloudSyncStatus::SYNC_SWITCHED_OFF:
523 manager.syncState_ = SyncState::INIT_STATE;
524 return true;
525 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
526 manager.syncState_ = SyncState::END_STATE;
527 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
528 return true;
529 default:
530 return false;
531 }
532 }
533
Process(CloudSyncDfxManager & manager)534 void StartState::Process(CloudSyncDfxManager& manager)
535 {
536 MEDIA_INFO_LOG("CloudSyncDfxManager new status:%{public}hu", manager.syncState_);
537 manager.SetStartTime();
538 manager.StartTimer();
539 SetReported(false);
540 }
541
StateSwitch(CloudSyncDfxManager & manager)542 bool EndState::StateSwitch(CloudSyncDfxManager& manager)
543 {
544 CloudSyncStatus cloudSyncStatus = GetCloudSyncStatus();
545 switch (cloudSyncStatus) {
546 case CloudSyncStatus::BEGIN:
547 case CloudSyncStatus::SYNC_SWITCHED_OFF:
548 manager.syncState_ = SyncState::INIT_STATE;
549 return true;
550 case CloudSyncStatus::TOTAL_DOWNLOAD_FINISH:
551 return true;
552 default:
553 return false;
554 }
555 }
556
Process(CloudSyncDfxManager & manager)557 void EndState::Process(CloudSyncDfxManager& manager)
558 {
559 std::unique_lock<std::mutex> lock(manager.endStateMutex_);
560 if (IsReported()) {
561 manager.ShutDownTimer();
562 return;
563 }
564 manager.SetStartTime();
565 manager.StartTimer();
566 int32_t downloadedThumb = 0;
567 int32_t generatedThumb = 0;
568 if (!DfxDatabaseUtils::QueryDownloadedAndGeneratedThumb(downloadedThumb, generatedThumb)) {
569 if (downloadedThumb != generatedThumb) {
570 return;
571 }
572 int32_t totalDownload = 0;
573 DfxDatabaseUtils::QueryTotalCloudThumb(totalDownload);
574 if (totalDownload != downloadedThumb) {
575 return;
576 }
577 SetReported(true);
578 manager.ShutDownTimer();
579 DfxReporter::ReportCloudSyncThumbGenerationStatus(downloadedThumb, generatedThumb, totalDownload);
580 }
581 }
582
StartTimer()583 void CloudSyncDfxManager::StartTimer()
584 {
585 std::unique_lock<std::mutex> lock(timerMutex_);
586 if (timerId_ != 0) {
587 return;
588 }
589 if (timer_.Setup() != ERR_OK) {
590 MEDIA_INFO_LOG("CloudSync Dfx Set Timer Failed");
591 return;
592 }
593 Utils::Timer::TimerCallback timerCallback = [this]() {
594 (void)this;
595 if (IsReported()) {
596 return;
597 }
598 int32_t generatedThumb = 0;
599 int32_t downloadedThumb = 0;
600 if (!DfxDatabaseUtils::QueryDownloadedAndGeneratedThumb(downloadedThumb, generatedThumb)) {
601 int32_t totalDownload = 0;
602 DfxDatabaseUtils::QueryTotalCloudThumb(totalDownload);
603 if (downloadedThumb == generatedThumb && totalDownload == generatedThumb) {
604 MEDIA_INFO_LOG("CloudSyncDfxManager Dfx report Thumb generation status, "
605 "download: %{public}d, generate: %{public}d", downloadedThumb, generatedThumb);
606 SetReported(true);
607 }
608 DfxReporter::ReportCloudSyncThumbGenerationStatus(downloadedThumb, generatedThumb, totalDownload);
609 }
610 };
611 timerId_ = timer_.Register(timerCallback, SIX_HOUR * TO_MILLION, false);
612 MEDIA_INFO_LOG("CloudSyncDfxManager StartTimer id:%{public}d", timerId_);
613 }
614
ShutDownTimer()615 void CloudSyncDfxManager::ShutDownTimer()
616 {
617 std::unique_lock<std::mutex> lock(timerMutex_);
618 if (timerId_ == 0) {
619 return;
620 }
621 MEDIA_INFO_LOG("CloudSyncDfxManager ShutDownTimer id:%{public}d", timerId_);
622 timer_.Unregister(timerId_);
623 timerId_ = 0;
624 timer_.Shutdown();
625 }
626
ResetStartTime()627 void CloudSyncDfxManager::ResetStartTime()
628 {
629 int32_t errCode;
630 shared_ptr<NativePreferences::Preferences> prefs =
631 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
632 if (!prefs) {
633 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
634 return;
635 }
636 prefs->PutLong(CLOUD_SYNC_START_TIME, 0);
637 prefs->FlushSync();
638 }
639
SetStartTime()640 void CloudSyncDfxManager::SetStartTime()
641 {
642 int32_t errCode;
643 shared_ptr<NativePreferences::Preferences> prefs =
644 NativePreferences::PreferencesHelper::GetPreferences(DFX_COMMON_XML, errCode);
645 if (!prefs) {
646 MEDIA_ERR_LOG("get dfx common preferences error: %{public}d", errCode);
647 return;
648 }
649 int64_t time = prefs->GetLong(CLOUD_SYNC_START_TIME, 0);
650 // if startTime exists, no need to reset startTime
651 if (time != 0) {
652 return;
653 }
654 time = MediaFileUtils::UTCTimeSeconds();
655 prefs->PutLong(CLOUD_SYNC_START_TIME, time);
656 prefs->FlushSync();
657 }
658
659 } // namespace Media
660 } // namespace OHOS