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
36 #include "want.h"
37 #include "post_event_utils.h"
38 #ifdef HAS_POWER_MANAGER_PART
39 #include "power_mgr_client.h"
40 #endif
41 #ifdef HAS_THERMAL_MANAGER_PART
42 #include "thermal_mgr_client.h"
43 #endif
44
45 #include "medialibrary_album_fusion_utils.h"
46 #include "medialibrary_bundle_manager.h"
47 #include "medialibrary_data_manager.h"
48 #include "medialibrary_errno.h"
49 #include "medialibrary_inotify.h"
50 #include "medialibrary_restore.h"
51 #include "media_file_utils.h"
52 #include "media_log.h"
53 #include "media_scanner_manager.h"
54 #include "application_context.h"
55 #include "ability_manager_client.h"
56 #include "resource_type.h"
57 #include "dfx_manager.h"
58 #include "medialibrary_unistore_manager.h"
59 #include "medialibrary_rdb_utils.h"
60 #include "moving_photo_processor.h"
61 #include "permission_utils.h"
62 #include "thumbnail_generate_worker_manager.h"
63 #include "parameters.h"
64
65 #ifdef HAS_WIFI_MANAGER_PART
66 #include "wifi_device.h"
67 #endif
68 #include "power_efficiency_manager.h"
69 #include "photo_album_lpath_operation.h"
70
71 using namespace OHOS::AAFwk;
72
73 namespace OHOS {
74 namespace Media {
75 // The task can be performed when the battery level reaches the value
76 const int32_t PROPER_DEVICE_BATTERY_CAPACITY = 50;
77
78 // The task can be performed only when the temperature of the device is lower than the value
79 const int32_t PROPER_DEVICE_TEMPERATURE_LEVEL = 1;
80 const int32_t PROPER_DEVICE_TEMPERATURE_LEVEL_HOT = 3;
81
82 // WIFI should be available in this state
83 const int32_t WIFI_STATE_CONNECTED = 4;
84
85 const int32_t DELAY_TASK_TIME = 30000;
86 const int32_t COMMON_EVENT_KEY_GET_DEFAULT_PARAM = -1;
87 const int32_t MegaByte = 1024 * 1024;
88 const int32_t MAX_FILE_SIZE_MB = 200;
89 const std::string COMMON_EVENT_KEY_BATTERY_CAPACITY = "soc";
90 const std::string COMMON_EVENT_KEY_DEVICE_TEMPERATURE = "0";
91 const std::string KEY_HIVIEW_VERSION_TYPE = "const.logsystem.versiontype";
92
93 // The network should be available in this state
94 const int32_t NET_CONN_STATE_CONNECTED = 3;
95 // The net bearer type is in net_all_capabilities.h
96 const int32_t BEARER_CELLULAR = 0;
97 bool MedialibrarySubscriber::isCellularNetConnected_ = false;
98 bool MedialibrarySubscriber::isWifiConnected_ = false;
99 bool MedialibrarySubscriber::currentStatus_ = false;
100
101 const std::vector<std::string> MedialibrarySubscriber::events_ = {
102 EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING,
103 EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING,
104 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF,
105 EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON,
106 EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED,
107 EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED,
108 EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED,
109 EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE,
110 EventFwk::CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE
111 };
112
113 const std::map<std::string, StatusEventType> BACKGROUND_OPERATION_STATUS_MAP = {
114 {EventFwk::CommonEventSupport::COMMON_EVENT_CHARGING, StatusEventType::CHARGING},
115 {EventFwk::CommonEventSupport::COMMON_EVENT_DISCHARGING, StatusEventType::DISCHARGING},
116 {EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF, StatusEventType::SCREEN_OFF},
117 {EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON, StatusEventType::SCREEN_ON},
118 {EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED, StatusEventType::BATTERY_CHANGED},
119 {EventFwk::CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED, StatusEventType::THERMAL_LEVEL_CHANGED},
120 };
121
MedialibrarySubscriber(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)122 MedialibrarySubscriber::MedialibrarySubscriber(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
123 : EventFwk::CommonEventSubscriber(subscriberInfo)
124 {
125 #ifdef HAS_POWER_MANAGER_PART
126 auto& powerMgrClient = PowerMgr::PowerMgrClient::GetInstance();
127 isScreenOff_ = !powerMgrClient.IsScreenOn();
128 #endif
129 #ifdef HAS_BATTERY_MANAGER_PART
130 auto& batteryClient = PowerMgr::BatterySrvClient::GetInstance();
131 auto chargeState = batteryClient.GetChargingStatus();
132 isCharging_ = (chargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_ENABLE) ||
133 (chargeState == PowerMgr::BatteryChargeState::CHARGE_STATE_FULL);
134 isPowerSufficient_ = batteryClient.GetCapacity() >= PROPER_DEVICE_BATTERY_CAPACITY;
135 #endif
136 #ifdef HAS_THERMAL_MANAGER_PART
137 auto& thermalMgrClient = PowerMgr::ThermalMgrClient::GetInstance();
138 newTemperatureLevel_ = static_cast<int32_t>(thermalMgrClient.GetThermalLevel());
139 isDeviceTemperatureProper_ = newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL;
140 #endif
141 #ifdef HAS_WIFI_MANAGER_PART
142 auto wifiDevicePtr = Wifi::WifiDevice::GetInstance(WIFI_DEVICE_ABILITY_ID);
143 if (wifiDevicePtr == nullptr) {
144 MEDIA_ERR_LOG("MedialibrarySubscriber wifiDevicePtr is null");
145 } else {
146 ErrCode ret = wifiDevicePtr->IsConnected(isWifiConnected_);
147 if (ret != Wifi::WIFI_OPT_SUCCESS) {
148 MEDIA_ERR_LOG("MedialibrarySubscriber Get-IsConnected-fail: -%{public}d", ret);
149 }
150 }
151 #endif
152 MEDIA_DEBUG_LOG("MedialibrarySubscriber current status:%{public}d, %{public}d, %{public}d, %{public}d, %{public}d",
153 isScreenOff_, isCharging_, isPowerSufficient_, isDeviceTemperatureProper_, isWifiConnected_);
154 }
155
~MedialibrarySubscriber()156 MedialibrarySubscriber::~MedialibrarySubscriber()
157 {
158 EndBackgroundOperationThread();
159 }
160
Subscribe(void)161 bool MedialibrarySubscriber::Subscribe(void)
162 {
163 EventFwk::MatchingSkills matchingSkills;
164 for (auto event : events_) {
165 matchingSkills.AddEvent(event);
166 }
167 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
168
169 std::shared_ptr<MedialibrarySubscriber> subscriber = std::make_shared<MedialibrarySubscriber>(subscribeInfo);
170 return EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber);
171 }
172
IsBetaVersion()173 static bool IsBetaVersion()
174 {
175 static const string versionType = system::GetParameter(KEY_HIVIEW_VERSION_TYPE, "unknown");
176 static bool isBetaVersion = versionType.find("beta") != std::string::npos;
177 return isBetaVersion;
178 }
179
UploadDBFile()180 static void UploadDBFile()
181 {
182 int64_t begin = MediaFileUtils::UTCTimeMilliSeconds();
183 static const std::string databaseDir = MEDIA_DB_DIR + "/rdb";
184 static const std::vector<std::string> dbFileName = { "/media_library.db",
185 "/media_library.db-shm",
186 "/media_library.db-wal" };
187 static const std::string destPath = "/data/storage/el2/log/logpack";
188 int64_t totalFileSize = 0;
189 for (auto &dbName : dbFileName) {
190 string dbPath = databaseDir + dbName;
191 struct stat statInfo {};
192 if (stat(dbPath.c_str(), &statInfo) != 0) {
193 continue;
194 }
195 totalFileSize += statInfo.st_size;
196 }
197 totalFileSize /= MegaByte; // Convert bytes to MB
198 if (totalFileSize > MAX_FILE_SIZE_MB) {
199 MEDIA_WARN_LOG("DB file over 200MB are not uploaded, totalFileSize is %{public}ld MB",
200 static_cast<long>(totalFileSize));
201 return ;
202 }
203 if (!MediaFileUtils::IsFileExists(destPath) && !MediaFileUtils::CreateDirectory(destPath)) {
204 MEDIA_ERR_LOG("Create dir failed, dir=%{private}s", destPath.c_str());
205 return ;
206 }
207 auto dataManager = MediaLibraryDataManager::GetInstance();
208 if (dataManager == nullptr) {
209 MEDIA_ERR_LOG("dataManager is nullptr");
210 return;
211 }
212 dataManager->UploadDBFileInner();
213 int64_t end = MediaFileUtils::UTCTimeMilliSeconds();
214 MEDIA_INFO_LOG("Handle %{public}ld MB DBFile success, cost %{public}ld ms", static_cast<long>(totalFileSize),
215 static_cast<long>(end - begin));
216 }
217
CheckHalfDayMissions()218 void MedialibrarySubscriber::CheckHalfDayMissions()
219 {
220 if (isScreenOff_ && isCharging_) {
221 if (IsBetaVersion()) {
222 MEDIA_INFO_LOG("Version is BetaVersion, UploadDBFile");
223 UploadDBFile();
224 }
225 DfxManager::GetInstance()->HandleHalfDayMissions();
226 MediaLibraryRestore::GetInstance().CheckBackup();
227 }
228 if (!isScreenOff_ || !isCharging_) {
229 MediaLibraryRestore::GetInstance().InterruptBackup();
230 }
231 }
232
UpdateCurrentStatus()233 void MedialibrarySubscriber::UpdateCurrentStatus()
234 {
235 std::lock_guard<std::mutex> lock(mutex_);
236 if (deviceTemperatureLevel_ != newTemperatureLevel_) {
237 deviceTemperatureLevel_ = newTemperatureLevel_;
238 ThumbnailService::GetInstance()->NotifyTempStatusForReady(deviceTemperatureLevel_);
239 }
240 bool newStatus = isScreenOff_ && isCharging_ && isPowerSufficient_ && isDeviceTemperatureProper_;
241 if (currentStatus_ == newStatus) {
242 return;
243 }
244
245 MEDIA_INFO_LOG("update status current:%{public}d, new:%{public}d, %{public}d, %{public}d, %{public}d, %{public}d",
246 currentStatus_, newStatus, isScreenOff_, isCharging_, isPowerSufficient_, isDeviceTemperatureProper_);
247 PowerEfficiencyManager::SetSubscriberStatus(isCharging_, isScreenOff_);
248
249 currentStatus_ = newStatus;
250 ThumbnailService::GetInstance()->UpdateCurrentStatusForTask(newStatus);
251 EndBackgroundOperationThread();
252 if (currentStatus_) {
253 isTaskWaiting_ = true;
254 backgroundOperationThread_ = std::thread([this] { this->DoBackgroundOperation(); });
255 } else {
256 StopBackgroundOperation();
257 }
258 }
259
WalCheckPointAsync()260 void MedialibrarySubscriber::WalCheckPointAsync()
261 {
262 if (!isScreenOff_ || !isCharging_) {
263 return;
264 }
265 std::thread(MediaLibraryRdbStore::WalCheckPoint).detach();
266 }
267
UpdateBackgroundOperationStatus(const AAFwk::Want & want,const StatusEventType statusEventType)268 void MedialibrarySubscriber::UpdateBackgroundOperationStatus(
269 const AAFwk::Want &want, const StatusEventType statusEventType)
270 {
271 switch (statusEventType) {
272 case StatusEventType::SCREEN_OFF:
273 isScreenOff_ = true;
274 CheckHalfDayMissions();
275 WalCheckPointAsync();
276 break;
277 case StatusEventType::SCREEN_ON:
278 isScreenOff_ = false;
279 CheckHalfDayMissions();
280 break;
281 case StatusEventType::CHARGING:
282 isCharging_ = true;
283 CheckHalfDayMissions();
284 WalCheckPointAsync();
285 break;
286 case StatusEventType::DISCHARGING:
287 isCharging_ = false;
288 CheckHalfDayMissions();
289 break;
290 case StatusEventType::BATTERY_CHANGED:
291 isPowerSufficient_ = want.GetIntParam(COMMON_EVENT_KEY_BATTERY_CAPACITY,
292 COMMON_EVENT_KEY_GET_DEFAULT_PARAM) >= PROPER_DEVICE_BATTERY_CAPACITY;
293 break;
294 case StatusEventType::THERMAL_LEVEL_CHANGED: {
295 newTemperatureLevel_ = want.GetIntParam(COMMON_EVENT_KEY_DEVICE_TEMPERATURE,
296 COMMON_EVENT_KEY_GET_DEFAULT_PARAM);
297 isDeviceTemperatureProper_ = newTemperatureLevel_ <= PROPER_DEVICE_TEMPERATURE_LEVEL;
298 PowerEfficiencyManager::UpdateAlbumUpdateInterval(isDeviceTemperatureProper_);
299 break;
300 }
301 default:
302 MEDIA_WARN_LOG("StatusEventType:%{public}d is not invalid", statusEventType);
303 return;
304 }
305
306 UpdateCurrentStatus();
307 UpdateBackgroundTimer();
308 }
309
UpdateCloudMediaAssetDownloadStatus(const AAFwk::Want & want,const StatusEventType statusEventType)310 void MedialibrarySubscriber::UpdateCloudMediaAssetDownloadStatus(const AAFwk::Want &want,
311 const StatusEventType statusEventType)
312 {
313 if (statusEventType != StatusEventType::THERMAL_LEVEL_CHANGED) {
314 return;
315 }
316 int32_t taskStatus = CloudMediaAssetManager::GetInstance().GetTaskStatus();
317 int32_t downloadType = CloudMediaAssetManager::GetInstance().GetDownloadType();
318 bool foregroundTemperature = want.GetIntParam(COMMON_EVENT_KEY_DEVICE_TEMPERATURE,
319 COMMON_EVENT_KEY_GET_DEFAULT_PARAM) <= PROPER_DEVICE_TEMPERATURE_LEVEL_HOT;
320 if (!foregroundTemperature && downloadType == static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_FORCE)) {
321 CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::TEMPERATURE_LIMIT);
322 return;
323 }
324 if (foregroundTemperature && taskStatus == static_cast<int32_t>(CloudMediaAssetTaskStatus::PAUSED)) {
325 CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(
326 CloudMediaTaskRecoverCause::FOREGROUND_TEMPERATURE_PROPER);
327 }
328 }
329
IsCellularNetConnected()330 bool MedialibrarySubscriber::IsCellularNetConnected()
331 {
332 return isCellularNetConnected_;
333 }
334
IsWifiConnected()335 bool MedialibrarySubscriber::IsWifiConnected()
336 {
337 return isWifiConnected_;
338 }
339
IsCurrentStatusOn()340 bool MedialibrarySubscriber::IsCurrentStatusOn()
341 {
342 return currentStatus_;
343 }
344
UpdateCloudMediaAssetDownloadTaskStatus()345 void MedialibrarySubscriber::UpdateCloudMediaAssetDownloadTaskStatus()
346 {
347 if (!isCellularNetConnected_) {
348 MEDIA_INFO_LOG("CellularNet not connected.");
349 int32_t taskStatus = CloudMediaAssetManager::GetInstance().GetTaskStatus();
350 if (taskStatus == static_cast<int32_t>(CloudMediaAssetTaskStatus::PAUSED)) {
351 CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::NETWORK_FLOW_LIMIT);
352 }
353 return;
354 }
355 if (CloudSyncUtils::IsUnlimitedTrafficStatusOn()) {
356 CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(CloudMediaTaskRecoverCause::NETWORK_NORMAL);
357 } else if (!isWifiConnected_) {
358 CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(CloudMediaTaskPauseCause::WIFI_UNAVAILABLE);
359 }
360 }
361
OnReceiveEvent(const EventFwk::CommonEventData & eventData)362 void MedialibrarySubscriber::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
363 {
364 const AAFwk::Want &want = eventData.GetWant();
365 std::string action = want.GetAction();
366 if (action != EventFwk::CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED) {
367 MEDIA_INFO_LOG("OnReceiveEvent action:%{public}s.", action.c_str());
368 }
369 if (action == EventFwk::CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE) {
370 isWifiConnected_ = eventData.GetCode() == WIFI_STATE_CONNECTED;
371 UpdateBackgroundTimer();
372 if (isWifiConnected_) {
373 CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(CloudMediaTaskRecoverCause::NETWORK_NORMAL);
374 }
375 } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_CONNECTIVITY_CHANGE) {
376 int netType = want.GetIntParam("NetType", -1);
377 bool cellularNetConnected = eventData.GetCode() == NET_CONN_STATE_CONNECTED;
378 isCellularNetConnected_ = netType == BEARER_CELLULAR ? cellularNetConnected : isCellularNetConnected_;
379 UpdateCloudMediaAssetDownloadTaskStatus();
380 } else if (BACKGROUND_OPERATION_STATUS_MAP.count(action) != 0) {
381 UpdateBackgroundOperationStatus(want, BACKGROUND_OPERATION_STATUS_MAP.at(action));
382 UpdateCloudMediaAssetDownloadStatus(want, BACKGROUND_OPERATION_STATUS_MAP.at(action));
383 } else if (action.compare(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) == 0) {
384 string packageName = want.GetElement().GetBundleName();
385 RevertPendingByPackage(packageName);
386 MediaLibraryBundleManager::GetInstance()->Clear();
387 PermissionUtils::ClearBundleInfoInCache();
388 }
389 }
390
GetNowTime()391 int64_t MedialibrarySubscriber::GetNowTime()
392 {
393 struct timespec t;
394 constexpr int64_t SEC_TO_MSEC = 1e3;
395 constexpr int64_t MSEC_TO_NSEC = 1e6;
396 clock_gettime(CLOCK_REALTIME, &t);
397 return t.tv_sec * SEC_TO_MSEC + t.tv_nsec / MSEC_TO_NSEC;
398 }
399
Init()400 void MedialibrarySubscriber::Init()
401 {
402 lockTime_ = GetNowTime();
403 agingCount_ = 0;
404 }
405
DeleteTemporaryPhotos()406 void DeleteTemporaryPhotos()
407 {
408 auto dataManager = MediaLibraryDataManager::GetInstance();
409 if (dataManager == nullptr) {
410 return;
411 }
412
413 string UriString = PAH_DISCARD_CAMERA_PHOTO;
414 MediaFileUtils::UriAppendKeyValue(UriString, URI_PARAM_API_VERSION, to_string(MEDIA_API_VERSION_V10));
415 Uri uri(UriString);
416 MediaLibraryCommand cmd(uri);
417 DataShare::DataShareValuesBucket valuesBucket;
418 valuesBucket.Put(PhotoColumn::PHOTO_IS_TEMP, true);
419 DataShare::DataSharePredicates predicates;
420
421 // 24H之前的数据
422 int64_t current = MediaFileUtils::UTCTimeMilliSeconds();
423 int64_t timeBefore24Hours = current - 24 * 60 * 60 * 1000;
424 string where = PhotoColumn::PHOTO_IS_TEMP + " = 1 AND (" + PhotoColumn::MEDIA_DATE_ADDED + " <= " +
425 to_string(timeBefore24Hours) + " OR " + MediaColumn::MEDIA_ID + " NOT IN (SELECT " + MediaColumn::MEDIA_ID +
426 " FROM (SELECT " + MediaColumn::MEDIA_ID + " FROM " + PhotoColumn::PHOTOS_TABLE + " WHERE " +
427 PhotoColumn::PHOTO_IS_TEMP + " = 1 " + "ORDER BY " + MediaColumn::MEDIA_ID +
428 " DESC LIMIT 50)) AND (select COUNT(1) from " + PhotoColumn::PHOTOS_TABLE +
429 " where " + PhotoColumn::PHOTO_IS_TEMP + " = 1) > 100) ";
430 predicates.SetWhereClause(where);
431
432 auto changedRows = dataManager->Update(cmd, valuesBucket, predicates);
433 if (changedRows < 0) {
434 MEDIA_INFO_LOG("Failed to update property of asset, err: %{public}d", changedRows);
435 return;
436 }
437 MEDIA_INFO_LOG("delete %{public}d temp files exceeding 24 hous or exceed maximum quantity.", changedRows);
438 }
439
DoThumbnailOperation()440 void MedialibrarySubscriber::DoThumbnailOperation()
441 {
442 auto dataManager = MediaLibraryDataManager::GetInstance();
443 if (dataManager == nullptr) {
444 return;
445 }
446
447 auto result = dataManager->GenerateThumbnailBackground();
448 if (result != E_OK) {
449 MEDIA_ERR_LOG("GenerateThumbnailBackground faild");
450 }
451
452 result = dataManager->UpgradeThumbnailBackground(isWifiConnected_);
453 if (result != E_OK) {
454 MEDIA_ERR_LOG("UpgradeThumbnailBackground faild");
455 }
456
457 result = dataManager->DoAging();
458 if (result != E_OK) {
459 MEDIA_ERR_LOG("DoAging faild");
460 }
461
462 shared_ptr<int> trashCountPtr = make_shared<int>();
463 result = dataManager->DoTrashAging(trashCountPtr);
464 if (result != E_OK) {
465 MEDIA_ERR_LOG("DoTrashAging faild");
466 }
467 VariantMap map = {{KEY_COUNT, *trashCountPtr}};
468 PostEventUtils::GetInstance().PostStatProcess(StatType::AGING_STAT, map);
469 }
470
QueryBurstNeedUpdate(AsyncTaskData * data)471 static void QueryBurstNeedUpdate(AsyncTaskData *data)
472 {
473 auto dataManager = MediaLibraryDataManager::GetInstance();
474 if (dataManager == nullptr) {
475 return;
476 }
477
478 int32_t result = dataManager->UpdateBurstFromGallery();
479 if (result != E_OK) {
480 MEDIA_ERR_LOG("UpdateBurstFromGallery faild");
481 }
482 }
483
DoUpdateBurstFromGallery()484 static int32_t DoUpdateBurstFromGallery()
485 {
486 MEDIA_INFO_LOG("Begin DoUpdateBurstFromGallery");
487 auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
488 if (asyncWorker == nullptr) {
489 MEDIA_ERR_LOG("Failed to get async worker instance!");
490 return E_FAIL;
491 }
492 shared_ptr<MediaLibraryAsyncTask> updateBurstTask =
493 make_shared<MediaLibraryAsyncTask>(QueryBurstNeedUpdate, nullptr);
494 if (updateBurstTask != nullptr) {
495 asyncWorker->AddTask(updateBurstTask, false);
496 } else {
497 MEDIA_ERR_LOG("Failed to create async task for updateBurstTask!");
498 return E_FAIL;
499 }
500 return E_SUCCESS;
501 }
502
UpdateDateTakenWhenZero(AsyncTaskData * data)503 static void UpdateDateTakenWhenZero(AsyncTaskData *data)
504 {
505 auto dataManager = MediaLibraryDataManager::GetInstance();
506 if (dataManager == nullptr) {
507 MEDIA_ERR_LOG("Failed to MediaLibraryDataManager instance!");
508 return;
509 }
510
511 int32_t result = dataManager->UpdateDateTakenWhenZero();
512 if (result != E_OK) {
513 MEDIA_ERR_LOG("UpdateDateTakenWhenZero faild, result = %{public}d", result);
514 }
515 }
516
DoUpdateDateTakenWhenZero()517 static int32_t DoUpdateDateTakenWhenZero()
518 {
519 MEDIA_DEBUG_LOG("Begin DoUpdateDateTakenWhenZero");
520 auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
521 if (asyncWorker == nullptr) {
522 MEDIA_ERR_LOG("Failed to get async worker instance!");
523 return E_FAIL;
524 }
525 shared_ptr<MediaLibraryAsyncTask> UpdateDateTakenWhenZeroTask =
526 make_shared<MediaLibraryAsyncTask>(UpdateDateTakenWhenZero, nullptr);
527 if (UpdateDateTakenWhenZeroTask != nullptr) {
528 asyncWorker->AddTask(UpdateDateTakenWhenZeroTask, false);
529 } else {
530 MEDIA_ERR_LOG("Failed to create async task for UpdateDateTakenWhenZeroTask !");
531 return E_FAIL;
532 }
533 return E_SUCCESS;
534 }
535
RecoverBackgroundDownloadCloudMediaAsset()536 static void RecoverBackgroundDownloadCloudMediaAsset()
537 {
538 if (!CloudMediaAssetManager::GetInstance().SetBgDownloadPermission(true)) {
539 return;
540 }
541 int32_t ret = CloudMediaAssetManager::GetInstance().RecoverDownloadCloudAsset(
542 CloudMediaTaskRecoverCause::BACKGROUND_TASK_AVAILABLE);
543 if (ret != E_OK) {
544 MEDIA_ERR_LOG("RecoverDownloadCloudAsset faild");
545 }
546 }
547
UpdateBurstCoverLevelFromGallery(AsyncTaskData * data)548 static void UpdateBurstCoverLevelFromGallery(AsyncTaskData *data)
549 {
550 auto dataManager = MediaLibraryDataManager::GetInstance();
551 if (dataManager == nullptr) {
552 return;
553 }
554
555 int32_t result = dataManager->UpdateBurstCoverLevelFromGallery();
556 if (result != E_OK) {
557 MEDIA_ERR_LOG("UpdateBurstCoverLevelFromGallery faild");
558 }
559 }
560
DoUpdateBurstCoverLevelFromGallery()561 static int32_t DoUpdateBurstCoverLevelFromGallery()
562 {
563 MEDIA_INFO_LOG("Begin DoUpdateBurstCoverLevelFromGallery");
564 auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
565 if (asyncWorker == nullptr) {
566 MEDIA_ERR_LOG("Failed to get async worker instance!");
567 return E_FAIL;
568 }
569 shared_ptr<MediaLibraryAsyncTask> updateBurstCoverLevelTask =
570 make_shared<MediaLibraryAsyncTask>(UpdateBurstCoverLevelFromGallery, nullptr);
571 if (updateBurstCoverLevelTask != nullptr) {
572 asyncWorker->AddTask(updateBurstCoverLevelTask, false);
573 } else {
574 MEDIA_ERR_LOG("Failed to create async task for updateBurstCoverLevelTask!");
575 return E_FAIL;
576 }
577 return E_SUCCESS;
578 }
579
DoBackgroundOperation()580 void MedialibrarySubscriber::DoBackgroundOperation()
581 {
582 if (!IsDelayTaskTimeOut() || !currentStatus_) {
583 MEDIA_INFO_LOG("The conditions for DoBackgroundOperation are not met, will return.");
584 return;
585 }
586
587 // delete temporary photos
588 DeleteTemporaryPhotos();
589
590 BackgroundTaskMgr::EfficiencyResourceInfo resourceInfo = BackgroundTaskMgr::EfficiencyResourceInfo(
591 BackgroundTaskMgr::ResourceType::CPU, true, 0, "apply", true, true);
592 BackgroundTaskMgr::BackgroundTaskMgrHelper::ApplyEfficiencyResources(resourceInfo);
593 Init();
594 DoThumbnailOperation();
595 // update burst from gallery
596 int32_t ret = DoUpdateBurstFromGallery();
597 if (ret != E_OK) {
598 MEDIA_ERR_LOG("DoUpdateBurstFromGallery faild");
599 }
600 CloudUploadChecker::HandleNoOriginPhoto();
601 ret = DoUpdateDateTakenWhenZero();
602 if (ret != E_OK) {
603 MEDIA_ERR_LOG("DoUpdateDateTakenWhenZero faild");
604 }
605 ret = DoUpdateBurstCoverLevelFromGallery();
606 CHECK_AND_PRINT_LOG(ret == E_OK, "DoUpdateBurstCoverLevelFromGallery faild");
607 RecoverBackgroundDownloadCloudMediaAsset();
608 CloudMediaAssetManager::GetInstance().StartDeleteCloudMediaAssets();
609 // compat old-version moving photo
610 MovingPhotoProcessor::StartProcess();
611 MediaLibraryAlbumFusionUtils::CleanInvalidCloudAlbumAndData();
612 auto watch = MediaLibraryInotify::GetInstance();
613 if (watch != nullptr) {
614 watch->DoAging();
615 }
616 }
617
PauseBackgroundDownloadCloudMedia()618 static void PauseBackgroundDownloadCloudMedia()
619 {
620 if (!CloudMediaAssetManager::GetInstance().SetBgDownloadPermission(false)) {
621 return;
622 }
623 int32_t taskStatus = static_cast<int32_t>(CloudMediaAssetTaskStatus::DOWNLOADING);
624 int32_t downloadType = static_cast<int32_t>(CloudMediaDownloadType::DOWNLOAD_GENTLE);
625 if (CloudMediaAssetManager::GetInstance().GetTaskStatus() == taskStatus &&
626 CloudMediaAssetManager::GetInstance().GetDownloadType() == downloadType) {
627 CloudMediaAssetManager::GetInstance().PauseDownloadCloudAsset(
628 CloudMediaTaskPauseCause::BACKGROUND_TASK_UNAVAILABLE);
629 }
630 }
631
StopBackgroundOperation()632 void MedialibrarySubscriber::StopBackgroundOperation()
633 {
634 MovingPhotoProcessor::StopProcess();
635 MediaLibraryDataManager::GetInstance()->InterruptBgworker();
636 PhotoAlbumLPathOperation::GetInstance().Stop();
637 PauseBackgroundDownloadCloudMedia();
638 CloudMediaAssetManager::GetInstance().StopDeleteCloudMediaAssets();
639 }
640
641 #ifdef MEDIALIBRARY_MTP_ENABLE
DoStartMtpService()642 void MedialibrarySubscriber::DoStartMtpService()
643 {
644 AAFwk::Want want;
645 want.SetElementName("com.ohos.medialibrary.medialibrarydata", "MtpService");
646 auto abilityContext = AbilityRuntime::Context::GetApplicationContext();
647 ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, abilityContext->GetToken(),
648 OHOS::AAFwk::DEFAULT_INVAL_VALUE);
649 MEDIA_INFO_LOG("MedialibrarySubscriber::DoStartMtpService. End calling StartAbility. ret=%{public}d", err);
650 }
651 #endif
652
RevertPendingByPackage(const std::string & bundleName)653 void MedialibrarySubscriber::RevertPendingByPackage(const std::string &bundleName)
654 {
655 MediaLibraryDataManager::GetInstance()->RevertPendingByPackage(bundleName);
656 }
657
UpdateBackgroundTimer()658 void MedialibrarySubscriber::UpdateBackgroundTimer()
659 {
660 if (isCharging_ && isScreenOff_) {
661 CloudSyncDfxManager::GetInstance().RunDfx();
662 }
663
664 ThumbnailGenerateWorkerManager::GetInstance().TryCloseThumbnailWorkerTimer();
665
666 std::lock_guard<std::mutex> lock(mutex_);
667 bool newStatus = isScreenOff_ && isCharging_ && isPowerSufficient_ &&
668 isDeviceTemperatureProper_ && isWifiConnected_;
669 if (timerStatus_ == newStatus) {
670 return;
671 }
672
673 MEDIA_INFO_LOG("update timer status current:%{public}d, new:%{public}d, %{public}d, %{public}d, %{public}d, "
674 "%{public}d, %{public}d",
675 timerStatus_, newStatus, isScreenOff_, isCharging_, isPowerSufficient_, isDeviceTemperatureProper_,
676 isWifiConnected_);
677
678 timerStatus_ = newStatus;
679 if (timerStatus_) {
680 BackgroundCloudFileProcessor::StartTimer();
681 } else {
682 BackgroundCloudFileProcessor::StopTimer();
683 }
684 }
685
IsDelayTaskTimeOut()686 bool MedialibrarySubscriber::IsDelayTaskTimeOut()
687 {
688 std::unique_lock<std::mutex> lock(delayTaskLock_);
689 return !delayTaskCv_.wait_for(lock, std::chrono::milliseconds(DELAY_TASK_TIME), [this]() {
690 return !isTaskWaiting_;
691 });
692 }
693
EndBackgroundOperationThread()694 void MedialibrarySubscriber::EndBackgroundOperationThread()
695 {
696 {
697 std::unique_lock<std::mutex> lock(delayTaskLock_);
698 isTaskWaiting_ = false;
699 }
700 delayTaskCv_.notify_all();
701 if (!backgroundOperationThread_.joinable()) {
702 return;
703 }
704 backgroundOperationThread_.join();
705 }
706 } // namespace Media
707 } // namespace OHOS
708