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 "Thumbnail"
16 
17 #include "thumbnail_aging_helper.h"
18 
19 #include "medialibrary_errno.h"
20 #include "media_log.h"
21 #include "thumbnail_const.h"
22 
23 using namespace std;
24 using namespace OHOS::DistributedKv;
25 using namespace OHOS::NativeRdb;
26 
27 namespace OHOS {
28 namespace Media {
AgingLcd(AsyncTaskData * data)29 static void AgingLcd(AsyncTaskData *data)
30 {
31     if (data == nullptr) {
32         return;
33     }
34     AgingAsyncTaskData* taskData = static_cast<AgingAsyncTaskData*>(data);
35     int32_t err = ThumbnailAgingHelper::ClearLcdFromFileTable(taskData->opts);
36     if (err != E_OK) {
37         MEDIA_ERR_LOG("Failed to ClearLcdFormFileTable %{public}d", err);
38     }
39 }
40 
41 #ifdef DISTRIBUTED
AgingDistributeLcd(AsyncTaskData * data)42 static void AgingDistributeLcd(AsyncTaskData* data)
43 {
44     if (data == nullptr) {
45         return;
46     }
47     AgingAsyncTaskData* taskData = static_cast<AgingAsyncTaskData*>(data);
48     int32_t err = ThumbnailAgingHelper::ClearRemoteLcdFromFileTable(taskData->opts);
49     if (err != E_OK) {
50         MEDIA_ERR_LOG("Failed to ClearRemoteLcdFormFileTable %{public}d", err);
51     }
52 }
53 #endif
54 
55 #ifdef DISTRIBUTED
ClearThumbnailRecordTask(AsyncTaskData * data)56 static void ClearThumbnailRecordTask(AsyncTaskData* data)
57 {
58     if (data == nullptr) {
59         return;
60     }
61     AgingAsyncTaskData* taskData = static_cast<AgingAsyncTaskData*>(data);
62     int32_t err = ThumbnailAgingHelper::ClearKeyAndRecordFromMap(taskData->opts);
63     if (err != E_OK) {
64         MEDIA_ERR_LOG("Failed to ClearKeyAndRecordFromMap %{public}d", err);
65     }
66 }
67 #endif
68 
AgingLcdBatch(ThumbRdbOpt & opts)69 int32_t ThumbnailAgingHelper::AgingLcdBatch(ThumbRdbOpt &opts)
70 {
71     MEDIA_INFO_LOG("IN %{private}s", opts.table.c_str());
72     if (opts.store == nullptr) {
73         return E_HAS_DB_ERROR;
74     }
75 
76     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
77     if (asyncWorker == nullptr) {
78         return E_ERR;
79     }
80     AgingAsyncTaskData* taskData = new (std::nothrow)AgingAsyncTaskData();
81     if (taskData == nullptr) {
82         return E_ERR;
83     }
84     taskData->opts = opts;
85     shared_ptr<MediaLibraryAsyncTask> agingAsyncTask = make_shared<MediaLibraryAsyncTask>(AgingLcd, taskData);
86     if (agingAsyncTask != nullptr) {
87         asyncWorker->AddTask(agingAsyncTask, false);
88     }
89     return E_OK;
90 }
91 
GetAgingDataCount(const int64_t & time,const bool & before,ThumbRdbOpt & opts,int & count)92 int32_t ThumbnailAgingHelper::GetAgingDataCount(const int64_t &time, const bool &before, ThumbRdbOpt &opts, int &count)
93 {
94     int err = GetLcdCountByTime(time, before, opts, count);
95     if (err != E_OK) {
96         MEDIA_ERR_LOG("Failed to GetAgingDataCount %{public}d", err);
97         return err;
98     }
99     return E_OK;
100 }
101 
ClearLcdFromFileTable(ThumbRdbOpt & opts)102 int32_t ThumbnailAgingHelper::ClearLcdFromFileTable(ThumbRdbOpt &opts)
103 {
104     int lcdCount = 0;
105     int32_t err = GetLcdCount(opts, lcdCount);
106     if (err != E_OK) {
107         MEDIA_ERR_LOG("Failed to GetLcdCount %{public}d", err);
108         return err;
109     }
110     MEDIA_DEBUG_LOG("lcdCount %{public}d", lcdCount);
111     if (lcdCount <= THUMBNAIL_LCD_AGING_THRESHOLD) {
112         MEDIA_INFO_LOG("Not need aging Lcd. lcdCount: %{lcdCount}d", lcdCount);
113         return E_OK;
114     }
115     vector<ThumbnailData> infos;
116     err = GetAgingLcdData(opts, lcdCount - THUMBNAIL_LCD_AGING_THRESHOLD, infos);
117     if ((err != E_OK) || infos.empty()) {
118         MEDIA_ERR_LOG("Failed to GetAgingLcdData %{public}d", err);
119         return err;
120     }
121 
122     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
123     if (asyncWorker == nullptr) {
124         return E_ERR;
125     }
126     for (uint32_t i = 0; i < infos.size(); i++) {
127         opts.row = infos[i].id;
128         if (ThumbnailUtils::DeleteThumbFile(infos[i], ThumbnailType::LCD)) {
129             ThumbnailUtils::CleanThumbnailInfo(opts, false, true);
130         }
131     }
132 
133     return E_OK;
134 }
135 
136 #ifdef DISTRIBUTED
AgingDistributeLcdBatch(ThumbRdbOpt & opts)137 int32_t ThumbnailAgingHelper::AgingDistributeLcdBatch(ThumbRdbOpt &opts)
138 {
139     if (opts.store == nullptr) {
140         MEDIA_ERR_LOG("opts.store is not init");
141         return E_ERR;
142     }
143 
144     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
145     if (asyncWorker == nullptr) {
146         return E_ERR;
147     }
148     AgingAsyncTaskData* taskData = new AgingAsyncTaskData();
149     if (taskData == nullptr) {
150         return E_ERR;
151     }
152     taskData->opts = opts;
153     shared_ptr<MediaLibraryAsyncTask> agingAsyncTask = make_shared<MediaLibraryAsyncTask>(AgingDistributeLcd, taskData);
154     if (agingAsyncTask != nullptr) {
155         asyncWorker->AddTask(agingAsyncTask, false);
156     }
157     return E_OK;
158 }
159 
ClearRemoteLcdFromFileTable(ThumbRdbOpt & opts)160 int32_t ThumbnailAgingHelper::ClearRemoteLcdFromFileTable(ThumbRdbOpt &opts)
161 {
162     int lcdCount = 0;
163     int32_t err = GetDistributeLcdCount(opts, lcdCount);
164     if (err != E_OK) {
165         MEDIA_ERR_LOG("Failed to GetDistributeLcdCount %{public}d", err);
166         return err;
167     }
168     MEDIA_DEBUG_LOG("GetDistributeLcdCount %{public}d", lcdCount);
169     if (lcdCount <= THUMBNAIL_LCD_AGING_THRESHOLD) {
170         MEDIA_INFO_LOG("Not need aging Lcd. GetDistributeLcdCount: %{lcdCount}d", lcdCount);
171         return E_OK;
172     }
173     vector<ThumbnailData> infos;
174     err = GetAgingDistributeLcdData(opts, lcdCount - THUMBNAIL_LCD_GENERATE_THRESHOLD, infos);
175     if ((err != E_OK) || infos.empty()) {
176         MEDIA_ERR_LOG("Failed to GetAgingDistributeLcdData %{public}d", err);
177         return err;
178     }
179 
180     for (uint32_t i = 0; i < infos.size(); i++) {
181         opts.row = infos[i].id;
182         ThumbnailUtils::DeleteDistributeLcdData(opts, infos[i]);
183     }
184 
185     return E_OK;
186 }
187 #endif
188 
GetLcdCount(ThumbRdbOpt & opts,int & outLcdCount)189 int32_t ThumbnailAgingHelper::GetLcdCount(ThumbRdbOpt &opts, int &outLcdCount)
190 {
191     int32_t err = E_ERR;
192     if (!ThumbnailUtils::QueryLcdCount(opts, outLcdCount, err)) {
193         MEDIA_ERR_LOG("Failed to QueryLcdCount %{public}d", err);
194         return err;
195     }
196     return E_OK;
197 }
198 
GetLcdCountByTime(const int64_t & time,const bool & before,ThumbRdbOpt & opts,int & outLcdCount)199 int32_t ThumbnailAgingHelper::GetLcdCountByTime(const int64_t &time, const bool &before, ThumbRdbOpt &opts,
200     int &outLcdCount)
201 {
202     int32_t err = E_ERR;
203     if (!ThumbnailUtils::QueryLcdCountByTime(time, before, opts, outLcdCount, err)) {
204         MEDIA_ERR_LOG("Failed to QueryLcdCountByTime %{public}d", err);
205         return err;
206     }
207     return E_OK;
208 }
209 
210 #ifdef DISTRIBUTED
GetDistributeLcdCount(ThumbRdbOpt & opts,int & outLcdCount)211 int32_t ThumbnailAgingHelper::GetDistributeLcdCount(ThumbRdbOpt &opts, int &outLcdCount)
212 {
213     int32_t err = E_ERR;
214     if (!ThumbnailUtils::QueryDistributeLcdCount(opts, outLcdCount, err)) {
215         MEDIA_ERR_LOG("Failed to QueryLcdCount %{public}d", err);
216         return err;
217     }
218     return E_OK;
219 }
220 #endif
221 
GetAgingLcdData(ThumbRdbOpt & opts,int lcdLimit,vector<ThumbnailData> & outDatas)222 int32_t ThumbnailAgingHelper::GetAgingLcdData(ThumbRdbOpt &opts, int lcdLimit, vector<ThumbnailData> &outDatas)
223 {
224     int32_t err = E_ERR;
225     if (!ThumbnailUtils::QueryAgingLcdInfos(opts, lcdLimit, outDatas, err)) {
226         MEDIA_ERR_LOG("Failed to QueryAgingLcdInfos %{public}d", err);
227         return err;
228     }
229     return E_OK;
230 }
231 
232 #ifdef DISTRIBUTED
GetAgingDistributeLcdData(ThumbRdbOpt & opts,int lcdLimit,vector<ThumbnailData> & outDatas)233 int32_t ThumbnailAgingHelper::GetAgingDistributeLcdData(ThumbRdbOpt &opts,
234     int lcdLimit, vector<ThumbnailData> &outDatas)
235 {
236     int32_t err = E_ERR;
237     if (!ThumbnailUtils::QueryAgingDistributeLcdInfos(opts, lcdLimit, outDatas, err)) {
238         MEDIA_ERR_LOG("Failed to QueryAgingLcdInfos %{public}d", err);
239         return err;
240     }
241     return E_OK;
242 }
243 
InvalidateDistributeBatch(ThumbRdbOpt & opts)244 int32_t ThumbnailAgingHelper::InvalidateDistributeBatch(ThumbRdbOpt &opts)
245 {
246     if (opts.store == nullptr) {
247         MEDIA_ERR_LOG("opts.store is not init");
248         return E_ERR;
249     }
250 
251     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
252     if (asyncWorker == nullptr) {
253         return E_ERR;
254     }
255     AgingAsyncTaskData* taskData = new (std::nothrow)AgingAsyncTaskData();
256     if (taskData == nullptr) {
257         return E_ERR;
258     }
259     taskData->opts = opts;
260     shared_ptr<MediaLibraryAsyncTask> agingAsyncTask = make_shared<MediaLibraryAsyncTask>(
261         ClearThumbnailRecordTask, taskData);
262     if (agingAsyncTask != nullptr) {
263         asyncWorker->AddTask(agingAsyncTask, true);
264     }
265     return E_OK;
266 }
267 
ClearKeyAndRecordFromMap(ThumbRdbOpt & opts)268 int32_t ThumbnailAgingHelper::ClearKeyAndRecordFromMap(ThumbRdbOpt &opts)
269 {
270     int32_t err = E_ERR;
271     vector<ThumbnailData> infos;
272     if (!ThumbnailUtils::QueryDeviceThumbnailRecords(opts, infos, err)) {
273         MEDIA_ERR_LOG("Failed to QueryDeviceThumbnailRecords %{public}d", err);
274         return err;
275     }
276 
277     for (uint32_t i = 0; i < infos.size(); i++) {
278         opts.row = infos[i].id;
279         if (ThumbnailUtils::DeleteOriginImage(opts)) {
280             ThumbnailUtils::DeleteDistributeThumbnailInfo(opts);
281         }
282     }
283     return E_OK;
284 }
285 #endif
286 } // namespace Media
287 } // namespace OHOS
288