• 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 "Thumbnail"
16 
17 #include "thumbnail_service.h"
18 
19 #include "display_manager.h"
20 #include "media_column.h"
21 #include "medialibrary_async_worker.h"
22 #include "medialibrary_db_const.h"
23 #include "medialibrary_errno.h"
24 #include "media_log.h"
25 #include "result_set_utils.h"
26 #include "thumbnail_aging_helper.h"
27 #include "thumbnail_const.h"
28 #include "thumbnail_generate_helper.h"
29 #include "thumbnail_helper_factory.h"
30 #include "thumbnail_uri_utils.h"
31 
32 using namespace std;
33 using namespace OHOS::DistributedKv;
34 using namespace OHOS::NativeRdb;
35 using namespace OHOS::AbilityRuntime;
36 
37 namespace OHOS {
38 namespace Media {
39 std::shared_ptr<ThumbnailService> ThumbnailService::thumbnailServiceInstance_{nullptr};
40 std::mutex ThumbnailService::instanceLock_;
ThumbnailService(void)41 ThumbnailService::ThumbnailService(void)
42 {
43     rdbStorePtr_ = nullptr;
44     kvStorePtr_ = nullptr;
45 }
46 
GetInstance()47 shared_ptr<ThumbnailService> ThumbnailService::GetInstance()
48 {
49     if (thumbnailServiceInstance_ == nullptr) {
50         std::lock_guard<std::mutex> lockGuard(instanceLock_);
51         if (thumbnailServiceInstance_ != nullptr) {
52             return thumbnailServiceInstance_;
53         }
54         thumbnailServiceInstance_ = shared_ptr<ThumbnailService>(new ThumbnailService());
55     }
56 
57     return thumbnailServiceInstance_;
58 }
59 
GetDefaultWindowSize(Size & size)60 static int32_t GetDefaultWindowSize(Size &size)
61 {
62     auto &displayMgr = OHOS::Rosen::DisplayManager::GetInstance();
63     auto display = displayMgr.GetDefaultDisplay();
64     if (display == nullptr) {
65         return E_ERR;
66     }
67     size.width = display->GetWidth();
68     size.height = display->GetHeight();
69     MEDIA_INFO_LOG("display window size::w %{public}d, h %{public}d", size.width, size.height);
70 
71     return E_OK;
72 }
73 
Init(const shared_ptr<RdbStore> & rdbStore,const shared_ptr<SingleKvStore> & kvStore,const shared_ptr<Context> & context)74 int32_t ThumbnailService::Init(const shared_ptr<RdbStore> &rdbStore,
75     const shared_ptr<SingleKvStore> &kvStore,
76     const shared_ptr<Context> &context)
77 {
78     rdbStorePtr_ = rdbStore;
79     kvStorePtr_ = kvStore;
80     context_ = context;
81 
82     return GetDefaultWindowSize(screenSize_);
83 }
84 
ReleaseService()85 void ThumbnailService::ReleaseService()
86 {
87     StopAllWorker();
88     rdbStorePtr_ = nullptr;
89     kvStorePtr_ = nullptr;
90     context_ = nullptr;
91     thumbnailServiceInstance_ = nullptr;
92 }
93 
94 #ifdef MEDIALIBRARY_COMPATIBILITY
GetPathFromDb(const shared_ptr<NativeRdb::RdbStore> & rdbStorePtr,const string & fileId,const string & table,string & path)95 static int32_t GetPathFromDb(const shared_ptr<NativeRdb::RdbStore> &rdbStorePtr, const string &fileId,
96     const string &table, string &path)
97 {
98     if (rdbStorePtr == nullptr) {
99         return E_HAS_DB_ERROR;
100     }
101     if (!all_of(fileId.begin(), fileId.end(), ::isdigit)) {
102         return E_INVALID_FILEID;
103     }
104     string querySql = "SELECT " + MediaColumn::MEDIA_FILE_PATH + " FROM " + table +
105         " WHERE " + MediaColumn::MEDIA_ID + "=?";
106     vector<string> selectionArgs = { fileId };
107     auto resultSet = rdbStorePtr->QuerySql(querySql, selectionArgs);
108     if (resultSet == nullptr || resultSet->GoToFirstRow() != NativeRdb::E_OK) {
109         return E_HAS_DB_ERROR;
110     }
111     path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
112     if (path.empty()) {
113         return E_INVALID_PATH;
114     }
115     return E_OK;
116 }
117 #endif
118 
GetThumbnailFd(const string & uri)119 int ThumbnailService::GetThumbnailFd(const string &uri)
120 {
121     string id, path, table;
122     Size size;
123     if (!ThumbnailUriUtils::ParseThumbnailInfo(uri, id, size, path, table)) {
124         return E_FAIL;
125     }
126 #ifdef MEDIALIBRARY_COMPATIBILITY
127     if (path.empty()) {
128         int32_t errCode = GetPathFromDb(rdbStorePtr_, id, table, path);
129         if (errCode != E_OK) {
130             MEDIA_ERR_LOG("GetPathFromDb failed, errCode = %{public}d", errCode);
131             return errCode;
132         }
133     }
134 #endif
135     ThumbRdbOpt opts = {
136         .store = rdbStorePtr_,
137         .path = path,
138         .table = table,
139         .row = id,
140         .uri = uri,
141     };
142     shared_ptr<IThumbnailHelper> thumbnailHelper = ThumbnailHelperFactory::GetThumbnailHelper(size);
143     if (thumbnailHelper == nullptr) {
144         return E_NO_MEMORY;
145     }
146     if (!IsThumbnail(size.width, size.height)) {
147         opts.screenSize = screenSize_;
148     }
149     int fd = thumbnailHelper->GetThumbnailPixelMap(opts);
150     if (fd < 0) {
151         MEDIA_ERR_LOG("GetThumbnailPixelMap failed : %{public}d", fd);
152     }
153     return fd;
154 }
155 
CreateThumbnail(const std::string & uri,const string & path,bool isSync)156 int32_t ThumbnailService::CreateThumbnail(const std::string &uri, const string &path, bool isSync)
157 {
158     string fileId;
159     string networkId;
160     string tableName;
161     if (!ThumbnailUriUtils::ParseFileUri(uri, fileId, networkId, tableName)) {
162         MEDIA_ERR_LOG("ParseThumbnailInfo faild");
163         return E_ERR;
164     }
165 
166     ThumbRdbOpt opts = {
167         .store = rdbStorePtr_,
168         .path = path,
169         .table = tableName,
170         .row = fileId,
171         .screenSize = screenSize_
172     };
173     Size size = { DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE };
174     shared_ptr<IThumbnailHelper> thumbnailHelper = ThumbnailHelperFactory::GetThumbnailHelper(size);
175     if (thumbnailHelper == nullptr) {
176         MEDIA_ERR_LOG("thumbnailHelper nullptr");
177         return E_ERR;
178     }
179     int32_t err = thumbnailHelper->CreateThumbnail(opts, isSync);
180     if (err != E_OK) {
181         MEDIA_ERR_LOG("CreateThumbnail failed : %{public}d", err);
182         return err;
183     }
184 
185     size = { DEFAULT_LCD_SIZE, DEFAULT_LCD_SIZE };
186     shared_ptr<IThumbnailHelper> lcdHelper = ThumbnailHelperFactory::GetThumbnailHelper(size);
187     if (lcdHelper == nullptr) {
188         MEDIA_ERR_LOG("lcdHelper nullptr");
189         return E_ERR;
190     }
191     err = lcdHelper->CreateThumbnail(opts, isSync);
192     if (err != E_OK) {
193         MEDIA_ERR_LOG("CreateLcd failed : %{public}d", err);
194         return err;
195     }
196     return err;
197 }
198 
InterruptBgworker()199 void ThumbnailService::InterruptBgworker()
200 {
201     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
202     if (asyncWorker != nullptr) {
203         asyncWorker->Interrupt();
204     }
205 }
206 
StopAllWorker()207 void ThumbnailService::StopAllWorker()
208 {
209     shared_ptr<MediaLibraryAsyncWorker> asyncWorker = MediaLibraryAsyncWorker::GetInstance();
210     if (asyncWorker != nullptr) {
211         asyncWorker->Stop();
212     }
213 }
214 
GenerateThumbnails()215 int32_t ThumbnailService::GenerateThumbnails()
216 {
217     int32_t err = 0;
218     vector<string> tableList;
219     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
220     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
221     tableList.emplace_back(MEDIALIBRARY_TABLE);
222 
223     for (const auto &tableName : tableList) {
224         ThumbRdbOpt opts = {
225             .store = rdbStorePtr_,
226             .kvStore = kvStorePtr_,
227             .table = tableName
228         };
229 
230         err = ThumbnailGenerateHelper::CreateThumbnailBatch(opts);
231         if (err != E_OK) {
232             MEDIA_ERR_LOG("CreateThumbnailBatch failed : %{public}d", err);
233         }
234         if (tableName != AudioColumn::AUDIOS_TABLE) {
235             err = ThumbnailGenerateHelper::CreateLcdBatch(opts);
236             if (err != E_OK) {
237                 MEDIA_ERR_LOG("CreateLcdBatch failed : %{public}d", err);
238             }
239         }
240     }
241 
242     return err;
243 }
244 
LcdAging()245 int32_t ThumbnailService::LcdAging()
246 {
247     int32_t err = 0;
248     vector<string> tableList;
249     tableList.emplace_back(PhotoColumn::PHOTOS_TABLE);
250     tableList.emplace_back(AudioColumn::AUDIOS_TABLE);
251     tableList.emplace_back(MEDIALIBRARY_TABLE);
252 
253     for (const auto &tableName : tableList) {
254         ThumbRdbOpt opts = {
255             .store = rdbStorePtr_,
256             .kvStore = kvStorePtr_,
257             .table = tableName,
258         };
259         err = ThumbnailAgingHelper::AgingLcdBatch(opts);
260         if (err != E_OK) {
261             MEDIA_ERR_LOG("AgingLcdBatch failed : %{public}d", err);
262         }
263     }
264 
265     return E_OK;
266 }
267 
268 #ifdef DISTRIBUTED
LcdDistributeAging(const string & udid)269 int32_t ThumbnailService::LcdDistributeAging(const string &udid)
270 {
271     ThumbRdbOpt opts = {
272         .store = rdbStorePtr_,
273         .kvStore = kvStorePtr_,
274         .udid = udid
275     };
276     int32_t err = ThumbnailAgingHelper::AgingDistributeLcdBatch(opts);
277     if (err != E_OK) {
278         MEDIA_ERR_LOG("AgingDistributeLcdBatch failed : %{public}d", err);
279         return err;
280     }
281     return E_OK;
282 }
283 
InvalidateDistributeThumbnail(const string & udid)284 int32_t ThumbnailService::InvalidateDistributeThumbnail(const string &udid)
285 {
286     ThumbRdbOpt opts = {
287         .store = rdbStorePtr_,
288         .kvStore = kvStorePtr_,
289         .udid = udid
290     };
291     int32_t err = ThumbnailAgingHelper::InvalidateDistributeBatch(opts);
292     if (err != E_OK) {
293         MEDIA_ERR_LOG("InvalidateDistributeBatch failed : %{public}d", err);
294     }
295     return err;
296 }
297 #endif
298 
InvalidateThumbnail(const std::string & id,const std::string & tableName,const std::string & path)299 void ThumbnailService::InvalidateThumbnail(const std::string &id, const std::string &tableName, const std::string &path)
300 {
301     ThumbRdbOpt opts = {
302         .store = rdbStorePtr_,
303         .path = path,
304         .table = tableName,
305         .row = id,
306     };
307     ThumbnailData thumbnailData;
308     ThumbnailUtils::DeleteOriginImage(opts);
309 }
310 } // namespace Media
311 } // namespace OHOS
312