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