1 /*
2 * Copyright (c) 2025 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 "medialibrary_restore.h"
20 #include "media_column.h"
21 #include "media_file_utils.h"
22 #include "media_log.h"
23
24 #include "medialibrary_errno.h"
25 #include "file_ex.h"
26 #include <nlohmann/json.hpp>
27 #include <memory>
28
29 using namespace OHOS::AAFwk;
30 using namespace std;
31 namespace OHOS {
32 namespace Media {
33 const int32_t SECONDS_TO_MS = 1000;
34 const int32_t MS_OF_ONE_DAY = 24 * 60 * 60 * 1000;
35 const static std::string DATA_CLONE_DESCRIPTION_JSON_FILE_NAME = "/dataclone_description.json";
36 const static std::string CLONE_TIME_STAMP = "cloneTimestamp";
37 const static std::string CLONE_FOLDER_PATH = PhotoColumn::FILES_LOCAL_DIR + ".backup/clone";
38 const static std::string RESTORE_FOLDER_PATH = PhotoColumn::FILES_LOCAL_DIR + ".backup/restore";
39
ClearContinueCloneData(AsyncTaskData * data)40 void MedialibrarySubscriber::ClearContinueCloneData(AsyncTaskData *data)
41 {
42 bool clearCloneFolder = MediaFileUtils::DeleteDir(CLONE_FOLDER_PATH);
43 bool clearRestoreFolder = MediaFileUtils::DeleteDir(RESTORE_FOLDER_PATH);
44 MEDIA_INFO_LOG("ClearContinueCloneData success clearCloneFolder:%{public}d clearRestoreFolder:%{public}d",
45 clearCloneFolder, clearRestoreFolder);
46 }
47
DoClearContinueCloneData()48 int32_t MedialibrarySubscriber::DoClearContinueCloneData()
49 {
50 auto asyncWorker = MediaLibraryAsyncWorker::GetInstance();
51 CHECK_AND_RETURN_RET_LOG(asyncWorker != nullptr, E_FAIL,
52 "Failed to get async worker instance!");
53 shared_ptr<MediaLibraryAsyncTask> clearContinueCloneTask =
54 make_shared<MediaLibraryAsyncTask>(ClearContinueCloneData, nullptr);
55 CHECK_AND_RETURN_RET_LOG(clearContinueCloneTask != nullptr, E_FAIL,
56 "Failed to create async task for clearContinueCloneTask !");
57 asyncWorker->AddTask(clearContinueCloneTask, false);
58 return E_SUCCESS;
59 }
60
IsClearContinueCloneData(const std::string & path)61 bool MedialibrarySubscriber::IsClearContinueCloneData(const std::string &path)
62 {
63 int64_t cloneTimestamp = MediaFileUtils::GetFileModificationTime(path) * SECONDS_TO_MS;
64 bool isCloneTimestampExist = MedialibrarySubscriber::GetCloneTimestamp(path, cloneTimestamp);
65 if (!isCloneTimestampExist) {
66 cloneTimestamp = MediaFileUtils::GetFileModificationTime(path) * SECONDS_TO_MS;
67 }
68 MEDIA_INFO_LOG("IsClearContinueCloneData fileModificationTime:%{public}" PRId64, cloneTimestamp);
69 int64_t curTime = MediaFileUtils::UTCTimeMilliSeconds();
70 return curTime - cloneTimestamp > MS_OF_ONE_DAY;
71 }
72
TryClearContinueCloneData()73 bool MedialibrarySubscriber::TryClearContinueCloneData()
74 {
75 bool isDirExists =
76 MediaFileUtils::IsDirExists(CLONE_FOLDER_PATH) || MediaFileUtils::IsDirExists(RESTORE_FOLDER_PATH);
77 CHECK_AND_RETURN_RET_LOG(isDirExists, false, "clone foler not exist, return");
78 std::string path = GetDataCloneDescriptionJsonPath();
79 MEDIA_INFO_LOG("GetDataCloneDescriptionJsonPath: %{public}s", MediaFileUtils::DesensitizePath(path).c_str());
80 if (!MediaFileUtils::IsFileExists(path)) {
81 int32_t ret = DoClearContinueCloneData();
82 CHECK_AND_RETURN_RET_LOG(ret == E_SUCCESS, false, "DoUpdateDirtyForCloudClone failed");
83 return true;
84 }
85 CHECK_AND_RETURN_RET_LOG(IsClearContinueCloneData(path), false, "not clean continue clone data");
86 int32_t taskRet = DoClearContinueCloneData();
87 CHECK_AND_RETURN_RET_LOG(taskRet == E_SUCCESS, false, "DoUpdateDirtyForCloudClone failed");
88 return true;
89 }
90
GetDataCloneDescriptionJsonPath()91 std::string MedialibrarySubscriber::GetDataCloneDescriptionJsonPath()
92 {
93 std::string restorePath = RESTORE_FOLDER_PATH + DATA_CLONE_DESCRIPTION_JSON_FILE_NAME;
94 std::string clonePath = CLONE_FOLDER_PATH + DATA_CLONE_DESCRIPTION_JSON_FILE_NAME;
95 return MediaFileUtils::IsFileExists(restorePath) ? restorePath : clonePath;
96 }
97
GetCloneTimestamp(const std::string & path,int64_t & cloneTimestamp)98 bool MedialibrarySubscriber::GetCloneTimestamp(const std::string &path, int64_t &cloneTimestamp)
99 {
100 std::string content = "";
101 bool isContentExist = LoadStringFromFile(path, content) && !content.empty();
102 CHECK_AND_RETURN_RET_LOG(isContentExist, false, "file is empty %{private}s", path.c_str());
103 nlohmann::json jsonArray = nlohmann::json::parse(content, nullptr, false);
104 CHECK_AND_RETURN_RET_LOG(!jsonArray.is_discarded(), false, "json array is empty ");
105 for (auto &[key, value] : jsonArray.items()) {
106 if (key == CLONE_TIME_STAMP && value.is_number_integer()) {
107 cloneTimestamp = value.get<int64_t>();
108 return true;
109 }
110 }
111 return false;
112 }
113 } // namespace Media
114 } // namespace OHOS
115