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