• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "MedialibrarySubscribe"
16 
17 #include "medialibrary_subscriber.h"
18 
19 #include <memory>
20 #include "appexecfwk_errors.h"
21 #include "background_cloud_file_processor.h"
22 #include "background_task_mgr_helper.h"
23 #ifdef HAS_BATTERY_MANAGER_PART
24 #include "battery_srv_client.h"
25 #endif
26 #include "bundle_info.h"
27 #include "cloud_media_asset_manager.h"
28 #include "cloud_media_asset_types.h"
29 #include "cloud_sync_utils.h"
30 #include "cloud_upload_checker.h"
31 #include "common_event_manager.h"
32 #include "common_event_support.h"
33 #include "common_event_utils.h"
34 #include "dfx_cloud_manager.h"
35 #include "dfx_moving_photo.h"
36 
37 #include "want.h"
38 #include "post_event_utils.h"
39 #ifdef HAS_POWER_MANAGER_PART
40 #include "power_mgr_client.h"
41 #endif
42 #ifdef HAS_THERMAL_MANAGER_PART
43 #include "thermal_mgr_client.h"
44 #endif
45 
46 #include "medialibrary_album_fusion_utils.h"
47 #include "medialibrary_all_album_refresh_processor.h"
48 #include "medialibrary_bundle_manager.h"
49 #include "medialibrary_data_manager.h"
50 #include "medialibrary_errno.h"
51 #include "medialibrary_inotify.h"
52 #include "medialibrary_kvstore_manager.h"
53 #ifdef META_RECOVERY_SUPPORT
54 #include "medialibrary_meta_recovery.h"
55 #endif
56 #include "medialibrary_restore.h"
57 #include "medialibrary_subscriber_database_utils.h"
58 #include "media_file_utils.h"
59 #include "media_log.h"
60 #include "media_scanner_manager.h"
61 #include "application_context.h"
62 #include "ability_manager_client.h"
63 #include "resource_type.h"
64 #include "dfx_manager.h"
65 #include "medialibrary_unistore_manager.h"
66 #include "medialibrary_update_dirty_data_task_data.h"
67 #include "medialibrary_rdb_utils.h"
68 #include "medialibrary_type_const.h"
69 #include "moving_photo_processor.h"
70 #include "permission_utils.h"
71 #include "thumbnail_generate_worker_manager.h"
72 #include "userfilemgr_uri.h"
73 #include "common_timer_errors.h"
74 #include "parameters.h"
75 #ifdef HAS_WIFI_MANAGER_PART
76 #include "wifi_device.h"
77 #endif
78 #include "net_conn_client.h"
79 #include "power_efficiency_manager.h"
80 #include "photo_album_lpath_operation.h"
81 #include "photo_day_month_year_operation.h"
82 #include "photo_mimetype_operation.h"
83 #include "preferences.h"
84 #include "preferences_helper.h"
85 #include "medialibrary_astc_stat.h"
86 #include "background_cloud_file_processor.h"
87 #ifdef MEDIALIBRARY_FEATURE_CLOUD_ENHANCEMENT
88 #include "enhancement_manager.h"
89 #include "cloud_enhancement_checker.h"
90 #endif
91 
92 using namespace OHOS::AAFwk;
93 
94 namespace OHOS {
95 namespace Media {
96 // The task can be performed when the battery level reaches the value
97 const int32_t PROPER_DEVICE_BATTERY_CAPACITY = 50;
98 const int32_t PROPER_DEVICE_BATTERY_CAPACITY_THUMBNAIL = 20;
99 
100 const int TIME_START_RELEASE_TEMPERATURE_LIMIT = 1;
101 const int TIME_STOP_RELEASE_TEMPERATURE_LIMIT = 6;
102 
103 // The task can be performed only when the temperature of the device is lower than the value
104 const int32_t PROPER_DEVICE_TEMPERATURE_LEVEL_37 = 1;
105 const int32_t PROPER_DEVICE_TEMPERATURE_LEVEL_40 = 2;
106 const int32_t PROPER_DEVICE_TEMPERATURE_LEVEL_43 = 3;
107 
108 // WIFI should be available in this state
109 const int32_t WIFI_STATE_CONNECTED = 4;
110 const int32_t DELAY_TASK_TIME = 30000;
111 const int32_t COMMON_EVENT_KEY_GET_DEFAULT_PARAM = -1;
112 const int32_t MegaByte = 1024 * 1024;
113 const int32_t MAX_FILE_SIZE_MB = 10240;
114 const int32_t UPDATE_DIRTY_CLOUD_CLONE_V1 = 1;
115 const int32_t UPDATE_DIRTY_CLOUD_CLONE_V2 = 2;
116 const std::string COMMON_EVENT_KEY_BATTERY_CAPACITY = "soc";
117 const std::string COMMON_EVENT_KEY_DEVICE_TEMPERATURE = "0";
118 static const std::string TASK_PROGRESS_XML = "/data/storage/el2/base/preferences/task_progress.xml";
119 static const std::string NO_UPDATE_DIRTY = "no_update_dirty";
120 static const std::string NO_UPDATE_DIRTY_CLOUD_CLONE_V2 = "no_update_dirty_cloud_clone_v2";
121 static const std::string NO_DELETE_DIRTY_HDC_DATA = "no_delete_dirty_hdc_data";
122 static const std::string NO_UPDATE_EDITDATA_SIZE = "no_update_editdata_size";
123 static const std::string UPDATE_EDITDATA_SIZE_COUNT = "update_editdata_size_count";
124 
125 // The network should be available in this state
126 const int32_t NET_CONN_STATE_CONNECTED = 3;
127 // The net bearer type is in net_all_capabilities.h
128 const int32_t BEARER_CELLULAR = 0;
129 const int32_t THUMB_ASTC_ENOUGH = 20000;
130 bool MedialibrarySubscriber::isCellularNetConnected_ = false;
131 bool MedialibrarySubscriber::isWifiConnected_ = false;
132 bool MedialibrarySubscriber::currentStatus_ = false;
133 // BetaVersion will upload the DB, and the true uploadDBFlag indicates that uploading is enabled.
134 const std::string KEY_HIVIEW_VERSION_TYPE = "const.logsystem.versiontype";
135 std::atomic<bool> uploadDBFlag(true);
136 int64_t g_lastTime = MediaFileUtils::UTCTimeMilliSeconds();
137 const int32_t HALF_HOUR_MS = 1800000;
138 
139 const std::vector<std::string> MedialibrarySubscriber::events_ = {
140     EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING,
141     EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING,
142     EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF,
143     EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON,
144     EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED,
145     EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED,
146     EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED,
147     EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE,
148     EventFwk::CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE,
149     EventFwk::CommonEventSupport::COMMON_EVENT_TIME_TICK,
150     EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOUT
151 };
152 
153 const std::map<std::string, StatusEventType> BACKGROUND_OPERATION_STATUS_MAP = {
154     {EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING, StatusEventType::CHARGING},
155     {EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING, StatusEventType::DISCHARGING},
156     {EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF, StatusEventType::SCREEN_OFF},
157     {EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON, StatusEventType::SCREEN_ON},
158     {EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED, StatusEventType::BATTERY_CHANGED},
159     {EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED, StatusEventType::THERMAL_LEVEL_CHANGED},
160     {EventFwk::CommonEventSupport::COMMON_EVENT_TIME_TICK, StatusEventType::TIME_TICK},
161 };
162 
GetNowLocalTime(std::tm & nowLocalTime)163 bool GetNowLocalTime(std::tm &nowLocalTime)
164 {
165     auto now = std::chrono::system_clock::now();
166     std::time_t nowTime = std::chrono::system_clock::to_time_t(now);
167     return localtime_r(&nowTime, &nowLocalTime) != nullptr;
168 }
169 
RefreshCellularNetStatus()170 void MedialibrarySubscriber::RefreshCellularNetStatus()
171 {
172     NetManagerStandard::NetHandle handle;
173     int32_t ret = NetManagerStandard::NetConnClient::GetInstance().GetDefaultNet(handle);
174     CHECK_AND_RETURN_LOG(ret == 0, "GetDefaultNet failed, err:%{public}d", ret);
175     NetManagerStandard::NetAllCapabilities netAllCap;
176     ret = NetManagerStandard::NetConnClient::GetInstance().GetNetCapabilities(handle, netAllCap);
177     CHECK_AND_RETURN_LOG(ret == 0, "GetNetCapabilities failed, err:%{public}d", ret);
178     const std::set<NetManagerStandard::NetBearType>& types = netAllCap.bearerTypes_;
179     if (types.count(NetManagerStandard::BEARER_CELLULAR)) {
180         MEDIA_INFO_LOG("init cellular status success: %{public}d", isCellularNetConnected_);
181         isCellularNetConnected_ = true;
182     }
183     return;
184 }
185 
MedialibrarySubscriber(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)186 MedialibrarySubscriber::MedialibrarySubscriber(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
187     : EventFwk::CommonEventSubscriber(subscriberInfo)
188 {
189 #ifdef HAS_POWER_MANAGER_PART
190     auto& powerMgrClient = PowerMgr::PowerMgrClient::GetInstance();
191     isScreenOff_ = !powerMgrClient.IsScreenOn();
192 #endif
193 #ifdef HAS_BATTERY_MANAGER_PART
194     auto& batteryClient = PowerMgr::BatterySrvClient::GetInstance();
195     auto chargeState = batteryClient.GetChargingStatus();
196     isCharging_ = (chargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_ENABLE) ||
197         (chargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_FULL);
198     batteryCapacity_ = batteryClient.GetCapacity();
199 #endif
200 #ifdef HAS_THERMAL_MANAGER_PART
201     auto& thermalMgrClient = PowerMgr::ThermalMgrClient::GetInstance();
202     newTemperatureLevel_ = static_cast<int32_t>(thermalMgrClient.GetThermalLevel());
203     isDeviceTemperatureProper_ = newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_37;
204 #endif
205 #ifdef HAS_WIFI_MANAGER_PART
206     auto wifiDevicePtr = Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
207     if (wifiDevicePtr == nullptr) {
208         MEDIA_ERR_LOG("MedialibrarySubscriber wifiDevicePtr is null");
209     } else {
210         ErrCode ret = wifiDevicePtr->IsConnected(isWifiConnected_);
211         if (ret != Wifi::WIFI_OPT_SUCCESS) {
212             MEDIA_ERR_LOG("MedialibrarySubscriber Get-IsConnected-fail: -%{public}d", ret);
213         }
214     }
215 #endif
216     MedialibrarySubscriber::RefreshCellularNetStatus();
217     MediaLibraryAllAlbumRefreshProcessor::GetInstance()->OnCurrentStatusChanged(
218         isScreenOff_ && isCharging_ && batteryCapacity_ >= PROPER_DEVICE_BATTERY_CAPACITY
219         && isDeviceTemperatureProper_);
220     MEDIA_DEBUG_LOG("MedialibrarySubscriber current status:%{public}d, %{public}d, %{public}d, %{public}d, %{public}d",
221         isScreenOff_, isCharging_, batteryCapacity_, newTemperatureLevel_, isWifiConnected_);
222 }
223 
224 MedialibrarySubscriber::~MedialibrarySubscriber() = default;
225 
Subscribe(void)226 bool MedialibrarySubscriber::Subscribe(void)
227 {
228     EventFwk::MatchingSkills matchingSkills;
229     for (auto event : events_) {
230         matchingSkills.AddEvent(event);
231     }
232 
233     MEDIA_INFO_LOG("Subscribe: add event.");
234     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
235 
236     std::shared_ptr<MedialibrarySubscriber> subscriber = std::make_shared<MedialibrarySubscriber>(subscribeInfo);
237     return EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
238 }
239 
IsBetaVersion()240 static bool IsBetaVersion()
241 {
242     static const string versionType = system::GetParameter(KEY_HIVIEW_VERSION_TYPE, "unknown");
243     static bool isBetaVersion = versionType.find("beta") != std::string::npos;
244     return isBetaVersion;
245 }
246 
IsLastHalfHourDb()247 static bool IsLastHalfHourDb()
248 {
249     int64_t curTime = MediaFileUtils::UTCTimeMilliSeconds();
250     if (curTime - g_lastTime >= HALF_HOUR_MS) {
251         g_lastTime = curTime;
252         return true;
253     }
254     return false;
255 }
256 
UploadDBFile()257 static void UploadDBFile()
258 {
259     uploadDBFlag.store(false);
260     int64_t begin = MediaFileUtils::UTCTimeMilliSeconds();
261     static const std::string databaseDir = MEDIA_DB_DIR + "/rdb";
262     static const std::vector<std::string> dbFileName = { "/media_library.db",
263                                                          "/media_library.db-shm",
264                                                          "/media_library.db-wal" };
265     static const std::string destPath = "/data/storage/el2/log/logpack";
266     int64_t totalFileSize = 0;
267     for (auto &dbName : dbFileName) {
268         string dbPath = databaseDir + dbName;
269         struct stat statInfo {};
270         if (stat(dbPath.c_str(), &statInfo) != 0) {
271             continue;
272         }
273         totalFileSize += statInfo.st_size;
274     }
275     totalFileSize /= MegaByte; // Convert bytes to MB
276     if (totalFileSize > MAX_FILE_SIZE_MB) {
277         MEDIA_WARN_LOG("DB file over 10GB are not uploaded, totalFileSize is %{public}ld MB",
278             static_cast<long>(totalFileSize));
279         uploadDBFlag.store(true);
280         return ;
281     }
282     if (!MediaFileUtils::IsFileExists(destPath) && !MediaFileUtils::CreateDirectory(destPath)) {
283         MEDIA_ERR_LOG("Create dir failed, dir=%{private}s", destPath.c_str());
284         uploadDBFlag.store(true);
285         return ;
286     }
287     auto dataManager = MediaLibraryDataManager::GetInstance();
288     if (dataManager == nullptr) {
289         MEDIA_ERR_LOG("dataManager is nullptr");
290         uploadDBFlag.store(true);
291         return;
292     }
293     dataManager->UploadDBFileInner(totalFileSize);
294     int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
295     MEDIA_INFO_LOG("Handle %{public}s MB DBFile success, cost %{public}s ms", std::to_string(totalFileSize).c_str(),
296         std::to_string(end - begin).c_str());
297     uploadDBFlag.store(true);
298 }
299 
CheckHalfDayMissions()300 void MedialibrarySubscriber::CheckHalfDayMissions()
301 {
302     if (isScreenOff_ && isCharging_) {
303         if (IsBetaVersion() && uploadDBFlag.load() && IsLastHalfHourDb()) {
304             MEDIA_INFO_LOG("Version is BetaVersion, UploadDBFile");
305             UploadDBFile();
306         }
307         DfxManager::GetInstance()->HandleHalfDayMissions();
308         MediaLibraryRestore::GetInstance().CheckBackup();
309     }
310     if (!isScreenOff_ || !isCharging_) {
311         MediaLibraryRestore::GetInstance().InterruptBackup();
312     }
313 #ifdef META_RECOVERY_SUPPORT
314     MediaLibraryMetaRecovery::GetInstance().StatisticSave();
315 #endif
316 }
317 
UpdateCurrentStatus()318 void MedialibrarySubscriber::UpdateCurrentStatus()
319 {
320     std::lock_guard<std::mutex> lock(mutex_);
321     std::tm nowLocalTime;
322     bool newStatus = false;
323     bool isPowerSufficient = batteryCapacity_ >= PROPER_DEVICE_BATTERY_CAPACITY;
324     if (GetNowLocalTime(nowLocalTime) && nowLocalTime.tm_hour >= TIME_START_RELEASE_TEMPERATURE_LIMIT &&
325         nowLocalTime.tm_hour < TIME_STOP_RELEASE_TEMPERATURE_LIMIT) {
326         newStatus = isScreenOff_ && isCharging_ && isPowerSufficient &&
327             newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_43;
328     } else {
329         newStatus = isScreenOff_ && isCharging_ && isPowerSufficient &&
330             newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_37;
331     }
332 
333     if (currentStatus_ == newStatus) {
334         return;
335     }
336 
337     MEDIA_INFO_LOG("update status current:%{public}d, new:%{public}d, %{public}d, %{public}d, %{public}d, %{public}d",
338         currentStatus_, newStatus, isScreenOff_, isCharging_, isPowerSufficient, newTemperatureLevel_);
339     currentStatus_ = newStatus;
340     backgroundDelayTask_.EndBackgroundOperationThread();
341     BackgroundCloudFileProcessor::RepairMimeType();
342     if (currentStatus_) {
343         backgroundDelayTask_.SetOperationThread([this] { this->DoBackgroundOperation(); });
344     } else {
345         StopBackgroundOperation();
346     }
347     MediaLibraryAllAlbumRefreshProcessor::GetInstance()->OnCurrentStatusChanged(currentStatus_);
348 }
349 
WalCheckPointAsync()350 void MedialibrarySubscriber::WalCheckPointAsync()
351 {
352     if (!isScreenOff_ || !isCharging_) {
353         return;
354     }
355     std::thread(MediaLibraryRdbStore::WalCheckPoint).detach();
356 }
357 
UpdateBackgroundOperationStatus(const AAFwk::Want & want,const StatusEventType statusEventType)358 void MedialibrarySubscriber::UpdateBackgroundOperationStatus(
359     const AAFwk::Want &want, const StatusEventType statusEventType)
360 {
361     switch (statusEventType) {
362         case StatusEventType::SCREEN_OFF:
363             isScreenOff_ = true;
364             break;
365         case StatusEventType::SCREEN_ON:
366             isScreenOff_ = false;
367             break;
368         case StatusEventType::CHARGING:
369             isCharging_ = true;
370             break;
371         case StatusEventType::DISCHARGING:
372             isCharging_ = false;
373             break;
374         case StatusEventType::BATTERY_CHANGED:
375             batteryCapacity_ = want.GetIntParam(COMMON_EVENT_KEY_BATTERY_CAPACITY,
376                 COMMON_EVENT_KEY_GET_DEFAULT_PARAM);
377             break;
378         case StatusEventType::THERMAL_LEVEL_CHANGED: {
379             newTemperatureLevel_ = want.GetIntParam(COMMON_EVENT_KEY_DEVICE_TEMPERATURE,
380                 COMMON_EVENT_KEY_GET_DEFAULT_PARAM);
381             isDeviceTemperatureProper_ = newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_37;
382             break;
383         }
384         case StatusEventType::TIME_TICK:
385             break;
386         default:
387             MEDIA_WARN_LOG("StatusEventType:%{public}d is not invalid", statusEventType);
388             return;
389     }
390 
391     UpdateCurrentStatus();
392     UpdateThumbnailBgGenerationStatus();
393     UpdateBackgroundTimer();
394     DealWithEventsAfterUpdateStatus(statusEventType);
395 }
396 
UpdateCloudMediaAssetDownloadStatus(const AAFwk::Want & want,const StatusEventType statusEventType)397 void MedialibrarySubscriber::UpdateCloudMediaAssetDownloadStatus(const AAFwk::Want &want,
398     const StatusEventType statusEventType)
399 {
400     if (statusEventType != StatusEventType::THERMAL_LEVEL_CHANGED) {
401         return;
402     }
403     int32_t taskStatus = CloudMediaAssetManager::GetInstance().GetTaskStatus();
404     int32_t downloadType = CloudMediaAssetManager::GetInstance().GetDownloadType();
405     bool foregroundTemperature = want.GetIntParam(COMMON_EVENT_KEY_DEVICE_TEMPERATURE,
406         COMMON_EVENT_KEY_GET_DEFAULT_PARAM) <= PROPER_DEVICE_TEMPERATURE_LEVEL_43;
407     if (!foregroundTemperature && downloadType == static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_FORCE)) {
408         CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::TEMPERATURE_LIMIT);
409         return;
410     }
411     if (foregroundTemperature && taskStatus == static_cast<int32_t>(CloudMediaAssetTaskStatus::PAUSED)) {
412         CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(
413             CloudMediaTaskRecoverCause::FOREGROUND_TEMPERATURE_PROPER);
414     }
415 }
416 
IsCellularNetConnected()417 bool MedialibrarySubscriber::IsCellularNetConnected()
418 {
419     return isCellularNetConnected_;
420 }
421 
IsWifiConnected()422 bool MedialibrarySubscriber::IsWifiConnected()
423 {
424     return isWifiConnected_;
425 }
426 
IsCurrentStatusOn()427 bool MedialibrarySubscriber::IsCurrentStatusOn()
428 {
429     return currentStatus_;
430 }
431 
UpdateCloudMediaAssetDownloadTaskStatus()432 void MedialibrarySubscriber::UpdateCloudMediaAssetDownloadTaskStatus()
433 {
434     if (!isCellularNetConnected_) {
435         MEDIA_INFO_LOG("CellularNet not connected.");
436         int32_t taskStatus = CloudMediaAssetManager::GetInstance().GetTaskStatus();
437         if (taskStatus == static_cast<int32_t>(CloudMediaAssetTaskStatus::PAUSED)) {
438             CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::NETWORK_FLOW_LIMIT);
439         }
440         return;
441     }
442     if (CloudSyncUtils::IsUnlimitedTrafficStatusOn()) {
443         CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(CloudMediaTaskRecoverCause::NETWORK_NORMAL);
444     } else if (!isWifiConnected_) {
445         CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::WIFI_UNAVAILABLE);
446     }
447 }
448 
OnReceiveEvent(const EventFwk::CommonEventData & eventData)449 void MedialibrarySubscriber::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
450 {
451     const AAFwk::Want &want = eventData.GetWant();
452     std::string action = want.GetAction();
453     if (action != EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED &&
454         action != EventFwk::CommonEventSupport::COMMON_EVENT_TIME_TICK) {
455         MEDIA_INFO_LOG("OnReceiveEvent action:%{public}s.", action.c_str());
456     }
457     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE) {
458         isWifiConnected_ = eventData.GetCode() == WIFI_STATE_CONNECTED;
459         UpdateBackgroundTimer();
460         if (isWifiConnected_) {
461             CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(CloudMediaTaskRecoverCause::NETWORK_NORMAL);
462         }
463     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE) {
464         int netType = want.GetIntParam("NetType", -1);
465         bool isNetConnected = eventData.GetCode() == NET_CONN_STATE_CONNECTED;
466         MEDIA_INFO_LOG("netType: %{public}d, isConnected: %{public}d.", netType, static_cast<int32_t>(isNetConnected));
467         isCellularNetConnected_ = netType == BEARER_CELLULAR ? isNetConnected : isCellularNetConnected_;
468         UpdateCloudMediaAssetDownloadTaskStatus();
469     } else if (BACKGROUND_OPERATION_STATUS_MAP.count(action) != 0) {
470         UpdateBackgroundOperationStatus(want, BACKGROUND_OPERATION_STATUS_MAP.at(action));
471         UpdateCloudMediaAssetDownloadStatus(want, BACKGROUND_OPERATION_STATUS_MAP.at(action));
472     } else if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) == 0) {
473         string packageName = want.GetElement().GetBundleName();
474         RevertPendingByPackage(packageName);
475         MediaLibraryBundleManager::GetInstance()->Clear();
476         PermissionUtils::ClearBundleInfoInCache();
477     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOUT) {
478         // when turn off gallery switch or quit account, clear the download lastest finished flag,
479         // so we can download lastest images for the subsequent login new account
480         BackgroundCloudFileProcessor::SetDownloadLatestFinished(false);
481     }
482 
483 #ifdef MEDIALIBRARY_FEATURE_CLOUD_ENHANCEMENT
484     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE ||
485         action == EventFwk::CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE) {
486         EnhancementManager::GetInstance().HandleNetChange(isWifiConnected_, isCellularNetConnected_);
487     }
488 #endif
489 }
490 
GetNowTime()491 int64_t MedialibrarySubscriber::GetNowTime()
492 {
493     struct timespec t;
494     constexpr int64_t SEC_TO_MSEC = 1e3;
495     constexpr int64_t MSEC_TO_NSEC = 1e6;
496     clock_gettime(CLOCK_REALTIME, &t);
497     return t.tv_sec * SEC_TO_MSEC + t.tv_nsec / MSEC_TO_NSEC;
498 }
499 
Init()500 void MedialibrarySubscriber::Init()
501 {
502     lockTime_ = GetNowTime();
503     agingCount_ = 0;
504 }
505 
DeleteTemporaryPhotos()506 void DeleteTemporaryPhotos()
507 {
508     auto dataManager = MediaLibraryDataManager::GetInstance();
509     if (dataManager == nullptr) {
510         return;
511     }
512 
513     string UriString = PAH_DISCARD_CAMERA_PHOTO;
514     MediaFileUtils::UriAppendKeyValue(UriString, URI_PARAM_API_VERSION, to_string(MEDIA_API_VERSION_V10));
515     Uri uri(UriString);
516     MediaLibraryCommand cmd(uri);
517     DataShare::DataShareValuesBucket valuesBucket;
518     valuesBucket.Put(PhotoColumn::PHOTO_IS_TEMP, true);
519     DataShare::DataSharePredicates predicates;
520 
521     // 24H之前的数据
522     int64_t current = MediaFileUtils::UTCTimeMilliSeconds();
523     int64_t timeBefore24Hours = current - 24 * 60 * 60 * 1000;
524     string where = PhotoColumn::PHOTO_IS_TEMP + " = 1 AND (" + PhotoColumn::MEDIA_DATE_ADDED + " <= " +
525         to_string(timeBefore24Hours) + " OR " + MediaColumn::MEDIA_ID + " NOT IN (SELECT " + MediaColumn::MEDIA_ID +
526         " FROM (SELECT " + MediaColumn::MEDIA_ID + " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
527         PhotoColumn::PHOTO_IS_TEMP + " = 1 " + "ORDER BY " + MediaColumn::MEDIA_ID +
528         " DESC LIMIT 50)) AND (select COUNT(1) from " + PhotoColumn::PHOTOS_TABLE +
529         " where " + PhotoColumn::PHOTO_IS_TEMP + " = 1) > 100) ";
530     predicates.SetWhereClause(where);
531 
532     auto changedRows = dataManager->Update(cmd, valuesBucket, predicates);
533     CHECK_AND_RETURN_LOG(changedRows >= 0, "Failed to update property of asset, err: %{public}d", changedRows);
534     MEDIA_INFO_LOG("delete %{public}d temp files exceeding 24 hous or exceed maximum quantity.", changedRows);
535 }
536 
DoAgingOperation()537 void MedialibrarySubscriber::DoAgingOperation()
538 {
539     auto dataManager = MediaLibraryDataManager::GetInstance();
540     CHECK_AND_RETURN_LOG(dataManager != nullptr, "dataManager is nullptr");
541 
542     int32_t result = dataManager->DoAging();
543     CHECK_AND_PRINT_LOG(result == E_OK, "DoAging faild");
544 
545     shared_ptr<int> trashCountPtr = make_shared<int>();
546     result = dataManager->DoTrashAging(trashCountPtr);
547     CHECK_AND_PRINT_LOG(result == E_OK, "DoTrashAging faild");
548 
549     VariantMap map = {{KEY_COUNT, *trashCountPtr}};
550     PostEventUtils::GetInstance().PostStatProcess(StatType::AGING_STAT, map);
551 }
552 
QueryBurstNeedUpdate(AsyncTaskData * data)553 static void QueryBurstNeedUpdate(AsyncTaskData *data)
554 {
555     auto dataManager = MediaLibraryDataManager::GetInstance();
556     CHECK_AND_RETURN_LOG(dataManager != nullptr,  "dataManager is nullptr");
557 
558     int32_t result = dataManager->UpdateBurstFromGallery();
559     CHECK_AND_PRINT_LOG(result == E_OK, "UpdateBurstFromGallery faild");
560 }
561 
DoUpdateBurstFromGallery()562 static int32_t DoUpdateBurstFromGallery()
563 {
564     MEDIA_INFO_LOG("Begin DoUpdateBurstFromGallery");
565     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
566     CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL, "Failed to get async worker instance!");
567 
568     shared_ptr<MediaLibraryAsyncTask> updateBurstTask =
569         make_shared<MediaLibraryAsyncTask>(QueryBurstNeedUpdate, nullptr);
570     CHECK_AND_RETURN_RET_LOG(updateBurstTask != nullptr, E_FAIL,
571         "Failed to create async task for updateBurstTask!");
572     asyncWorker->AddTask(updateBurstTask, false);
573     return E_SUCCESS;
574 }
575 
QueryUpdateSize(AsyncTaskData * data)576 static void QueryUpdateSize(AsyncTaskData *data)
577 {
578     auto dataManager = MediaLibraryDataManager::GetInstance();
579     CHECK_AND_RETURN_LOG(dataManager != nullptr,  "dataManager is nullptr");
580 
581     int32_t result = dataManager->UpdateMediaSizeFromStorage();
582     CHECK_AND_PRINT_LOG(result == E_OK, "UpdateMediaSizeFromStorage failed");
583 }
584 
UpdateAllEditDataSize()585 static int32_t UpdateAllEditDataSize()
586 {
587     int32_t errCode;
588     shared_ptr<NativePreferences::Preferences> prefs =
589         NativePreferences::PreferencesHelper::GetPreferences(TASK_PROGRESS_XML, errCode);
590     if (prefs == nullptr) {
591         MEDIA_ERR_LOG("Get preferences error: %{public}d", errCode);
592         return E_ERR;
593     }
594     if (prefs->GetInt(NO_UPDATE_EDITDATA_SIZE, 0) == 1) {
595         return E_SUCCESS;
596     }
597 
598     MEDIA_INFO_LOG("Begin DoUpdateAllEditDataSize");
599     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
600     CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL, "Failed to get async worker instance!");
601 
602     shared_ptr<MediaLibraryAsyncTask> updateSizeTask =
603         make_shared<MediaLibraryAsyncTask>(QueryUpdateSize, nullptr);
604     CHECK_AND_RETURN_RET_LOG(updateSizeTask != nullptr, E_FAIL,
605         "Failed to create async task for updateBurstTask!");
606     asyncWorker->AddTask(updateSizeTask, false);
607     return E_SUCCESS;
608 }
609 
UpdateDirtyForCloudClone(AsyncTaskData * data)610 static void UpdateDirtyForCloudClone(AsyncTaskData *data)
611 {
612     auto *taskData = static_cast<UpdateDirtyDataAsyncTaskData *>(data);
613     CHECK_AND_RETURN_LOG(taskData != nullptr, "taskData is nullptr!");
614     int32_t taskVersion = taskData->taskVersion_;
615     auto dataManager = MediaLibraryDataManager::GetInstance();
616     CHECK_AND_RETURN_LOG(dataManager != nullptr, "Failed to MediaLibraryDataManager instance!");
617 
618     int32_t result = dataManager->UpdateDirtyForCloudClone(taskVersion);
619     CHECK_AND_PRINT_LOG(result == E_OK, "UpdateDirtyForCloudClone faild, result = %{public}d", result);
620 }
621 
ClearDirtyHdcData(AsyncTaskData * data)622 static void ClearDirtyHdcData(AsyncTaskData *data)
623 {
624     auto dataManager = MediaLibraryDataManager::GetInstance();
625     CHECK_AND_RETURN_LOG(dataManager != nullptr, "Failed to MediaLibraryDataManager instance!");
626 
627     int32_t result = dataManager->ClearDirtyHdcData();
628     CHECK_AND_PRINT_LOG(result == E_OK, "ClearDirtyHdcData faild, result = %{public}d", result);
629 }
630 
631 
DoUpdateDirtyForCloudClone(int32_t taskVersion)632 static int32_t DoUpdateDirtyForCloudClone(int32_t taskVersion)
633 {
634     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
635     CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL,
636         "Failed to get async worker instance!");
637     auto *taskData = new (std::nothrow) UpdateDirtyDataAsyncTaskData(taskVersion);
638     CHECK_AND_RETURN_RET_LOG(taskData != nullptr, E_FAIL, "Failed to alloc async data for update dirty data!");
639     shared_ptr<MediaLibraryAsyncTask> updateDirtyForCloudTask =
640         make_shared<MediaLibraryAsyncTask>(UpdateDirtyForCloudClone, taskData);
641     CHECK_AND_RETURN_RET_LOG(updateDirtyForCloudTask != nullptr, E_FAIL,
642         "Failed to create async task for updateDirtyForCloudTask !");
643     asyncWorker->AddTask(updateDirtyForCloudTask, false);
644     return E_SUCCESS;
645 }
646 
DoClearDirtyHdcData()647 static int32_t DoClearDirtyHdcData()
648 {
649     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
650     CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL,
651         "Failed to get async worker instance!");
652     shared_ptr<MediaLibraryAsyncTask> clearDirtyHdcDataTask =
653         make_shared<MediaLibraryAsyncTask>(ClearDirtyHdcData, nullptr);
654     CHECK_AND_RETURN_RET_LOG(clearDirtyHdcDataTask != nullptr, E_FAIL,
655         "Failed to create async task for clearDirtyHdcDataTask !");
656     asyncWorker->AddTask(clearDirtyHdcDataTask, false);
657     return E_SUCCESS;
658 }
659 
RecoverBackgroundDownloadCloudMediaAsset()660 static void RecoverBackgroundDownloadCloudMediaAsset()
661 {
662     if (!CloudMediaAssetManager::GetInstance().SetBgDownloadPermission(true)) {
663         return;
664     }
665     int32_t ret = CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(
666         CloudMediaTaskRecoverCause::BACKGROUND_TASK_AVAILABLE);
667     CHECK_AND_PRINT_LOG(ret == E_OK, "RecoverDownloadCloudAsset faild");
668 }
669 
UpdateBurstCoverLevelFromGallery(AsyncTaskData * data)670 static void UpdateBurstCoverLevelFromGallery(AsyncTaskData *data)
671 {
672     auto dataManager = MediaLibraryDataManager::GetInstance();
673     CHECK_AND_RETURN_LOG(dataManager != nullptr, "dataManager is nullptr");
674 
675     int32_t result = dataManager->UpdateBurstCoverLevelFromGallery();
676     CHECK_AND_PRINT_LOG(result == E_OK, "UpdateBurstCoverLevelFromGallery faild");
677 }
678 
DoUpdateBurstCoverLevelFromGallery()679 static int32_t DoUpdateBurstCoverLevelFromGallery()
680 {
681     MEDIA_INFO_LOG("Begin DoUpdateBurstCoverLevelFromGallery");
682     auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
683     CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL,
684         "Failed to get async worker instance!");
685 
686     shared_ptr<MediaLibraryAsyncTask> updateBurstCoverLevelTask =
687         make_shared<MediaLibraryAsyncTask>(UpdateBurstCoverLevelFromGallery, nullptr);
688     CHECK_AND_RETURN_RET_LOG(updateBurstCoverLevelTask != nullptr, E_FAIL,
689         "Failed to create async task for updateBurstCoverLevelTask!");
690     asyncWorker->AddTask(updateBurstCoverLevelTask, false);
691     return E_SUCCESS;
692 }
693 
UpdateDirtyForBeta(const shared_ptr<NativePreferences::Preferences> & prefs)694 static void UpdateDirtyForBeta(const shared_ptr<NativePreferences::Preferences>& prefs)
695 {
696     CHECK_AND_RETURN_LOG((IsBetaVersion() && prefs != nullptr), "not need UpdateDirtyForBeta");
697     if (prefs->GetInt(NO_UPDATE_DIRTY, 0) != 1) {
698         int32_t ret = DoUpdateDirtyForCloudClone(UPDATE_DIRTY_CLOUD_CLONE_V1);
699         CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateDirtyForCloudClone failed");
700     }
701     if (prefs->GetInt(NO_UPDATE_DIRTY_CLOUD_CLONE_V2, 0) != 1) {
702         int32_t ret = DoUpdateDirtyForCloudClone(UPDATE_DIRTY_CLOUD_CLONE_V2);
703         CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateDirtyForCloudClone failed");
704     }
705     return;
706 }
707 
ClearDirtyHdcData(const shared_ptr<NativePreferences::Preferences> & prefs)708 static void ClearDirtyHdcData(const shared_ptr<NativePreferences::Preferences>& prefs)
709 {
710     if (prefs != nullptr && (prefs->GetInt(NO_DELETE_DIRTY_HDC_DATA, 0) != 1)) {
711         int32_t ret = DoClearDirtyHdcData();
712         CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateDirtyForCloudClone failed");
713     }
714     return;
715 }
716 
ClearDirtyData()717 void MedialibrarySubscriber::ClearDirtyData()
718 {
719     int32_t errCode;
720     shared_ptr<NativePreferences::Preferences> prefs =
721         NativePreferences::PreferencesHelper::GetPreferences(TASK_PROGRESS_XML, errCode);
722     CHECK_AND_RETURN_LOG(prefs, "Get preferences error: %{public}d", errCode);
723     UpdateDirtyForBeta(prefs);
724     ClearDirtyHdcData(prefs);
725     TryClearContinueCloneData();
726     return;
727 }
728 
PeriodicAnalyzePhotosData()729 static void PeriodicAnalyzePhotosData()
730 {
731     constexpr int64_t analyzeIntervalMillisecond = 24 * 60 * 60 * 1000;
732     static int64_t lastAnalyzeTime {0};
733     if (MediaFileUtils::UTCTimeMilliSeconds() - lastAnalyzeTime >= analyzeIntervalMillisecond) {
734         MediaLibraryRdbUtils::AnalyzePhotosData();
735         lastAnalyzeTime = MediaFileUtils::UTCTimeMilliSeconds();
736         return;
737     }
738 }
739 
DoBackgroundOperation()740 void MedialibrarySubscriber::DoBackgroundOperation()
741 {
742     bool cond = (!backgroundDelayTask_.IsDelayTaskTimeOut() || !currentStatus_);
743     CHECK_AND_RETURN_LOG(!cond, "The conditions for DoBackgroundOperation are not met, will return.");
744 #ifdef META_RECOVERY_SUPPORT
745     // check metadata recovery state
746     MediaLibraryMetaRecovery::GetInstance().CheckRecoveryState();
747 #endif
748     // delete temporary photos
749     DeleteTemporaryPhotos();
750     // clear dirty data
751     ClearDirtyData();
752     BackgroundTaskMgr::EfficiencyResourceInfo resourceInfo = BackgroundTaskMgr::EfficiencyResourceInfo(
753         BackgroundTaskMgr::ResourceType::CPU, true, 0, "apply", true, true);
754     BackgroundTaskMgr::BackgroundTaskMgrHelper::ApplyEfficiencyResources(resourceInfo);
755     Init();
756     DoAgingOperation();
757     PeriodicAnalyzePhotosData();
758     // update burst from gallery
759     int32_t ret = DoUpdateBurstFromGallery();
760     CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateBurstFromGallery faild");
761     // update all editdata size
762     ret = UpdateAllEditDataSize();
763     CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateAllEditDataSize faild");
764 
765     CloudUploadChecker::RepairNoOriginPhoto();
766 #ifdef MEDIALIBRARY_FEATURE_CLOUD_ENHANCEMENT
767     // add permission for cloud enhancement photo
768     CloudEnhancementChecker::AddPermissionForCloudEnhancement();
769 #endif
770     // migration highlight info to new path
771     if (MediaFileUtils::IsFileExists(ROOT_MEDIA_DIR + HIGHLIGHT_INFO_OLD)) {
772         MEDIA_INFO_LOG("Migration highlight info to new path");
773         bool retMigration = MediaFileUtils::CopyDirAndDelSrc(ROOT_MEDIA_DIR + HIGHLIGHT_INFO_OLD,
774             ROOT_MEDIA_DIR + HIGHLIGHT_INFO_NEW);
775         if (retMigration) {
776             bool retDelete = MediaFileUtils::DeleteDir(ROOT_MEDIA_DIR + HIGHLIGHT_INFO_OLD);
777             if (!retDelete) {
778                 MEDIA_ERR_LOG("Delete old highlight path fail");
779             }
780         }
781     }
782     ret = DoUpdateBurstCoverLevelFromGallery();
783     CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateBurstCoverLevelFromGallery faild");
784     RecoverBackgroundDownloadCloudMediaAsset();
785     CloudMediaAssetManager::GetInstance().StartDeleteCloudMediaAssets();
786     // compat old-version moving photo
787     MovingPhotoProcessor::StartProcess();
788     MediaLibraryAlbumFusionUtils::CleanInvalidCloudAlbumAndData(true);
789     auto watch = MediaLibraryInotify::GetInstance();
790     if (watch != nullptr) {
791         watch->DoAging();
792     }
793     DfxMovingPhoto::AbnormalMovingPhotoStatistics();
794     PhotoMimetypeOperation::UpdateInvalidMimeType();
795     DfxManager::GetInstance()->HandleTwoDayMissions();
796     DfxManager::GetInstance()->HandleOneWeekMissions();
797     PhotoDayMonthYearOperation::RepairDateTime();
798     backgroundTaskFactory_.Execute();
799 }
800 
PauseBackgroundDownloadCloudMedia()801 static void PauseBackgroundDownloadCloudMedia()
802 {
803     if (!CloudMediaAssetManager::GetInstance().SetBgDownloadPermission(false)) {
804         return;
805     }
806     int32_t taskStatus = static_cast<int32_t>(CloudMediaAssetTaskStatus::DOWNLOADING);
807     int32_t downloadType = static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_GENTLE);
808     if (CloudMediaAssetManager::GetInstance().GetTaskStatus() == taskStatus &&
809         CloudMediaAssetManager::GetInstance().GetDownloadType() == downloadType) {
810         CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(
811             CloudMediaTaskPauseCause::BACKGROUND_TASK_UNAVAILABLE);
812     }
813 }
814 
StopBackgroundOperation()815 void MedialibrarySubscriber::StopBackgroundOperation()
816 {
817 #ifdef META_RECOVERY_SUPPORT
818     MediaLibraryMetaRecovery::GetInstance().InterruptRecovery();
819 #endif
820     MovingPhotoProcessor::StopProcess();
821     MediaLibraryDataManager::GetInstance()->InterruptBgworker();
822     PauseBackgroundDownloadCloudMedia();
823     PhotoAlbumLPathOperation::GetInstance().Stop();
824     CloudMediaAssetManager::GetInstance().StopDeleteCloudMediaAssets();
825 }
826 
UpdateThumbnailBgGenerationStatus()827 void MedialibrarySubscriber::UpdateThumbnailBgGenerationStatus()
828 {
829     std::lock_guard<std::mutex> lock(mutex_);
830     bool isPowerSufficientForThumbnail = batteryCapacity_ >= PROPER_DEVICE_BATTERY_CAPACITY_THUMBNAIL;
831     bool newStatus = false;
832     if (isCharging_) {
833         newStatus = isScreenOff_ && isPowerSufficientForThumbnail &&
834             newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_43;
835     } else if (isScreenOff_ && newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_37 &&
836         batteryCapacity_ >= PROPER_DEVICE_BATTERY_CAPACITY) {
837         int32_t thumbAstcCount = 0;
838         int32_t thumbTotalCount = 0;
839         MedialibrarySubscriberDatabaseUtils::QueryThumbAstc(thumbAstcCount);
840         MedialibrarySubscriberDatabaseUtils::QueryThumbTotal(thumbTotalCount);
841         bool isThumbAstcEnough = thumbAstcCount > THUMB_ASTC_ENOUGH || thumbAstcCount == thumbTotalCount;
842         newStatus = !isThumbAstcEnough;
843         CHECK_AND_PRINT_LOG(isThumbAstcEnough,
844             "ThumbnailBg generate status: isThumbAstcEnough:%{public}d,"
845             " thumbAstcCount:%{public}d, thumbTotalCount:%{public}d",
846             isThumbAstcEnough, thumbAstcCount, thumbTotalCount);
847     }
848 
849     if (thumbnailBgGenerationStatus_ == newStatus) {
850         return;
851     }
852     MEDIA_INFO_LOG("update status thumbnailBg:%{public}d, new:%{public}d, "
853         "%{public}d, %{public}d, %{public}d, %{public}d",
854         thumbnailBgGenerationStatus_, newStatus, isScreenOff_,
855         isCharging_, batteryCapacity_, newTemperatureLevel_);
856     thumbnailBgGenerationStatus_ = newStatus;
857 
858     thumbnailBgDelayTask_.EndBackgroundOperationThread();
859     if (thumbnailBgGenerationStatus_) {
860         thumbnailBgDelayTask_.SetOperationThread([this] { this->DoThumbnailBgOperation(); });
861     } else {
862         MediaLibraryAstcStat::GetInstance().GetInterruptInfo(isScreenOff_, isCharging_,
863             isPowerSufficientForThumbnail,
864             newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL_40);
865         StopThumbnailBgOperation();
866     }
867 }
868 
DoThumbnailBgOperation()869 void MedialibrarySubscriber::DoThumbnailBgOperation()
870 {
871     bool cond = (!thumbnailBgDelayTask_.IsDelayTaskTimeOut() || !thumbnailBgGenerationStatus_);
872     CHECK_AND_RETURN_LOG(!cond, "The conditions for DoThumbnailBgOperation are not met, will return.");
873 
874     auto dataManager = MediaLibraryDataManager::GetInstance();
875     CHECK_AND_RETURN_LOG(dataManager != nullptr, "dataManager is nullptr");
876 
877     auto result = dataManager->GenerateThumbnailBackground();
878     CHECK_AND_PRINT_LOG(result == E_OK, "GenerateThumbnailBackground faild");
879 
880     result = dataManager->UpgradeThumbnailBackground(isWifiConnected_);
881     CHECK_AND_PRINT_LOG(result == E_OK, "UpgradeThumbnailBackground faild");
882 
883     result = dataManager->GenerateHighlightThumbnailBackground();
884     CHECK_AND_PRINT_LOG(result == E_OK, "GenerateHighlightThumbnailBackground failed %{public}d", result);
885 }
886 
StopThumbnailBgOperation()887 void MedialibrarySubscriber::StopThumbnailBgOperation()
888 {
889     MediaLibraryDataManager::GetInstance()->InterruptThumbnailBgWorker();
890 }
891 
892 #ifdef MEDIALIBRARY_MTP_ENABLE
DoStartMtpService()893 void MedialibrarySubscriber::DoStartMtpService()
894 {
895     AAFwk::Want want;
896     want.SetElementName("com.ohos.medialibrary.medialibrarydata", "MtpService");
897     auto abilityContext = AbilityRuntime::Context::GetApplicationContext();
898     ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, abilityContext->GetToken(),
899         OHOS::AAFwk::DEFAULT_INVAL_VALUE);
900     MEDIA_INFO_LOG("MedialibrarySubscriber::DoStartMtpService. End calling StartAbility. ret=%{public}d", err);
901 }
902 #endif
903 
RevertPendingByPackage(const std::string & bundleName)904 void MedialibrarySubscriber::RevertPendingByPackage(const std::string &bundleName)
905 {
906     MediaLibraryDataManager::GetInstance()->RevertPendingByPackage(bundleName);
907 }
908 
UpdateBackgroundTimer()909 void MedialibrarySubscriber::UpdateBackgroundTimer()
910 {
911     std::lock_guard<std::mutex> lock(mutex_);
912     bool isPowerSufficient = batteryCapacity_ >= PROPER_DEVICE_BATTERY_CAPACITY;
913     bool newStatus = isScreenOff_ && isCharging_ && isPowerSufficient &&
914         isDeviceTemperatureProper_ && isWifiConnected_;
915     if (timerStatus_ == newStatus) {
916         return;
917     }
918 
919     MEDIA_INFO_LOG("update timer status current:%{public}d, new:%{public}d, %{public}d, %{public}d, %{public}d, "
920         "%{public}d, %{public}d",
921         timerStatus_, newStatus, isScreenOff_, isCharging_, isPowerSufficient, isDeviceTemperatureProper_,
922         isWifiConnected_);
923 
924     timerStatus_ = newStatus;
925     if (timerStatus_) {
926         BackgroundCloudFileProcessor::StartTimer();
927     } else {
928         BackgroundCloudFileProcessor::StopTimer();
929     }
930 }
931 
DealWithEventsAfterUpdateStatus(const StatusEventType statusEventType)932 void MedialibrarySubscriber::DealWithEventsAfterUpdateStatus(const StatusEventType statusEventType)
933 {
934     std::lock_guard<std::mutex> lock(mutex_);
935     if (deviceTemperatureLevel_ != newTemperatureLevel_) {
936         deviceTemperatureLevel_ = newTemperatureLevel_;
937         ThumbnailService::GetInstance()->NotifyTempStatusForReady(deviceTemperatureLevel_);
938     }
939 
940     CloudSyncDfxManager::GetInstance().RunDfx();
941     ThumbnailService::GetInstance()->UpdateCurrentStatusForTask(thumbnailBgGenerationStatus_);
942     ThumbnailGenerateWorkerManager::GetInstance().TryCloseThumbnailWorkerTimer();
943     MediaLibraryKvStoreManager::GetInstance().TryCloseAllKvStore();
944     PowerEfficiencyManager::SetSubscriberStatus(isCharging_, isScreenOff_);
945 
946     if (statusEventType == StatusEventType::SCREEN_OFF || statusEventType == StatusEventType::CHARGING) {
947         WalCheckPointAsync();
948         CheckHalfDayMissions();
949         return;
950     }
951 
952     if (statusEventType == StatusEventType::SCREEN_ON || statusEventType == StatusEventType::DISCHARGING) {
953         CheckHalfDayMissions();
954         return;
955     }
956 
957     if (statusEventType == StatusEventType::THERMAL_LEVEL_CHANGED) {
958         MEDIA_INFO_LOG("Current temperature level is %{public}d", newTemperatureLevel_);
959         PowerEfficiencyManager::UpdateAlbumUpdateInterval(isDeviceTemperatureProper_);
960     }
961 }
962 
IsDelayTaskTimeOut()963 bool MedialibrarySubscriber::DelayTask::IsDelayTaskTimeOut()
964 {
965     std::unique_lock<std::mutex> lock(this->lock);
966     return !cv.wait_for(lock, std::chrono::milliseconds(DELAY_TASK_TIME), [this]() {
967         return !isTaskWaiting;
968     });
969 }
970 
EndBackgroundOperationThread()971 void MedialibrarySubscriber::DelayTask::EndBackgroundOperationThread()
972 {
973     {
974         std::unique_lock<std::mutex> lock(this->lock);
975         isTaskWaiting = false;
976         MEDIA_INFO_LOG("DelayTask %{public}s EndBackgroundOperationThread", taskName.c_str());
977     }
978 #ifdef META_RECOVERY_SUPPORT
979     MediaLibraryMetaRecovery::GetInstance().InterruptRecovery();
980 #endif
981     MovingPhotoProcessor::StopProcess();
982     cv.notify_all();
983     if (!operationThread.joinable()) {
984         return;
985     }
986     operationThread.join();
987 }
988 
SetOperationThread(std::function<void ()> operationTask)989 void MedialibrarySubscriber::DelayTask::SetOperationThread(std::function<void()> operationTask)
990 {
991     if (operationThread.joinable()) {
992         operationThread.join();
993     }
994     {
995         std::unique_lock<std::mutex> lock(this->lock);
996         isTaskWaiting = true;
997     }
998     this->operationThread = std::thread(operationTask);
999 }
1000 
QueryThumbAstc(int32_t & thumbAstcCount)1001 int32_t MedialibrarySubscriberDatabaseUtils::QueryThumbAstc(int32_t& thumbAstcCount)
1002 {
1003     std::vector<std::string> columns = { "count(1) AS count" };
1004     std::string queryColumn = "count";
1005     NativeRdb::RdbPredicates astcPredicates(PhotoColumn::PHOTOS_TABLE);
1006     astcPredicates.GreaterThanOrEqualTo(PhotoColumn::PHOTO_THUMBNAIL_READY,
1007         static_cast<int32_t>(ThumbnailReady::GENERATE_THUMB_RETRY));
1008     int32_t errCode = QueryInt(astcPredicates, columns, queryColumn, thumbAstcCount);
1009     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Query thumbAstcCount fail: %{public}d", errCode);
1010     return E_OK;
1011 }
1012 
QueryThumbTotal(int32_t & thumbTotalCount)1013 int32_t MedialibrarySubscriberDatabaseUtils::QueryThumbTotal(int32_t& thumbTotalCount)
1014 {
1015     std::vector<std::string> columns = { "count(1) AS count" };
1016     std::string queryColumn = "count";
1017     NativeRdb::RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
1018     int32_t errCode = QueryInt(predicates, columns, queryColumn, thumbTotalCount);
1019     CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Query thumbTotalCount fail: %{public}d", errCode);
1020     return E_OK;
1021 }
1022 
QueryInt(const NativeRdb::AbsRdbPredicates & predicates,const std::vector<std::string> & columns,const std::string & queryColumn,int32_t & value)1023 int32_t MedialibrarySubscriberDatabaseUtils::QueryInt(const NativeRdb::AbsRdbPredicates &predicates,
1024     const std::vector<std::string> &columns, const std::string &queryColumn, int32_t &value)
1025 {
1026     auto resultSet = MediaLibraryRdbStore::QueryWithFilter(predicates, columns);
1027     bool cond = (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK);
1028     CHECK_AND_RETURN_RET(!cond, E_DB_FAIL);
1029     value = GetInt32Val(queryColumn, resultSet);
1030     return E_OK;
1031 }
1032 }  // namespace Media
1033 }  // namespace OHOS
1034