1 /*
2 * Copyright (C) 2021-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 "MtpMedialibraryManager"
16 #include "mtp_medialibrary_manager.h"
17
18 #include <unistd.h>
19 #include <sys/time.h>
20 #include "datashare_predicates.h"
21 #include "datashare_abs_result_set.h"
22 #include "datashare_result_set.h"
23 #include "directory_ex.h"
24 #include "fetch_result.h"
25 #include "image_format_convert.h"
26 #include "image_packer.h"
27 #include "image_source.h"
28 #include "media_column.h"
29 #include "mtp_data_utils.h"
30 #include "media_file_utils.h"
31 #include "media_mtp_utils.h"
32 #include "mtp_error_utils.h"
33 #include "media_library_manager.h"
34 #include "media_log.h"
35 #include "medialibrary_errno.h"
36 #include "medialibrary_tracer.h"
37 #include "media_smart_map_column.h"
38 #include "moving_photo_file_utils.h"
39 #include "photo_album_column.h"
40 #include "ptp_media_sync_observer.h"
41 #include "pixel_map.h"
42 #include "ptp_album_handles.h"
43 #include "ptp_medialibrary_manager_uri.h"
44 #include "ptp_special_handles.h"
45 #include "system_ability_definition.h"
46 #include "userfilemgr_uri.h"
47 #include "mediatool_uri.h"
48 #include "album_operation_uri.h"
49
50 using namespace std;
51
52 namespace OHOS {
53 namespace Media {
54
55 sptr<IRemoteObject> MtpMedialibraryManager::getThumbToken_ = nullptr;
56 constexpr int32_t NORMAL_WIDTH = 256;
57 constexpr int32_t NORMAL_HEIGHT = 256;
58 const string THUMBNAIL_WIDTH = "256";
59 const string THUMBNAIL_HEIGHT = "256";
60 constexpr int32_t COMPRE_SIZE_LEVEL_1 = 256;
61 constexpr int32_t COMPRE_SIZE_LEVEL_2 = 204800;
62 constexpr size_t SIZE_ONE = 1;
63 const string NORMAL_MEDIA_URI = "file://media/Photo/";
64 const string THUMBNAIL_FORMAT = "image/jpeg";
65 static constexpr uint8_t THUMBNAIL_MID = 90;
66 constexpr int32_t PARENT_ID = 0;
67 const string API_VERSION = "api_version";
68 const string POSITION_CLOUD_FLAG = "2";
69 const string IS_LOCAL = "2";
70 const string ALBUM_MEDIA_TYPE = "7";
71 const int64_t DATE_UNTRASHED = 0;
72 const int32_t SPECIAL_PTHOTO_TYPE = 2;
73 const std::string PARENT = "parent";
74 const std::string HIDDEN_ALBUM = ".hiddenAlbum";
75 const string BURST_COVER_LEVEL = "1";
76 const string EMPTY_COLUMN_NAME = "0";
77 const string PARENT_ID_STRING = "0";
78 const std::string MOVING_PHOTO_SUFFIX = ".mp4";
79 constexpr int32_t MILLI_TO_SECOND = 1000;
80 constexpr int32_t PATH_TIMEVAL_MAX = 2;
81 constexpr int32_t MOVING_PHOTO_TYPE = 3;
82 constexpr int32_t BURST_COVER_LEVEL_INT = 1;
83 constexpr int32_t MEDIA_PHOTO_TYPE = 1;
84 constexpr int32_t MEDIA_VIDEO_TYPE = 2;
85 constexpr int32_t ALBUM_NAME_MAX = 70;
86 namespace {
87 std::vector<std::string> g_photoColumns = {
88 MediaColumn::MEDIA_ID + " + " + to_string(COMMON_PHOTOS_OFFSET) + " as " + MEDIA_DATA_DB_ID,
89 MediaColumn::MEDIA_SIZE,
90 MediaColumn::MEDIA_NAME,
91 PhotoColumn::PHOTO_OWNER_ALBUM_ID +" as " + PARENT,
92 MediaColumn::MEDIA_DATE_ADDED,
93 MediaColumn::MEDIA_DURATION,
94 MediaColumn::MEDIA_TYPE,
95 MediaColumn::MEDIA_FILE_PATH,
96 PhotoColumn::PHOTO_SUBTYPE,
97 PhotoColumn::MEDIA_DATE_MODIFIED,
98 PhotoColumn::PHOTO_THUMB_SIZE,
99 PhotoColumn::PHOTO_BURST_KEY,
100 PhotoColumn::MOVING_PHOTO_EFFECT_MODE,
101 PhotoColumn::PHOTO_BURST_COVER_LEVEL,
102 };
103 const std::string ZERO = "0";
104 } // namespace
105
106 std::shared_ptr<MtpMedialibraryManager> MtpMedialibraryManager::instance_ = nullptr;
107 std::mutex MtpMedialibraryManager::mutex_;
108 shared_ptr<DataShare::DataShareHelper> MtpMedialibraryManager::dataShareHelper_ = nullptr;
109 std::shared_ptr<MediaSyncObserver> mediaPhotoObserver_ = nullptr;
110 // LCOV_EXCL_START
GetHmdfsPath(const std::string & path)111 std::string MtpMedialibraryManager::GetHmdfsPath(const std::string &path)
112 {
113 const std::string FILES = "/files/";
114 const std::string HMDFS_DIR = "/mnt/hmdfs/100/account/device_view/local";
115 size_t filesPos = path.find(FILES);
116 if (filesPos == std::string::npos) {
117 MEDIA_WARN_LOG("path:%{public}s", path.c_str());
118 return path;
119 }
120 return HMDFS_DIR + path.substr(filesPos);
121 }
122
MtpMedialibraryManager(void)123 MtpMedialibraryManager::MtpMedialibraryManager(void)
124 {
125 }
126
~MtpMedialibraryManager(void)127 MtpMedialibraryManager::~MtpMedialibraryManager(void)
128 {
129 }
130
GetInstance()131 std::shared_ptr<MtpMedialibraryManager> MtpMedialibraryManager::GetInstance()
132 {
133 if (instance_ == nullptr) {
134 std::lock_guard<std::mutex> lock(mutex_);
135 if (instance_ == nullptr) {
136 instance_ = std::make_shared<MtpMedialibraryManager>();
137 }
138 }
139 return instance_;
140 }
141
Init(const sptr<IRemoteObject> & token,const std::shared_ptr<MtpOperationContext> & context)142 void MtpMedialibraryManager::Init(const sptr<IRemoteObject> &token, const std::shared_ptr<MtpOperationContext> &context)
143 {
144 std::lock_guard<std::mutex> lock(mutex_);
145 if (dataShareHelper_ == nullptr) {
146 dataShareHelper_ = DataShare::DataShareHelper::Creator(token, MEDIALIBRARY_DATA_URI);
147 }
148 if (mediaPhotoObserver_ == nullptr) {
149 mediaPhotoObserver_ = std::make_shared<MediaSyncObserver>();
150 }
151 CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr, "fail to get dataShareHelper");
152 CHECK_AND_RETURN_LOG(mediaPhotoObserver_ != nullptr, "fail to get mediaPhotoObserver");
153 getThumbToken_ = token;
154 mediaPhotoObserver_->context_ = context;
155 mediaPhotoObserver_->dataShareHelper_ = dataShareHelper_;
156 mediaPhotoObserver_->StartNotifyThread();
157 dataShareHelper_->RegisterObserverExt(Uri(PhotoColumn::PHOTO_URI_PREFIX), mediaPhotoObserver_, true);
158 dataShareHelper_->RegisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_URI_PREFIX), mediaPhotoObserver_, true);
159 }
160
Clear()161 void MtpMedialibraryManager::Clear()
162 {
163 MEDIA_INFO_LOG("MtpMediaLibrary::Ptp Clear is called");
164 std::lock_guard<std::mutex> lock(mutex_);
165 if (mediaPhotoObserver_ != nullptr) {
166 mediaPhotoObserver_->StopNotifyThread();
167 }
168 if (dataShareHelper_ != nullptr) {
169 dataShareHelper_->UnregisterObserverExt(Uri(PhotoColumn::PHOTO_URI_PREFIX), mediaPhotoObserver_);
170 dataShareHelper_->UnregisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_URI_PREFIX), mediaPhotoObserver_);
171 }
172 mediaPhotoObserver_ = nullptr;
173 dataShareHelper_ = nullptr;
174 deletedMovingPhotoHandles_.clear();
175 auto ptpSpecialHandles = PtpSpecialHandles::GetInstance();
176 CHECK_AND_RETURN_LOG(ptpSpecialHandles != nullptr, "fail to get ptpSpecialHandles");
177 ptpSpecialHandles->ClearDeletedHandles();
178 }
179
HandleConvertToAdded(uint32_t key)180 static uint32_t HandleConvertToAdded(uint32_t key)
181 {
182 auto ptpSpecialHandles = PtpSpecialHandles::GetInstance();
183 CHECK_AND_RETURN_RET_LOG(ptpSpecialHandles != nullptr, key, "ptpSpecialHandles is nullptr");
184 return ptpSpecialHandles->HandleConvertToAdded(key);
185 }
186
GetHandles(int32_t parentId,vector<int> & outHandles,MediaType mediaType)187 int32_t MtpMedialibraryManager::GetHandles(int32_t parentId, vector<int> &outHandles, MediaType mediaType)
188 {
189 shared_ptr<DataShare::DataShareResultSet> resultSet;
190 DataShare::DataSharePredicates predicates;
191 vector<string> columns;
192 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
193 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
194 if (parentId == PARENT_ID || parentId == PTP_IN_MTP_ID) {
195 Uri uri(PAH_QUERY_PHOTO_ALBUM);
196 columns.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
197 columns.push_back(PhotoAlbumColumns::ALBUM_NAME + " as " + MEDIA_DATA_DB_NAME);
198 columns.push_back(ALBUM_MEDIA_TYPE + " as " + MEDIA_DATA_DB_MEDIA_TYPE);
199 columns.push_back(PhotoAlbumColumns::ALBUM_DATE_MODIFIED);
200 columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_SIZE);
201 columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_PARENT_ID);
202 columns.push_back(PhotoAlbumColumns::ALBUM_DATE_ADDED);
203 predicates.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
204 predicates.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
205 predicates.NotEqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
206 resultSet = dataShareHelper_->Query(uri, predicates, columns);
207 } else {
208 Uri uri(PAH_QUERY_PHOTO);
209 columns.push_back(MediaColumn::MEDIA_ID + " + " + to_string(COMMON_PHOTOS_OFFSET) + " as " + MEDIA_DATA_DB_ID);
210 columns.push_back(MediaColumn::MEDIA_SIZE);
211 columns.push_back(MediaColumn::MEDIA_NAME);
212 columns.push_back(PhotoColumn::PHOTO_OWNER_ALBUM_ID +" as " + PARENT);
213 columns.push_back(MediaColumn::MEDIA_DATE_ADDED);
214 columns.push_back(MediaColumn::MEDIA_DURATION);
215 columns.push_back(MediaColumn::MEDIA_TYPE);
216 columns.push_back(PhotoColumn::PHOTO_SUBTYPE);
217 columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_NAME);
218 DataShare::DataSharePredicates predicates;
219 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(parentId));
220 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
221 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
222 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
223 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
224 resultSet = dataShareHelper_->Query(uri, predicates, columns);
225 }
226 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
227 MtpErrorUtils::SolveGetHandlesError(E_NO_SUCH_FILE), "fail to get handles");
228 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
229 MtpErrorUtils::SolveGetHandlesError(E_SUCCESS), "have no handles");
230 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
231 int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
232 outHandles.push_back(id);
233 }
234 resultSet->GoToFirstRow();
235 return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
236 }
237
GetAlbumCloud()238 int32_t MtpMedialibraryManager::GetAlbumCloud()
239 {
240 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
241 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
242 DataShare::DataSharePredicates predicatesCloud;
243 Uri uri(PAH_QUERY_PHOTO_ALBUM);
244 vector<string> columnsCloud;
245 columnsCloud.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
246 predicatesCloud.EqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
247 shared_ptr<DataShare::DataShareResultSet> resultSetcloud = dataShareHelper_->Query(uri, predicatesCloud,
248 columnsCloud);
249 CHECK_AND_RETURN_RET_LOG(resultSetcloud != nullptr,
250 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to GetAlbumCloud");
251 int cloudCount = 0;
252 resultSetcloud->GetRowCount(cloudCount);
253 MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumCloud cloudCount:%{public}d", cloudCount);
254 resultSetcloud->Close();
255 return MTP_SUCCESS;
256 }
257
GetAlbumCloudDisplay(vector<string> & ownerAlbumIds)258 int32_t MtpMedialibraryManager::GetAlbumCloudDisplay(vector<string> &ownerAlbumIds)
259 {
260 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
261 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
262 DataShare::DataSharePredicates predicatesCloudDisplay;
263 vector<string> columnsCloudDisplay;
264 Uri uri(PAH_QUERY_PHOTO_ALBUM);
265 columnsCloudDisplay.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
266 predicatesCloudDisplay.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
267 predicatesCloudDisplay.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
268 predicatesCloudDisplay.EqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
269 predicatesCloudDisplay.In(PhotoAlbumColumns::ALBUM_ID, ownerAlbumIds);
270 shared_ptr<DataShare::DataShareResultSet> resultSetcloudDisplay = dataShareHelper_->Query(uri,
271 predicatesCloudDisplay, columnsCloudDisplay);
272 CHECK_AND_RETURN_RET_LOG(resultSetcloudDisplay != nullptr,
273 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to GetAlbumCloudDisplay");
274 int cloudCountDisplay = 0;
275 resultSetcloudDisplay->GetRowCount(cloudCountDisplay);
276 MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumCloudDisplay cloudCountDisplay:%{public}d", cloudCountDisplay);
277 resultSetcloudDisplay->Close();
278 return MTP_SUCCESS;
279 }
280
GetAlbumInfo(const shared_ptr<MtpOperationContext> & context,bool isHandle)281 shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetAlbumInfo(
282 const shared_ptr<MtpOperationContext> &context, bool isHandle)
283 {
284 CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "context is nullptr");
285 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr, "GetAlbumInfo fail to get datasharehelper");
286 DataShare::DataSharePredicates predicates;
287 Uri uri(PAH_QUERY_PHOTO_ALBUM);
288 vector<string> columns;
289 columns.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
290 columns.push_back(PhotoAlbumColumns::ALBUM_NAME + " as " + MEDIA_DATA_DB_NAME);
291 columns.push_back(ALBUM_MEDIA_TYPE + " as " + MEDIA_DATA_DB_MEDIA_TYPE);
292 columns.push_back(PhotoAlbumColumns::ALBUM_DATE_MODIFIED);
293 columns.push_back(PARENT_ID_STRING + " as " + PARENT);
294 columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_SIZE);
295 columns.push_back(PhotoAlbumColumns::ALBUM_DATE_ADDED);
296 if (!isHandle) {
297 predicates.EqualTo(MEDIA_DATA_DB_ALBUM_ID, to_string(HandleConvertToAdded(context->handle)));
298 return dataShareHelper_->Query(uri, predicates, columns);
299 }
300 vector<string> ownerAlbumIds;
301 shared_ptr<DataShare::DataShareResultSet> resultSet = GetOwnerAlbumIdList();
302 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "fail to GetPhotosInfo");
303 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
304 string ownerAlbumId = GetStringVal(PhotoColumn::PHOTO_OWNER_ALBUM_ID, resultSet);
305 ownerAlbumIds.push_back(ownerAlbumId);
306 }
307 int32_t errCode = GetAlbumCloud();
308 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, nullptr, "fail to GetAlbumCloud");
309 errCode = GetAlbumCloudDisplay(ownerAlbumIds);
310 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, nullptr, "fail to GetAlbumCloudDisplay");
311 predicates.BeginWrap();
312 predicates.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
313 predicates.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
314 predicates.BeginWrap();
315 predicates.NotEqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
316 predicates.Or();
317 predicates.IsNull(MEDIA_DATA_DB_IS_LOCAL);
318 predicates.EndWrap();
319 predicates.EndWrap();
320 predicates.Or();
321 predicates.In(PhotoAlbumColumns::ALBUM_ID, ownerAlbumIds);
322 shared_ptr<DataShare::DataShareResultSet> resultSetAll = dataShareHelper_->Query(uri, predicates, columns);
323 CHECK_AND_RETURN_RET_LOG(resultSetAll != nullptr, nullptr, "fail to GetAlbumInfo");
324 int count = 0;
325 resultSetAll->GetRowCount(count);
326 MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumInfo count:%{public}d", count);
327 return resultSetAll;
328 }
329
GetOwnerAlbumIdList()330 std::shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetOwnerAlbumIdList()
331 {
332 Uri uri(PAH_QUERY_PHOTO);
333 vector<string> columns;
334 columns.push_back(PhotoColumn::PHOTO_OWNER_ALBUM_ID);
335 DataShare::DataSharePredicates predicates;
336 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
337 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
338 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
339 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
340 predicates.Distinct();
341 return dataShareHelper_->Query(uri, predicates, columns);
342 }
343
GetPhotosInfoForMove(const shared_ptr<MtpOperationContext> & context)344 shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetPhotosInfoForMove(
345 const shared_ptr<MtpOperationContext> &context)
346 {
347 CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "context is nullptr");
348 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr,
349 "MtpMedialibraryManager::GetPhotosInfo fail to get datasharehelper");
350 Uri uri(PAH_QUERY_PHOTO);
351 DataShare::DataSharePredicates predicates;
352 int32_t file_id = static_cast<int32_t>(context->handle % COMMON_PHOTOS_OFFSET);
353 predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(file_id));
354 return dataShareHelper_->Query(uri, predicates, g_photoColumns);
355 }
356
GetPhotosInfo(const shared_ptr<MtpOperationContext> & context,bool isHandle)357 shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetPhotosInfo(
358 const shared_ptr<MtpOperationContext> &context, bool isHandle)
359 {
360 CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "context is nullptr");
361 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr,
362 "MtpMedialibraryManager::GetPhotosInfo fail to get datasharehelper");
363 Uri uri(PAH_QUERY_PHOTO);
364 DataShare::DataSharePredicates predicates;
365 if (isHandle) {
366 vector<string> burstKeys = GetBurstKeyFromPhotosInfo();
367 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(context->parent));
368 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
369 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
370 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
371 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
372 predicates.EqualTo(PhotoColumn::PHOTO_IS_TEMP, to_string(false));
373 if (!burstKeys.empty()) {
374 predicates.BeginWrap()
375 ->BeginWrap()
376 ->NotIn(PhotoColumn::PHOTO_BURST_KEY, burstKeys)
377 ->Or()
378 ->IsNull(PhotoColumn::PHOTO_BURST_KEY)
379 ->EndWrap()
380 ->Or()
381 ->EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL)
382 ->EndWrap();
383 }
384 } else {
385 int32_t file_id = static_cast<int32_t>(HandleConvertToAdded(context->handle) % COMMON_PHOTOS_OFFSET);
386 predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(file_id));
387 }
388 return dataShareHelper_->Query(uri, predicates, g_photoColumns);
389 }
390
GetBurstKeyFromPhotosInfo()391 vector<string> MtpMedialibraryManager::GetBurstKeyFromPhotosInfo()
392 {
393 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, vector<string>(),
394 "MtpMedialibraryManager::GetBurstKeyFromPhotosInfo fail to get datasharehelper");
395 vector<string> bustKeys;
396 Uri uri(PAH_QUERY_PHOTO);
397 vector<string> columns;
398 columns.push_back(PhotoColumn::PHOTO_BURST_KEY);
399 DataShare::DataSharePredicates predicates;
400 predicates.NotEqualTo(PhotoColumn::MEDIA_DATE_TRASHED, "0");
401 predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL);
402 predicates.IsNotNull(PhotoColumn::PHOTO_BURST_KEY);
403 shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
404 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
405 vector<string>(), "fail to get handles");
406 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
407 vector<string>(), "have no handles");
408 do {
409 string bustKey = GetStringVal(PhotoColumn::PHOTO_BURST_KEY, resultSet);
410 bustKeys.push_back(bustKey);
411 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
412 return bustKeys;
413 }
414
HaveMovingPhotesHandle(const shared_ptr<DataShare::DataShareResultSet> resultSet,shared_ptr<UInt32List> & outHandles,const uint32_t parent,FileCountInfo & fileCountInfo)415 int32_t MtpMedialibraryManager::HaveMovingPhotesHandle(const shared_ptr<DataShare::DataShareResultSet> resultSet,
416 shared_ptr<UInt32List> &outHandles, const uint32_t parent, FileCountInfo &fileCountInfo)
417 {
418 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "resultSet is nullptr");
419
420 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS, "have no handles");
421 do {
422 uint32_t id = static_cast<uint32_t>(GetInt32Val(MediaColumn::MEDIA_ID, resultSet));
423 outHandles->push_back(id);
424 if (id < COMMON_PHOTOS_OFFSET) {
425 continue;
426 }
427 int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
428 int32_t mediaType = GetInt32Val(MediaColumn::MEDIA_TYPE, resultSet);
429 int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
430 if (MtpDataUtils::IsMtpMovingPhoto(subtype, effectMode)) {
431 uint32_t videoId = id + (COMMON_MOVING_OFFSET - COMMON_PHOTOS_OFFSET);
432 outHandles->push_back(videoId);
433 fileCountInfo.livePhotoCount++;
434 } else if (subtype == static_cast<int32_t>(PhotoSubType::BURST)) {
435 int32_t burstCoverLevel = GetInt32Val(PhotoColumn::PHOTO_BURST_COVER_LEVEL, resultSet);
436 if (burstCoverLevel == BURST_COVER_LEVEL_INT) {
437 fileCountInfo.burstCount++;
438 }
439 fileCountInfo.burstTotalCount++;
440 } else if (mediaType == MEDIA_PHOTO_TYPE) {
441 fileCountInfo.normalCount++;
442 } else if (mediaType == MEDIA_VIDEO_TYPE) {
443 fileCountInfo.videoCount++;
444 } else {
445 MEDIA_ERR_LOG("MtpMedialibraryManager::HaveMovingPhotesHandle mediaType is not photo or video");
446 }
447 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
448 fileCountInfo.pictureCount = fileCountInfo.normalCount + fileCountInfo.livePhotoCount + fileCountInfo.burstCount;
449 return E_SUCCESS;
450 }
451
GetHandles(const shared_ptr<MtpOperationContext> & context,shared_ptr<UInt32List> & outHandles)452 int32_t MtpMedialibraryManager::GetHandles(const shared_ptr<MtpOperationContext> &context,
453 shared_ptr<UInt32List> &outHandles)
454 {
455 string extension;
456 MediaType mediaType;
457 CHECK_AND_RETURN_RET_LOG(context != nullptr,
458 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "context is nullptr");
459 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
460 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
461 int32_t errCode = MtpDataUtils::SolveHandlesFormatData(context->format, extension, mediaType);
462 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS,
463 MtpErrorUtils::SolveGetHandlesError(errCode), "fail to SolveHandlesFormatData");
464 shared_ptr<DataShare::DataShareResultSet> resultSet;
465 if (context->parent == PARENT_ID || context->parent == PTP_IN_MTP_ID) {
466 resultSet = GetAlbumInfo(context, true);
467 auto albumHandles = PtpAlbumHandles::GetInstance();
468 if (albumHandles != nullptr) {
469 albumHandles->AddAlbumHandles(resultSet);
470 }
471 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
472 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get handles");
473 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS, "have no handles");
474 do {
475 int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
476 outHandles->push_back(id);
477 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
478 return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
479 }
480 resultSet = GetPhotosInfo(context, true);
481 FileCountInfo fileCountInfo;
482 errCode = HaveMovingPhotesHandle(resultSet, outHandles, context->parent, fileCountInfo);
483 CountPhotosNumber(context, fileCountInfo);
484 return MtpErrorUtils::SolveGetHandlesError(errCode);
485 }
486
GetAllHandles(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt32List> & out)487 int32_t MtpMedialibraryManager::GetAllHandles(
488 const std::shared_ptr<MtpOperationContext> &context, std::shared_ptr<UInt32List> &out)
489 {
490 CHECK_AND_RETURN_RET_LOG((context != nullptr && dataShareHelper_ != nullptr && out != nullptr),
491 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "context is nullptr");
492 auto resultSet = GetAlbumInfo(context, true);
493 auto albumHandles = PtpAlbumHandles::GetInstance();
494 if (albumHandles != nullptr) {
495 albumHandles->AddAlbumHandles(resultSet);
496 }
497 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr && resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS,
498 "have no handles");
499 do {
500 int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
501 out->push_back(id);
502 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
503
504 DataShare::DataSharePredicates predicates;
505 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
506 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, ZERO);
507 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, ZERO);
508 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, ZERO);
509
510 auto burstKeys = GetBurstKeyFromPhotosInfo();
511 if (!burstKeys.empty()) {
512 predicates.BeginWrap()
513 ->BeginWrap()
514 ->NotIn(PhotoColumn::PHOTO_BURST_KEY, burstKeys)
515 ->Or()->IsNull(PhotoColumn::PHOTO_BURST_KEY)
516 ->EndWrap()
517 ->Or()->EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL)
518 ->EndWrap();
519 }
520
521 Uri uri(PAH_QUERY_PHOTO);
522 resultSet = dataShareHelper_->Query(uri, predicates, g_photoColumns);
523 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr && resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS,
524 "have no handles");
525 do {
526 uint32_t id = static_cast<uint32_t>(GetInt32Val(MediaColumn::MEDIA_ID, resultSet));
527 out->push_back(id);
528 if (id < COMMON_PHOTOS_OFFSET) {
529 continue;
530 }
531 int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
532 int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
533 if (MtpDataUtils::IsMtpMovingPhoto(subtype, effectMode)) {
534 uint32_t videoId = id + (COMMON_MOVING_OFFSET - COMMON_PHOTOS_OFFSET);
535 out->push_back(videoId);
536 }
537 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
538 return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
539 }
540
GetObjectInfo(const shared_ptr<MtpOperationContext> & context,shared_ptr<ObjectInfo> & outObjectInfo)541 int32_t MtpMedialibraryManager::GetObjectInfo(const shared_ptr<MtpOperationContext> &context,
542 shared_ptr<ObjectInfo> &outObjectInfo)
543 {
544 CHECK_AND_RETURN_RET_LOG(context != nullptr,
545 MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "context is nullptr");
546 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
547 MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "fail to get datasharehelper");
548 DataShare::DataSharePredicates predicates;
549 MEDIA_INFO_LOG("GetObjectInfo %{public}d,%{public}d", context->handle, context ->parent);
550 shared_ptr<DataShare::DataShareResultSet> resultSet;
551 if ((context->parent == PARENT_ID || context->parent == PTP_IN_MTP_ID) && context->handle < COMMON_PHOTOS_OFFSET) {
552 resultSet = GetAlbumInfo(context, false);
553 } else {
554 resultSet = GetPhotosInfo(context, false);
555 }
556 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
557 MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "fail to get object set");
558 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
559 MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "have no handles");
560 return SetObject(resultSet, context, outObjectInfo);
561 }
562
GetSizeFromOfft(const off_t & size)563 uint32_t MtpMedialibraryManager::GetSizeFromOfft(const off_t &size)
564 {
565 return size > std::numeric_limits<uint32_t>::max() ? std::numeric_limits<uint32_t>::max() : size;
566 }
567
GetMovingPhotoVideoDisplayName(const std::string & displayName,const std::string & path)568 static std::string GetMovingPhotoVideoDisplayName(const std::string &displayName, const std::string &path)
569 {
570 auto pos = displayName.find_last_of(DELIMETER_NAME);
571 auto posPath = path.find_last_of(DELIMETER_NAME);
572 if (pos == std::string::npos || posPath == std::string::npos) {
573 return displayName + DEFAULT_FORMAT_MP4;
574 }
575 return displayName.substr(0, pos) + path.substr(posPath);
576 }
577
SetObject(const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,const shared_ptr<MtpOperationContext> & context,std::shared_ptr<ObjectInfo> & outObjectInfo)578 int32_t MtpMedialibraryManager::SetObject(const std::shared_ptr<DataShare::DataShareResultSet> &resultSet,
579 const shared_ptr<MtpOperationContext> &context, std::shared_ptr<ObjectInfo> &outObjectInfo)
580 {
581 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
582 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
583 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "resultSet is nullptr");
584 do {
585 if (static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) < SPECIAL_PTHOTO_TYPE) {
586 unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
587 CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
588 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
589 unique_ptr<FileAsset> fileAsset = fetchFileResult->GetFirstObject();
590 return SetObjectInfo(fileAsset, outObjectInfo);
591 }
592 string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
593 string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
594 string sourcePath = MtpDataUtils::GetMovingOrEnditSourcePath(data, 0, context);
595 if (sourcePath.empty()) {
596 MEDIA_ERR_LOG("MtpMedialibraryManager::SetObject get sourcePath failed");
597 return MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE);
598 }
599 outObjectInfo->handle = HandleConvertToAdded(context->handle);
600 outObjectInfo->name = GetMovingPhotoVideoDisplayName(displayName, sourcePath);
601 outObjectInfo->parent = static_cast<uint32_t>(GetInt32Val(MediaColumn::MEDIA_PARENT_ID, resultSet));
602 outObjectInfo->storageID = context->storageID;
603 struct stat statInfo;
604 CHECK_AND_RETURN_RET_LOG(stat(sourcePath.c_str(), &statInfo) == 0,
605 MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE),
606 "MtpMedialibraryManager::SetObject stat failed");
607 outObjectInfo->size = GetSizeFromOfft(statInfo.st_size);
608 outObjectInfo->dateCreated = statInfo.st_ctime;
609 outObjectInfo->dateModified = statInfo.st_mtime;
610 outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
611 outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
612 outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
613 outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
614 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
615 return MtpErrorUtils::SolveGetObjectInfoError(E_SUCCESS);
616 }
617
SetObjectInfo(const unique_ptr<FileAsset> & fileAsset,shared_ptr<ObjectInfo> & outObjectInfo)618 int32_t MtpMedialibraryManager::SetObjectInfo(const unique_ptr<FileAsset> &fileAsset,
619 shared_ptr<ObjectInfo> &outObjectInfo)
620 {
621 CHECK_AND_RETURN_RET_LOG(outObjectInfo != nullptr,
622 MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "outObjectInfo is nullptr");
623 outObjectInfo->handle = static_cast<uint32_t>(fileAsset->GetId());
624 outObjectInfo->name = fileAsset->GetDisplayName();
625 if (MtpDataUtils::IsMtpMovingPhoto(fileAsset->GetPhotoSubType(), fileAsset->GetMovingPhotoEffectMode()) &&
626 fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) {
627 struct stat statInfo;
628 CHECK_AND_RETURN_RET_LOG(stat(fileAsset->GetPath().c_str(), &statInfo) == 0,
629 MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "SetObjectInfo stat failed");
630 outObjectInfo->size = GetSizeFromOfft(statInfo.st_size);
631 } else {
632 outObjectInfo->size = static_cast<uint32_t>(fileAsset->GetSize()); // need support larger than 4GB file
633 }
634 outObjectInfo->parent = static_cast<uint32_t>(fileAsset->GetParent());
635 outObjectInfo->dateCreated = fileAsset->GetDateAdded() / MILLI_TO_SECOND;
636 outObjectInfo->dateModified = fileAsset->GetDateModified() / MILLI_TO_SECOND;
637 outObjectInfo->storageID = DEFAULT_STORAGE_ID;
638 if (fileAsset->GetMediaType() == MEDIA_TYPE_ALBUM) {
639 outObjectInfo->format = MTP_FORMAT_ASSOCIATION_CODE;
640 } else if (fileAsset->GetMediaType() == MEDIA_TYPE_IMAGE) {
641 outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_1;
642 outObjectInfo->format = MTP_FORMAT_EXIF_JPEG_CODE;
643 outObjectInfo->storageID = DEFAULT_STORAGE_ID;
644 outObjectInfo->imagePixelHeight = static_cast<uint32_t>(fileAsset->GetHeight());
645 outObjectInfo->imagePixelWidth = static_cast<uint32_t>(fileAsset->GetWidth());
646 outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
647 outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
648 outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
649 outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
650 } else if (fileAsset->GetMediaType() == MEDIA_TYPE_VIDEO) {
651 MEDIA_INFO_LOG("SetObjectInfo MEDIA_TYPE_VIDEO");
652 outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_1;
653 outObjectInfo->format = MTP_FORMAT_MPEG_CODE;
654 outObjectInfo->storageID = DEFAULT_STORAGE_ID;
655 outObjectInfo->imagePixelHeight = static_cast<uint32_t>(fileAsset->GetHeight());
656 outObjectInfo->imagePixelWidth = static_cast<uint32_t>(fileAsset->GetWidth());
657 outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
658 outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
659 outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
660 outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
661 }
662 return MtpErrorUtils::SolveGetObjectInfoError(E_SUCCESS);
663 }
664
GetFd(const shared_ptr<MtpOperationContext> & context,int32_t & outFd,const std::string & mode)665 int32_t MtpMedialibraryManager::GetFd(const shared_ptr<MtpOperationContext> &context, int32_t &outFd,
666 const std::string &mode)
667 {
668 CHECK_AND_RETURN_RET_LOG(context != nullptr,
669 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "context is nullptr");
670 MEDIA_DEBUG_LOG("GetFd handle::%{public}u", context->handle);
671 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
672 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
673 shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
674 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
675 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get handles");
676 std::string sourcePath;
677 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
678 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "have no row");
679 string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
680 if (context->handle > COMMON_MOVING_OFFSET) {
681 sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(data);
682 } else {
683 sourcePath = data;
684 }
685 std::string realPath;
686 CHECK_AND_RETURN_RET_LOG(PathToRealPath(sourcePath, realPath),
687 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get realPath");
688 MEDIA_DEBUG_LOG("mtp Getfd realPath %{public}s", realPath.c_str());
689 std::error_code ec;
690 int openMode = (mode.compare(MEDIA_FILEMODE_READWRITE) == 0) ? O_RDWR : O_RDONLY;
691 outFd = open(realPath.c_str(), openMode);
692 if (outFd > 0) {
693 MEDIA_DEBUG_LOG("mtp GetFd outhd %{public}d", outFd);
694 return MtpErrorUtils::SolveGetFdError(E_SUCCESS);
695 } else {
696 return MtpErrorUtils::SolveGetFdError(E_HAS_FS_ERROR);
697 }
698 }
699
GetFdByOpenFile(const shared_ptr<MtpOperationContext> & context,int32_t & outFd)700 int32_t MtpMedialibraryManager::GetFdByOpenFile(const shared_ptr<MtpOperationContext> &context, int32_t &outFd)
701 {
702 CHECK_AND_RETURN_RET_LOG(context != nullptr,
703 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "context is nullptr");
704 MEDIA_DEBUG_LOG("GetFdByOpenFile handle::%{public}u", context->handle);
705 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
706 MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
707 uint32_t id = HandleConvertToAdded(context->handle) % COMMON_PHOTOS_OFFSET;
708 string uri = URI_MTP_OPERATION + "/" + to_string(id);
709 MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
710 Uri openUri(uri);
711 outFd = dataShareHelper_->OpenFile(openUri, MEDIA_FILEMODE_READWRITE);
712
713 if (outFd > 0) {
714 MEDIA_DEBUG_LOG("mtp GetFdByOpenFile outFd %{public}d", outFd);
715 return MtpErrorUtils::SolveGetFdError(E_SUCCESS);
716 } else {
717 return MtpErrorUtils::SolveGetFdError(E_HAS_FS_ERROR);
718 }
719 }
720
CompressImage(std::unique_ptr<PixelMap> & pixelMap,std::vector<uint8_t> & data)721 bool MtpMedialibraryManager::CompressImage(std::unique_ptr<PixelMap> &pixelMap, std::vector<uint8_t> &data)
722 {
723 PackOption option = {
724 .format = THUMBNAIL_FORMAT,
725 .quality = THUMBNAIL_MID,
726 .numberHint = SIZE_ONE
727 };
728 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "pixelMap is nullptr");
729 data.resize(pixelMap->GetByteCount());
730 ImagePacker imagePacker;
731 uint32_t errorCode = imagePacker.StartPacking(data.data(), data.size(), option);
732 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to StartPacking %{public}d", errorCode);
733 errorCode = imagePacker.AddImage(*pixelMap);
734 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to AddImage %{public}d", errorCode);
735 int64_t packedSize = 0;
736 errorCode = imagePacker.FinalizePacking(packedSize);
737 CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to FinalizePacking %{public}d", errorCode);
738
739 data.resize(packedSize);
740 return true;
741 }
742
GetThumb(const shared_ptr<MtpOperationContext> & context,shared_ptr<UInt8List> & outThumb)743 int32_t MtpMedialibraryManager::GetThumb(const shared_ptr<MtpOperationContext> &context,
744 shared_ptr<UInt8List> &outThumb)
745 {
746 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
747 MEDIA_DEBUG_LOG("GetThumb handle::%{public}u", context->handle);
748 if (context->handle < COMMON_PHOTOS_OFFSET) {
749 MEDIA_INFO_LOG("handle is album");
750 return MTP_SUCCESS;
751 }
752 shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
753 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
754 MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
755 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
756 MTP_ERROR_STORE_NOT_AVAILABLE, "have no row");
757 unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
758 CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
759 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
760 unique_ptr<FileAsset> fileAsset = fetchFileResult->GetFirstObject();
761 CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fileAsset is nullptr");
762 std::string dataPath = fileAsset->GetFilePath();
763 if (fileAsset->GetId() < static_cast<int32_t>(COMMON_PHOTOS_OFFSET)) {
764 return MTP_SUCCESS;
765 }
766 int32_t id = fileAsset->GetId() % COMMON_PHOTOS_OFFSET;
767 auto thumbSizeValue = fileAsset->GetStrMember(PhotoColumn::PHOTO_THUMB_SIZE);
768 std::string path = GetThumbUri(id, thumbSizeValue, dataPath);
769 std::string startUri = NORMAL_MEDIA_URI;
770 startUri += to_string(id);
771 if (GetThumbnailFromPath(startUri, outThumb) == MTP_SUCCESS) {
772 MEDIA_DEBUG_LOG("mtp GetThumbnailFromPath SUCESSE");
773 return MTP_SUCCESS;
774 }
775 auto mediaLibraryManager = MediaLibraryManager::GetMediaLibraryManager();
776 CHECK_AND_RETURN_RET_LOG(mediaLibraryManager != nullptr,
777 MTP_ERROR_ACCESS_DENIED, "mediaLibraryManager is nullptr");
778 mediaLibraryManager->InitMediaLibraryManager(getThumbToken_);
779 CHECK_AND_RETURN_RET_LOG(path.size() != 0, MTP_ERROR_NO_THIS_FILE, "path is null");
780 MEDIA_DEBUG_LOG("GetThumb path:%{private}s", path.c_str());
781
782 Uri resultUri(path);
783 auto pixelMap = mediaLibraryManager->GetThumbnail(resultUri);
784 CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetThumbnail failed");
785
786 bool ret = CompressImage(pixelMap, *outThumb);
787 CHECK_AND_RETURN_RET_LOG(ret == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressImage failed");
788 return MTP_SUCCESS;
789 }
790
GetThumbnailFromPath(string & path,shared_ptr<UInt8List> & outThumb)791 int32_t MtpMedialibraryManager::GetThumbnailFromPath(string &path, shared_ptr<UInt8List> &outThumb)
792 {
793 MediaLibraryTracer tracer;
794 tracer.Start("MTP MtpMedialibraryManager::GetThumbnailFromPath");
795 CHECK_AND_RETURN_RET_LOG(outThumb != nullptr, E_ERR, "mtp outThumb is null");
796 CHECK_AND_RETURN_RET_LOG(!path.empty(), E_ERR, "mtp path is null");
797 string openUriStr = path + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_THUMBNAIL + "&" + MEDIA_DATA_DB_WIDTH +
798 "=" + THUMBNAIL_WIDTH + "&" + MEDIA_DATA_DB_HEIGHT + "=" + THUMBNAIL_HEIGHT;
799 MEDIA_DEBUG_LOG("mtp openUriStr::%{public}s", openUriStr.c_str());
800 Uri openUri(openUriStr);
801 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
802 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
803 int32_t fd = dataShareHelper_->OpenFile(openUri, "R");
804 CHECK_AND_RETURN_RET_LOG(fd >= 0, E_ERR, "mtp get fd fail");
805 struct stat fileInfo;
806 if (fstat(fd, &fileInfo) != E_OK) {
807 int32_t ret = close(fd);
808 CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
809 return E_ERR;
810 }
811 outThumb->resize(fileInfo.st_size);
812 ssize_t numBytes = read(fd, outThumb->data(), fileInfo.st_size);
813 if (numBytes == E_ERR) {
814 int32_t ret = close(fd);
815 CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
816 MEDIA_ERR_LOG("mtp fread fail");
817 return E_ERR;
818 }
819 int32_t ret = close(fd);
820 CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
821 return MTP_SUCCESS;
822 }
823
GetThumbUri(const int32_t & id,const std::string & thumbSizeValue,const std::string & dataPath)824 std::string MtpMedialibraryManager::GetThumbUri(const int32_t &id,
825 const std::string &thumbSizeValue, const std::string &dataPath)
826 {
827 std::string startUri = NORMAL_MEDIA_URI;
828 size_t commaPos = dataPath.rfind(".");
829 size_t underlinePos = dataPath.rfind("/");
830 if (commaPos == std::string::npos || underlinePos == std::string::npos || commaPos < underlinePos) {
831 MEDIA_DEBUG_LOG("fail to query datapath");
832 return "";
833 }
834 std::string suffixStr = dataPath.substr(commaPos);
835 std::string lastStr = dataPath.substr(underlinePos, commaPos - underlinePos);
836 startUri += to_string(id);
837 startUri += lastStr;
838 startUri += lastStr;
839 startUri += suffixStr;
840
841 size_t colonPos = thumbSizeValue.find(':');
842 if (colonPos == std::string::npos || colonPos + SIZE_ONE >= thumbSizeValue.size()) {
843 MEDIA_DEBUG_LOG("fail to query thumbnail size");
844 return startUri + "?oper=thumbnail";
845 }
846 std::string widthStr = thumbSizeValue.substr(0, colonPos);
847 std::string heightStr = thumbSizeValue.substr(colonPos + SIZE_ONE);
848
849 return startUri + "?oper=thumbnail" + "&width=" +
850 widthStr + "&height=" + heightStr + "&path=" + dataPath;
851 }
852
CondCloseFd(bool isConditionTrue,const int fd)853 void MtpMedialibraryManager::CondCloseFd(bool isConditionTrue, const int fd)
854 {
855 bool cond = (!isConditionTrue || fd <= 0);
856 CHECK_AND_RETURN_LOG(!cond, "fd error");
857 CHECK_AND_RETURN_LOG(fcntl(fd, F_GETFD) != -1, "fd is already invalid");
858 int32_t ret = close(fd);
859 CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "DealFd CloseFd fail!");
860 }
861
GetPictureThumb(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt8List> & outThumb)862 int32_t MtpMedialibraryManager::GetPictureThumb(const std::shared_ptr<MtpOperationContext> &context,
863 std::shared_ptr<UInt8List> &outThumb)
864 {
865 int fd = 0;
866 int error = GetFd(context, fd, MEDIA_FILEMODE_READONLY);
867 CHECK_AND_RETURN_RET_LOG(error == MTP_SUCCESS, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetFd failed");
868 uint32_t errorCode = 0;
869 SourceOptions opts;
870 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(fd, opts, errorCode);
871 CondCloseFd(imageSource == nullptr, fd);
872 CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "imageSource is nullptr");
873 DecodeOptions decodeOpts;
874 decodeOpts.desiredSize = {
875 .width = NORMAL_WIDTH,
876 .height = NORMAL_HEIGHT
877 };
878 std::unique_ptr<PixelMap> cropPixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
879 CondCloseFd(cropPixelMap == nullptr, fd);
880 CHECK_AND_RETURN_RET_LOG(cropPixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "PixelMap is nullptr");
881
882 bool ret = CompressImage(cropPixelMap, *outThumb);
883 CHECK_AND_RETURN_RET_LOG(ret == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressImage failed");
884 return MTP_SUCCESS;
885 }
886
GetVideoThumb(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt8List> & outThumb)887 int32_t MtpMedialibraryManager::GetVideoThumb(const std::shared_ptr<MtpOperationContext> &context,
888 std::shared_ptr<UInt8List> &outThumb)
889 {
890 int fd = 0;
891 int error = GetFd(context, fd, MEDIA_FILEMODE_READONLY);
892 CHECK_AND_RETURN_RET_LOG(error == MTP_SUCCESS, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetFd failed");
893 shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
894 CHECK_AND_RETURN_RET_LOG(avMetadataHelper != nullptr,
895 MTP_ERROR_NO_THUMBNAIL_PRESENT, "avMetadataHelper is nullptr");
896 struct stat64 st;
897 int32_t ret = fstat64(fd, &st);
898 CondCloseFd(ret != 0, fd);
899 CHECK_AND_RETURN_RET_LOG(ret == 0, MTP_ERROR_NO_THUMBNAIL_PRESENT, "Get file state failed, err %{public}d", errno);
900 int64_t length = static_cast<int64_t>(st.st_size);
901 ret = avMetadataHelper->SetSource(fd, 0, length, AV_META_USAGE_PIXEL_MAP);
902 CondCloseFd(ret != 0, fd);
903 CHECK_AND_RETURN_RET_LOG(ret == 0, MTP_ERROR_NO_THUMBNAIL_PRESENT, "SetSource failed, ret %{public}d", ret);
904 PixelMapParams param;
905 param.colorFormat = PixelFormat::RGBA_8888;
906 param.dstWidth = NORMAL_WIDTH;
907 param.dstHeight = NORMAL_HEIGHT;
908 shared_ptr<PixelMap> sPixelMap = avMetadataHelper->FetchFrameYuv(0,
909 AVMetadataQueryOption::AV_META_QUERY_NEXT_SYNC, param);
910 CondCloseFd(sPixelMap == nullptr, fd);
911 CHECK_AND_RETURN_RET_LOG(sPixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "sPixelMap is nullptr");
912 if (sPixelMap->GetPixelFormat() == PixelFormat::YCBCR_P010) {
913 uint32_t ret = ImageFormatConvert::ConvertImageFormat(sPixelMap, PixelFormat::RGBA_1010102);
914 CondCloseFd(ret != E_OK, fd);
915 CHECK_AND_RETURN_RET_LOG(ret == E_OK, MTP_ERROR_NO_THUMBNAIL_PRESENT,
916 "PixelMapYuv10ToRGBA_1010102: source ConvertImageFormat fail");
917 }
918 InitializationOptions opts = {
919 .pixelFormat = PixelFormat::RGBA_8888,
920 .alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL
921 };
922 unique_ptr<PixelMap> compressImage = PixelMap::Create(*sPixelMap, opts);
923 CondCloseFd(sPixelMap == nullptr, fd);
924 CHECK_AND_RETURN_RET_LOG(compressImage != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "compressImage is nullptr");
925 CloseFdForGet(context, fd);
926 bool retparam = CompressImage(compressImage, *outThumb);
927 CHECK_AND_RETURN_RET_LOG(retparam == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressVideo failed");
928 return MTP_SUCCESS;
929 }
930
GetAssetById(const int32_t id,shared_ptr<FileAsset> & outFileAsset)931 int32_t MtpMedialibraryManager::GetAssetById(const int32_t id, shared_ptr<FileAsset> &outFileAsset)
932 {
933 DataShare::DataSharePredicates predicates;
934 string whereClause = MEDIA_DATA_DB_ID + " = ?";
935 uint32_t field_id = id;
936 if (field_id > COMMON_PHOTOS_OFFSET) {
937 field_id = id - COMMON_PHOTOS_OFFSET;
938 }
939 vector<string> whereArgs = {to_string(field_id)};
940 predicates.SetWhereClause(whereClause);
941 predicates.SetWhereArgs(whereArgs);
942 Uri uri(PAH_QUERY_PHOTO);
943 vector<string> columns;
944 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
945 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
946 shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
947 CHECK_AND_RETURN_RET(resultSet != nullptr, E_NO_SUCH_FILE);
948 unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
949 CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
950 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
951 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
952 E_NO_SUCH_FILE, "no such file");
953 unique_ptr<FileAsset> fileUniAsset = fetchFileResult->GetFirstObject();
954 outFileAsset = move(fileUniAsset);
955 return E_SUCCESS;
956 }
957
GetPathById(const int32_t id,string & outPath)958 int32_t MtpMedialibraryManager::GetPathById(const int32_t id, string &outPath)
959 {
960 shared_ptr<FileAsset> fileAsset;
961 int errCode = GetAssetById(id, fileAsset);
962 CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_HAS_DB_ERROR, "fileAsset is nullptr, assetId: %{public}d", id);
963 outPath = fileAsset->GetPath();
964 return errCode;
965 }
966
GetIdByPath(const std::string & path,uint32_t & outId)967 int32_t MtpMedialibraryManager::GetIdByPath(const std::string &path, uint32_t &outId)
968 {
969 DataShare::DataSharePredicates predicates;
970 string whereClause = MEDIA_DATA_DB_FILE_PATH + " = ?";
971 vector<string> whereArgs = {path};
972 predicates.SetWhereClause(whereClause);
973 predicates.SetWhereArgs(whereArgs);
974 Uri uri(PAH_QUERY_PHOTO);
975 vector<string> columns;
976 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
977 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
978 shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
979 CHECK_AND_RETURN_RET(resultSet != nullptr, E_NO_SUCH_FILE);
980 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
981 MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
982 unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
983 CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
984 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
985 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
986 E_NO_SUCH_FILE, "no such file");
987 unique_ptr<FileAsset> fileUniAsset = fetchFileResult->GetFirstObject();
988 outId = static_cast<uint32_t>(fileUniAsset->GetId());
989 return E_SUCCESS;
990 }
991
SendObjectInfo(const std::shared_ptr<MtpOperationContext> & context,uint32_t & outStorageID,uint32_t & outParent,uint32_t & outHandle)992 int32_t MtpMedialibraryManager::SendObjectInfo(const std::shared_ptr<MtpOperationContext> &context,
993 uint32_t &outStorageID, uint32_t &outParent, uint32_t &outHandle)
994 {
995 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
996 MediaLibraryTracer tracer;
997 tracer.Start("MTP MtpMedialibraryManager::SendObjectInfo");
998 if (context->parent == 0 || context->parent == MTP_ALL_HANDLE_ID) {
999 CHECK_AND_RETURN_RET_LOG(context->format == MTP_FORMAT_ASSOCIATION_CODE,
1000 MTP_ERROR_INVALID_OBJECTHANDLE, "file type not support");
1001 Uri createAlbumUri(MEDIALIBRARY_DATA_URI + "/" + PTP_ALBUM_OPERATION + "/" + OPRN_CREATE);
1002 DataShare::DataShareValuesBucket valuesBucket;
1003 valuesBucket.Put(PhotoAlbumColumns::ALBUM_NAME, context->name);
1004 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1005 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1006 int outRowId = dataShareHelper_->Insert(createAlbumUri, valuesBucket);
1007 CHECK_AND_RETURN_RET_LOG(outRowId > 0,
1008 MtpErrorUtils::SolveSendObjectInfoError(E_HAS_DB_ERROR), "fail to create album");
1009 outHandle = static_cast<uint32_t>(outRowId);
1010 } else {
1011 DataShare::DataShareValuesBucket valuesBucket;
1012 MediaType mediaType;
1013 int errCode = MtpDataUtils::GetMediaTypeByName(context->name, mediaType);
1014 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetMediaTypeByName");
1015 bool cond = ((mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO));
1016 CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTHANDLE, "file type not support");
1017 string uri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CREATEASSET;
1018 MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1019 Uri createFileUri(uri);
1020 valuesBucket.Put(MEDIA_DATA_DB_NAME, context->name);
1021 valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
1022 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1023 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1024 int outRowId = dataShareHelper_->Insert(createFileUri, valuesBucket);
1025 CHECK_AND_RETURN_RET_LOG(outRowId > 0,
1026 MtpErrorUtils::SolveSendObjectInfoError(E_HAS_DB_ERROR), "fail to create assset");
1027 outHandle = static_cast<uint32_t>(outRowId + COMMON_PHOTOS_OFFSET);
1028 }
1029 outStorageID = DEFAULT_STORAGE_ID;
1030 outParent = context->parent;
1031 return MtpErrorUtils::SolveSendObjectInfoError(E_SUCCESS);
1032 }
1033
MoveObject(const std::shared_ptr<MtpOperationContext> & context)1034 int32_t MtpMedialibraryManager::MoveObject(const std::shared_ptr<MtpOperationContext> &context)
1035 {
1036 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1037 if (context->handle < COMMON_PHOTOS_OFFSET) {
1038 MEDIA_DEBUG_LOG("move album is invalid");
1039 return MTP_ERROR_INVALID_OBJECTHANDLE;
1040 }
1041 MediaLibraryTracer tracer;
1042 tracer.Start("MTP MtpMedialibraryManager::MoveObject");
1043 shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
1044 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "resultSet is nullptr");
1045 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1046 MTP_ERROR_INVALID_OBJECTHANDLE, "have no handles");
1047 int errorCode;
1048 int32_t subType = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
1049 int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
1050 uint32_t objectHandle = 0;
1051 if (MtpDataUtils::IsMtpMovingPhoto(subType, effectMode) || subType == static_cast<int32_t>(PhotoSubType::BURST)) {
1052 errorCode = CopyObject(context, objectHandle, true);
1053 CHECK_AND_RETURN_RET_LOG(errorCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "CopyObject failed");
1054 errorCode = DeletePhoto(context, true);
1055 CHECK_AND_RETURN_RET_LOG(errorCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "DeletePhoto failed");
1056 } else {
1057 DataShare::DataSharePredicates predicates;
1058 predicates.EqualTo(PhotoColumn::MEDIA_ID,
1059 to_string(HandleConvertToAdded(context->handle) % COMMON_PHOTOS_OFFSET));
1060 int32_t albumId = GetInt32Val(PARENT, resultSet);
1061 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(albumId));
1062 DataShare::DataShareValuesBucket valuesBuckets;
1063 valuesBuckets.Put(PhotoColumn::PHOTO_OWNER_ALBUM_ID,
1064 static_cast<int32_t>(HandleConvertToAdded(context->parent)));
1065 string uri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + OPRN_BATCH_UPDATE_OWNER_ALBUM_ID;
1066 MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1067 Uri moveAssetsUri(uri);
1068 errorCode = dataShareHelper_->Update(moveAssetsUri, predicates, valuesBuckets);
1069 CHECK_AND_RETURN_RET_LOG(errorCode > 0, MtpErrorUtils::SolveGetHandlesError(errorCode), "Update is fail");
1070 }
1071 return MTP_SUCCESS;
1072 }
1073
GetFileAssetFromPhotosInfo(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<FileAsset> & fileAsset)1074 int32_t MtpMedialibraryManager::GetFileAssetFromPhotosInfo(const std::shared_ptr<MtpOperationContext> &context,
1075 std::shared_ptr<FileAsset> &fileAsset)
1076 {
1077 std::shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
1078 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
1079 MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
1080 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1081 MTP_ERROR_STORE_NOT_AVAILABLE, "have no row");
1082 std::shared_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
1083 CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
1084 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
1085 fileAsset = fetchFileResult->GetFirstObject();
1086 CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fileAsset is nullptr");
1087 return MTP_SUCCESS;
1088 }
1089
GetMovingPhotoVideoPath(const std::string & dataPath,std::string & displayName,std::string & movingPhotoDataPath,MediaType & mediaType)1090 int32_t MtpMedialibraryManager::GetMovingPhotoVideoPath(const std::string &dataPath,
1091 std::string &displayName, std::string &movingPhotoDataPath, MediaType &mediaType)
1092 {
1093 mediaType = MEDIA_TYPE_VIDEO;
1094 movingPhotoDataPath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(dataPath);
1095 MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving movingPhotoDataPath:%{public}s",
1096 movingPhotoDataPath.c_str());
1097 size_t indexPos = displayName.rfind(".");
1098 CHECK_AND_RETURN_RET_LOG(indexPos != std::string::npos, MTP_ERROR_NO_THIS_FILE, "can not find displayname suffix");
1099 if (indexPos + SIZE_ONE >= movingPhotoDataPath.size()) {
1100 MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving movingPhotoDataPath is error");
1101 return E_ERR;
1102 }
1103 displayName.resize(indexPos);
1104 displayName += MOVING_PHOTO_SUFFIX;
1105 MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving displayName:%{private}s", displayName.c_str());
1106 return MTP_SUCCESS;
1107 }
1108
InsertCopyObject(const std::string & displayName,const MediaType & mediaType)1109 int32_t MtpMedialibraryManager::InsertCopyObject(const std::string &displayName, const MediaType &mediaType)
1110 {
1111 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1112 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1113 string uri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CREATEASSET;
1114 MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1115 Uri createFileUri(uri);
1116 DataShare::DataShareValuesBucket valuesBucket;
1117 valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
1118 valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
1119 int insertId = dataShareHelper_->Insert(createFileUri, valuesBucket);
1120 MEDIA_DEBUG_LOG("MTP InsertCopyObject insertId:%{public}d", insertId);
1121 return insertId;
1122 }
1123
CopyAndDumpFile(const std::shared_ptr<MtpOperationContext> & context,const std::string & oldDataPath,std::shared_ptr<FileAsset> & oldFileAsset)1124 int32_t MtpMedialibraryManager::CopyAndDumpFile(const std::shared_ptr<MtpOperationContext> &context,
1125 const std::string &oldDataPath, std::shared_ptr<FileAsset> &oldFileAsset)
1126 {
1127 CHECK_AND_RETURN_RET_LOG(oldFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "oldFileAsset is nullptr");
1128
1129 std::shared_ptr<FileAsset> newFileAsset;
1130 int32_t errCode = GetFileAssetFromPhotosInfo(context, newFileAsset);
1131 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetFileAssetFromPhotosInfo");
1132 CHECK_AND_RETURN_RET_LOG(newFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "newFileAsset is nullptr");
1133
1134 int newFd = 0;
1135 errCode = GetFdByOpenFile(context, newFd);
1136 CHECK_AND_RETURN_RET_LOG((newFd > 0) && (errCode == MTP_SUCCESS), MTP_ERROR_NO_THIS_FILE,
1137 "MTP GetFdByOpenFile open file failed newfd:%{public}d, errCode:%{public}d", newFd, errCode);
1138 bool copyRet = MediaFileUtils::CopyFileUtil(oldDataPath, newFileAsset->GetFilePath());
1139 if (copyRet && errCode == MTP_SUCCESS) {
1140 struct timeval times[PATH_TIMEVAL_MAX] = { { 0, 0 }, { 0, 0 } };
1141 times[0].tv_sec = oldFileAsset->GetDateAdded() / MILLI_TO_SECOND;
1142 times[1].tv_sec = oldFileAsset->GetDateModified() / MILLI_TO_SECOND;
1143 std::string hdfsPath = GetHmdfsPath(newFileAsset->GetFilePath());
1144 if (utimes(hdfsPath.c_str(), times) != 0) {
1145 MEDIA_WARN_LOG("utimes hdfsPath:%{public}s failed", hdfsPath.c_str());
1146 }
1147 errCode = CloseFd(context, newFd);
1148 return errCode;
1149 }
1150 MEDIA_ERR_LOG("MTP oldDataPath:%{public}s copy failed", oldDataPath.c_str());
1151 errCode = close(newFd);
1152 return errCode;
1153 }
1154
CopyObject(const std::shared_ptr<MtpOperationContext> & context,uint32_t & outObjectHandle,bool isForMove)1155 int32_t MtpMedialibraryManager::CopyObject(const std::shared_ptr<MtpOperationContext> &context,
1156 uint32_t &outObjectHandle, bool isForMove)
1157 {
1158 CHECK_AND_RETURN_RET_LOG((context != nullptr) && (context->parent != 0),
1159 MTP_ERROR_INVALID_OBJECTHANDLE, "context is invailed");
1160 CHECK_AND_RETURN_RET_LOG(context->handle > COMMON_PHOTOS_OFFSET, MTP_ERROR_PARAMETER_NOT_SUPPORTED,
1161 "not allow to copy folder in PTP");
1162 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1163 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1164 int32_t errCode = E_ERR;
1165 std::shared_ptr<FileAsset> oldFileAsset;
1166 errCode = GetFileAssetFromPhotosInfo(context, oldFileAsset);
1167 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetFileAssetFromPhotosInfo");
1168 CHECK_AND_RETURN_RET_LOG(oldFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "oldFileAsset is nullptr");
1169 std::string oldDataPath = oldFileAsset->GetFilePath();
1170 context->name = oldFileAsset->GetDisplayName();
1171 MediaType mediaType;
1172 std::string displayName = context->name;
1173 std::string movingPhotoDataPath = oldDataPath;
1174 if (context->handle > COMMON_MOVING_OFFSET) {
1175 errCode = GetMovingPhotoVideoPath(oldDataPath, displayName, movingPhotoDataPath, mediaType);
1176 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetMovingPhotoVideoPath");
1177 } else {
1178 mediaType = oldFileAsset->GetMediaType();
1179 }
1180 bool cond = (mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO) || context->parent == uint32_t(-1);
1181 CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTHANDLE, "file type not support");
1182 int insertId = InsertCopyObject(displayName, mediaType);
1183 CHECK_AND_RETURN_RET_LOG(insertId > 0,
1184 MtpErrorUtils::SolveSendObjectInfoError(E_HAS_DB_ERROR), "fail to create assset");
1185 std::shared_ptr<MtpOperationContext> newFileContext = std::make_shared<MtpOperationContext>();
1186 newFileContext->handle = static_cast<uint32_t>(insertId) + COMMON_PHOTOS_OFFSET;
1187 newFileContext->parent = context->parent;
1188 if (isForMove) {
1189 auto ptpSpecialHandles = PtpSpecialHandles::GetInstance();
1190 CHECK_AND_RETURN_RET_LOG(ptpSpecialHandles != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1191 "ptpSpecialHandles is nullptr");
1192 ptpSpecialHandles->AddHandleToMap(context->handle, newFileContext->handle);
1193 }
1194 errCode = CopyAndDumpFile(newFileContext, movingPhotoDataPath, oldFileAsset);
1195 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to CopyObjectSub");
1196 outObjectHandle = newFileContext->handle;
1197 return MTP_SUCCESS;
1198 }
1199
CheckRenameSuffix(const std::shared_ptr<MtpOperationContext> & context,const std::string & colValueStr)1200 static int32_t CheckRenameSuffix(const std::shared_ptr<MtpOperationContext> &context,
1201 const std::string& colValueStr)
1202 {
1203 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
1204 std::string renameStr = colValueStr;
1205 std::string originalStr = context->name;
1206
1207 size_t renamePos = renameStr.rfind('.');
1208 size_t originalPos = originalStr.rfind('.');
1209 CHECK_AND_RETURN_RET_LOG(renamePos != std::string::npos && originalPos != std::string::npos,
1210 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "suffix is null");
1211 CHECK_AND_RETURN_RET_LOG(renameStr.substr(renamePos) == originalStr.substr(originalPos),
1212 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "suffix is not equal");
1213
1214 return MTP_SUCCESS;
1215 }
1216
CheckVideoOfMovingPhotoSuffix(const std::string & name,std::string & colValueStr)1217 static int32_t CheckVideoOfMovingPhotoSuffix(const std::string& name, std::string& colValueStr)
1218 {
1219 size_t colValueSuffixPoint = colValueStr.rfind('.');
1220 CHECK_AND_RETURN_RET_LOG(colValueSuffixPoint != std::string::npos,
1221 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "colValueStr suffix is null");
1222 std::string colValueSuffix = colValueStr.substr(colValueSuffixPoint);
1223 if (colValueSuffix == MOVING_PHOTO_SUFFIX) {
1224 size_t nameSuffixPoint = name.rfind('.');
1225 CHECK_AND_RETURN_RET_LOG(nameSuffixPoint != std::string::npos,
1226 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "name suffix is null");
1227 std::string nameSuffix = name.substr(nameSuffixPoint);
1228 colValueStr = colValueStr.substr(0, colValueSuffixPoint) + nameSuffix;
1229 }
1230 return MTP_SUCCESS;
1231 }
1232
GetPhotoName(const std::shared_ptr<MtpOperationContext> & context)1233 int32_t MtpMedialibraryManager::GetPhotoName(const std::shared_ptr<MtpOperationContext> &context)
1234 {
1235 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
1236 Uri uri(MEDIALIBRARY_DATA_URI + "/" + PAH_PHOTO + "/" + OPRN_QUERY);
1237 vector<string> columns;
1238 columns.push_back(MediaColumn::MEDIA_NAME);
1239 DataSharePredicates predicates;
1240 predicates.EqualTo(MediaColumn::MEDIA_ID,
1241 to_string(HandleConvertToAdded(context->handle) % COMMON_PHOTOS_OFFSET));
1242 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1243 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1244 auto resultSet = dataShareHelper_->Query(uri, predicates, columns);
1245 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
1246 MtpErrorUtils::SolveDeleteObjectError(E_NO_SUCH_FILE), "fail to get albummInfo");
1247 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1248 MtpErrorUtils::SolveDeleteObjectError(E_SUCCESS), "have no handles");
1249 context->name = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
1250 resultSet->Close();
1251 return MTP_SUCCESS;
1252 }
1253
SetPhotoObjectPropValue(const std::shared_ptr<MtpOperationContext> & context,std::string & colValueStr)1254 int32_t MtpMedialibraryManager::SetPhotoObjectPropValue(const std::shared_ptr<MtpOperationContext> &context,
1255 std::string& colValueStr)
1256 {
1257 CHECK_AND_RETURN_RET_LOG(MediaFileUtils::CheckDisplayName(colValueStr) == E_OK,
1258 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "violate the naming rules");
1259 CHECK_AND_RETURN_RET_LOG(GetPhotoName(context) == MTP_SUCCESS,
1260 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "get photo name fail");
1261 CHECK_AND_RETURN_RET_LOG(CheckVideoOfMovingPhotoSuffix(context->name, colValueStr) == MTP_SUCCESS,
1262 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "get photo name fail");
1263 CHECK_AND_RETURN_RET_LOG(CheckRenameSuffix(context, colValueStr) == MTP_SUCCESS,
1264 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "rename media asset fail");
1265 string updateUri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + OPRN_UPDATE;
1266 MediaFileUtils::UriAppendKeyValue(updateUri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1267 Uri updateAssetUri(updateUri);
1268 DataSharePredicates predicates;
1269 DataShareValuesBucket valuesBucket;
1270 valuesBucket.Put(MediaColumn::MEDIA_NAME, colValueStr);
1271 valuesBucket.Put(MediaColumn::MEDIA_TITLE, MediaFileUtils::GetTitleFromDisplayName(colValueStr));
1272 predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(context->handle % COMMON_PHOTOS_OFFSET));
1273
1274 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1275 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1276 int32_t changedRows = dataShareHelper_->Update(updateAssetUri, predicates, valuesBucket);
1277 CHECK_AND_RETURN_RET_LOG(changedRows > 0,
1278 MtpErrorUtils::SolveCloseFdError(E_HAS_DB_ERROR), "fail to update file");
1279
1280 return MTP_SUCCESS;
1281 }
1282
SetAlbumObjectPropValue(const std::shared_ptr<MtpOperationContext> & context,std::string & colValueStr)1283 int32_t MtpMedialibraryManager::SetAlbumObjectPropValue(const std::shared_ptr<MtpOperationContext> &context,
1284 std::string& colValueStr)
1285 {
1286 CHECK_AND_RETURN_RET_LOG(MediaFileUtils::CheckAlbumName(colValueStr) == E_OK,
1287 MTP_ERROR_INVALID_OBJECTPROP_VALUE, "violate the naming rules");
1288 DataSharePredicates predicates;
1289 DataShareValuesBucket valuesBucket;
1290 valuesBucket.Put(PhotoAlbumColumns::ALBUM_NAME, colValueStr);
1291 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(HandleConvertToAdded(context->handle)));
1292
1293 Uri uri(MEDIALIBRARY_DATA_URI + "/" + PTP_ALBUM_OPERATION + "/" + OPRN_ALBUM_SET_NAME);
1294 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1295 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1296 int32_t errCode = dataShareHelper_->Update(uri, predicates, valuesBucket);
1297 CHECK_AND_RETURN_RET_LOG(errCode > 0 && errCode != NativeRdb::E_INVALID_ARGS,
1298 MtpErrorUtils::SolveCloseFdError(E_HAS_DB_ERROR), "fail to update albumName");
1299 Uri queryUri(PAH_QUERY_PHOTO_ALBUM);
1300 vector<string> columns;
1301 columns.push_back(PhotoAlbumColumns::ALBUM_ID);
1302 DataSharePredicates queryPredicates;
1303 queryPredicates.EqualTo(PhotoAlbumColumns::ALBUM_NAME, colValueStr);
1304 auto resultSet = dataShareHelper_->Query(queryUri, queryPredicates, columns);
1305 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
1306 MtpErrorUtils::SolveDeleteObjectError(E_NO_SUCH_FILE), "fail to get albummInfo");
1307 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1308 MtpErrorUtils::SolveDeleteObjectError(E_NO_SUCH_FILE), "have no handles");
1309 int32_t newAlbumId = GetInt32Val(PhotoAlbumColumns::ALBUM_ID, resultSet);
1310 resultSet->Close();
1311 auto ptpSpecialHandles = PtpSpecialHandles::GetInstance();
1312 CHECK_AND_RETURN_RET_LOG(ptpSpecialHandles != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1313 "ptpSpecialHandles is nullptr");
1314 ptpSpecialHandles->AddHandleToMap(context->handle, newAlbumId);
1315
1316 return MTP_SUCCESS;
1317 }
1318
SetObjectPropValue(const std::shared_ptr<MtpOperationContext> & context)1319 int32_t MtpMedialibraryManager::SetObjectPropValue(const std::shared_ptr<MtpOperationContext> &context)
1320 {
1321 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
1322 MediaLibraryTracer tracer;
1323 tracer.Start("MTP MtpMedialibraryManager::SetObjectPropValue");
1324 std::string colName("");
1325 std::variant<int64_t, std::string> colValue;
1326 int32_t errCode = MtpDataUtils::SolveSetObjectPropValueData(context, colName, colValue);
1327 CHECK_AND_RETURN_RET_LOG(errCode == 0, errCode, "fail to SolveSetObjectPropValueData");
1328 CHECK_AND_RETURN_RET_LOG(colName.compare(MEDIA_DATA_DB_PARENT_ID) != 0, E_INVALID_FILEID, "colName is invaild");
1329 CHECK_AND_RETURN_RET_LOG(std::get_if<std::string>(&colValue) != nullptr, E_INVALID_FILEID, "colName is invaild");
1330 CHECK_AND_RETURN_RET_LOG(std::get<std::string>(colValue) != "", E_INVALID_FILEID, "colName is invaild");
1331 std::string colValueStr = std::get<std::string>(colValue);
1332 if (context->handle > COMMON_PHOTOS_OFFSET) {
1333 return SetPhotoObjectPropValue(context, colValueStr);
1334 } else {
1335 return SetAlbumObjectPropValue(context, colValueStr);
1336 }
1337 return MTP_SUCCESS;
1338 }
1339
CloseFdForGet(const std::shared_ptr<MtpOperationContext> & context,int32_t fd)1340 int32_t MtpMedialibraryManager::CloseFdForGet(const std::shared_ptr<MtpOperationContext> &context, int32_t fd)
1341 {
1342 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1343 MEDIA_INFO_LOG("CloseFd handle::%{public}u", context->handle);
1344 CHECK_AND_RETURN_RET_LOG(fcntl(fd, F_GETFD) != -1, E_ERR, "fd is already invalid");
1345 CHECK_AND_RETURN_RET_LOG(fd > 0, E_ERR, "wrong fd");
1346 int errCode = close(fd);
1347 return MtpErrorUtils::SolveCloseFdError(errCode);
1348 }
1349
CloseFd(const shared_ptr<MtpOperationContext> & context,int32_t fd)1350 int32_t MtpMedialibraryManager::CloseFd(const shared_ptr<MtpOperationContext> &context, int32_t fd)
1351 {
1352 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1353 MEDIA_INFO_LOG("CloseFd handle::%{public}u", context->handle);
1354 int32_t errCode = E_SUCCESS;
1355 CHECK_AND_RETURN_RET_LOG(fd > 0, E_ERR, "wrong fd");
1356 if (context->handle > EDITED_PHOTOS_OFFSET) {
1357 errCode = close(fd);
1358 return MtpErrorUtils::SolveCloseFdError(errCode);
1359 }
1360 shared_ptr<FileAsset> fileAsset;
1361 errCode = GetAssetById(HandleConvertToAdded(context->handle), fileAsset);
1362 CHECK_AND_RETURN_RET_LOG(errCode == E_SUCCESS,
1363 MtpErrorUtils::SolveCloseFdError(errCode), "fail to GetAssetById");
1364 DataShare::DataShareValuesBucket valuesBucket;
1365 valuesBucket.Put(MEDIA_DATA_DB_URI, MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CLOSEASSET +
1366 "/" + to_string(HandleConvertToAdded(context->handle) % COMMON_PHOTOS_OFFSET));
1367 CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fileAsset is nullptr");
1368 MEDIA_INFO_LOG("CloseFd %{public}s, FilePath %{public}s", fileAsset->GetUri().c_str(),
1369 fileAsset->GetFilePath().c_str());
1370 Uri closeAssetUri(MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CLOSEASSET);
1371 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1372 MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1373 if (close(fd) == MTP_SUCCESS) {
1374 errCode = dataShareHelper_->Insert(closeAssetUri, valuesBucket);
1375 }
1376 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to Close file");
1377 DataShare::DataShareValuesBucket valuesBucketForOwnerAlbumId;
1378 string uri = URI_MTP_OPERATION + "/" + OPRN_UPDATE_OWNER_ALBUM_ID;
1379 MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1380 Uri updateOwnerAlbumIdUri(uri);
1381 DataShare::DataSharePredicates predicates;
1382 predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(context->handle - COMMON_PHOTOS_OFFSET));
1383 valuesBucketForOwnerAlbumId.Put(PhotoColumn::PHOTO_OWNER_ALBUM_ID, static_cast<int32_t>(context->parent));
1384 int32_t changedRows = dataShareHelper_->Update(updateOwnerAlbumIdUri, predicates, valuesBucketForOwnerAlbumId);
1385 CHECK_AND_RETURN_RET_LOG(changedRows > 0,
1386 MtpErrorUtils::SolveCloseFdError(E_HAS_DB_ERROR), "fail to update owneralbumid");
1387 return MtpErrorUtils::SolveCloseFdError(E_SUCCESS);
1388 }
1389
GetObjectPropList(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<std::vector<Property>> & outProps)1390 int32_t MtpMedialibraryManager::GetObjectPropList(const std::shared_ptr<MtpOperationContext> &context,
1391 std::shared_ptr<std::vector<Property>> &outProps)
1392 {
1393 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1394 if (context->property == 0) {
1395 CHECK_AND_RETURN_RET_LOG(context->groupCode != 0, MTP_ERROR_PARAMETER_NOT_SUPPORTED, "groupCode error");
1396 MEDIA_ERR_LOG("context property = 0");
1397 return MTP_ERROR_SPECIFICATION_BY_GROUP_UNSUPPORTED;
1398 }
1399 shared_ptr<DataShare::DataShareResultSet> resultSet;
1400 if (context->handle < COMMON_PHOTOS_OFFSET) {
1401 context->parent = PARENT_ID;
1402 }
1403 if (context->parent == PARENT_ID && context->handle < COMMON_PHOTOS_OFFSET) {
1404 resultSet = GetAlbumInfo(context, false);
1405 } else {
1406 resultSet = GetPhotosInfo(context, false);
1407 }
1408 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
1409 MTP_ERROR_INVALID_OBJECTHANDLE, "fail to getSet");
1410 return MtpDataUtils::GetPropListBySet(context, resultSet, outProps);
1411 }
1412
GetObjectPropValue(const shared_ptr<MtpOperationContext> & context,uint64_t & outIntVal,uint128_t & outLongVal,string & outStrVal)1413 int32_t MtpMedialibraryManager::GetObjectPropValue(const shared_ptr<MtpOperationContext> &context,
1414 uint64_t &outIntVal, uint128_t &outLongVal, string &outStrVal)
1415 {
1416 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1417 shared_ptr<DataShare::DataShareResultSet> resultSet;
1418 if (context->parent == PARENT_ID || context->parent == PTP_IN_MTP_ID) {
1419 resultSet = GetAlbumInfo(context, false);
1420 } else {
1421 resultSet = GetPhotosInfo(context, false);
1422 }
1423 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to getSet");
1424 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1425 MTP_ERROR_INVALID_OBJECTHANDLE, "have no row");
1426 PropertyValue propValue;
1427 bool isVideoOfMovingPhoto = static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) == MOVING_PHOTO_TYPE;
1428 int32_t errCode = MtpDataUtils::GetPropValueBySet(context->property, resultSet, propValue, isVideoOfMovingPhoto);
1429 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to get GetPropValueBySet");
1430 outIntVal = propValue.outIntVal;
1431 outStrVal = propValue.outStrVal;
1432 return errCode;
1433 }
1434
DeleteAlbum(const std::shared_ptr<MtpOperationContext> & context)1435 int32_t MtpMedialibraryManager::DeleteAlbum(const std::shared_ptr<MtpOperationContext> &context)
1436 {
1437 CHECK_AND_RETURN_RET_LOG(context != nullptr,
1438 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "context is nullptr");
1439 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1440 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1441 int32_t errCode = E_ERR;
1442 DataShare::DataSharePredicates predicates;
1443 string deleteUri = MEDIALIBRARY_DATA_URI + "/" + PTP_ALBUM_OPERATION + "/" + OPRN_DELETE;
1444 Uri uri(deleteUri);
1445 predicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, to_string(HandleConvertToAdded(context->handle)));
1446 string queryUriStr = MEDIALIBRARY_DATA_URI + "/" + PAH_ALBUM + "/" + OPRN_QUERY;
1447 Uri queryUri(queryUriStr);
1448 std::vector<string> columns;
1449 columns.push_back(PhotoAlbumColumns::ALBUM_ID);
1450 columns.push_back(PhotoAlbumColumns::ALBUM_TYPE);
1451 auto resultSet = dataShareHelper_->Query(queryUri, predicates, columns);
1452 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MtpErrorUtils::SolveDeleteObjectError(E_ERR),
1453 "resultSet is nullptr");
1454 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1455 MtpErrorUtils::SolveDeleteObjectError(E_ERR), "resultSet is nullptr");
1456 int32_t albumType = GetInt32Val(PhotoAlbumColumns::ALBUM_TYPE, resultSet);
1457 resultSet->Close();
1458 if (albumType == static_cast<int32_t>(PhotoAlbumType::SOURCE)) {
1459 MEDIA_DEBUG_LOG("can not delete source photo album");
1460 return MtpErrorUtils::SolveDeleteObjectError(E_ERR);
1461 }
1462 errCode = dataShareHelper_->Delete(uri, predicates);
1463 CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, MtpErrorUtils::SolveDeleteObjectError(E_ERR), "Delete album fail");
1464 return MTP_SUCCESS;
1465 }
1466
DeleteObject(const std::shared_ptr<MtpOperationContext> & context)1467 int32_t MtpMedialibraryManager::DeleteObject(const std::shared_ptr<MtpOperationContext> &context)
1468 {
1469 CHECK_AND_RETURN_RET_LOG(context != nullptr,
1470 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "context is nullptr");
1471 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1472 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1473 MEDIA_INFO_LOG("MtpMedialibraryManager::DeleteObject handle:%{public}d, parent:%{public}d",
1474 context->handle, context ->parent);
1475 MediaLibraryTracer tracer;
1476 tracer.Start("MTP MtpMedialibraryManager::DeleteObject");
1477 if (context->handle < COMMON_PHOTOS_OFFSET) {
1478 int32_t errCode = DeleteAlbum(context);
1479 CHECK_AND_RETURN_RET_LOG(errCode == E_SUCCESS, MtpErrorUtils::SolveDeleteObjectError(errCode),
1480 "MtpMedialibraryManager::DeleteAlbum failed!");
1481 return MtpErrorUtils::SolveCloseFdError(E_SUCCESS);
1482 }
1483 int32_t errCode = DeletePhoto(context, false);
1484 CHECK_AND_RETURN_RET_LOG(errCode == E_SUCCESS, MtpErrorUtils::SolveDeleteObjectError(errCode),
1485 "MtpMedialibraryManager::DeletePhoto failed!");
1486 return MtpErrorUtils::SolveDeleteObjectError(E_SUCCESS);
1487 }
1488
DeletePhoto(const std::shared_ptr<MtpOperationContext> & context,bool isForMove)1489 int32_t MtpMedialibraryManager::DeletePhoto(const std::shared_ptr<MtpOperationContext> &context, bool isForMove)
1490 {
1491 CHECK_AND_RETURN_RET_LOG(context != nullptr,
1492 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "context is nullptr");
1493 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1494 MtpErrorUtils::SolveDeleteObjectError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1495 string deleteUri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + OPRN_DELETE;
1496 MediaFileUtils::UriAppendKeyValue(deleteUri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1497 Uri uri(deleteUri);
1498 shared_ptr<DataShare::DataShareResultSet> resultSet;
1499 uint32_t actualHandle = 0;
1500 DataShare::DataSharePredicates predicates;
1501 if (isForMove) {
1502 resultSet = GetPhotosInfoForMove(context);
1503 actualHandle = context->handle;
1504 } else {
1505 resultSet = GetPhotosInfo(context, false);
1506 actualHandle = HandleConvertToAdded(context->handle);
1507 }
1508 predicates.EqualTo(PhotoColumn::MEDIA_ID, static_cast<int32_t>(actualHandle % COMMON_PHOTOS_OFFSET));
1509
1510 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to getSet");
1511 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1512 MTP_ERROR_INVALID_OBJECTHANDLE, "have no row");
1513
1514 int32_t subType = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
1515 int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
1516 resultSet->Close();
1517 if (MtpDataUtils::IsMtpMovingPhoto(subType, effectMode)) {
1518 deletedMovingPhotoHandles_.insert(actualHandle);
1519 if (deletedMovingPhotoHandles_.count((actualHandle % COMMON_PHOTOS_OFFSET) + COMMON_PHOTOS_OFFSET) == 0 ||
1520 deletedMovingPhotoHandles_.count((actualHandle % COMMON_PHOTOS_OFFSET) + COMMON_MOVING_OFFSET) == 0) {
1521 return MtpErrorUtils::SolveCloseFdError(E_SUCCESS);
1522 }
1523 }
1524 int32_t ret = dataShareHelper_->Delete(uri, predicates);
1525 MEDIA_DEBUG_LOG("MtpMedialibraryManager::DeletePhoto ret:%{public}d", ret);
1526 CHECK_AND_RETURN_RET_LOG(ret >= 0, MtpErrorUtils::SolveDeleteObjectError(E_ERR), "delete photo fail");
1527 return E_SUCCESS;
1528 }
1529
DeleteCanceledObject(uint32_t id)1530 void MtpMedialibraryManager::DeleteCanceledObject(uint32_t id)
1531 {
1532 CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr,
1533 "MtpMedialibraryManager::DeleteCanceledObject fail to get datasharehelpe");
1534
1535 string trashUri = PAH_TRASH_PHOTO;
1536 MediaFileUtils::UriAppendKeyValue(trashUri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1537 Uri trashAssetUri(trashUri);
1538 DataShare::DataShareValuesBucket valuesBucketTrashed;
1539 valuesBucketTrashed.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
1540 DataShare::DataSharePredicates predicatesTrashed;
1541 predicatesTrashed.EqualTo(MediaColumn::MEDIA_ID, to_string(HandleConvertToAdded(id) % COMMON_PHOTOS_OFFSET));
1542 dataShareHelper_->Update(trashAssetUri, predicatesTrashed, valuesBucketTrashed);
1543 MEDIA_INFO_LOG("Update file date_trashed SUCCESS");
1544
1545 std::string deleteUriStr = TOOL_DELETE_PHOTO;
1546 MediaFileUtils::UriAppendKeyValue(deleteUriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1547 Uri deleteUri(deleteUriStr);
1548 DataShare::DataSharePredicates predicates;
1549 predicates.EqualTo(MediaColumn::MEDIA_ID, to_string(HandleConvertToAdded(id) % COMMON_PHOTOS_OFFSET));
1550 DataShare::DataShareValuesBucket valuesBucket;
1551 valuesBucket.Put(PhotoColumn::MEDIA_DATE_TRASHED, DATE_UNTRASHED);
1552 dataShareHelper_->Update(deleteUri, predicates, valuesBucket);
1553 MEDIA_INFO_LOG("DeleteCaneledObject SUCCESS");
1554 }
1555
GetAlbumName(uint32_t fileId,std::string & albumName)1556 int32_t MtpMedialibraryManager::GetAlbumName(uint32_t fileId, std::string &albumName)
1557 {
1558 MEDIA_DEBUG_LOG("MtpMedialibraryManager::%{public}s is called", __func__);
1559 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "datasharehelper is null");
1560 Uri uri(PAH_QUERY_PHOTO_ALBUM);
1561 std::vector<std::string> column;
1562 column.push_back(MEDIA_DATA_DB_ALBUM_NAME);
1563 DataShare::DataSharePredicates albumPredicates;
1564 albumPredicates.EqualTo(PhotoAlbumColumns::ALBUM_ID, std::to_string(fileId));
1565 auto resultSet = dataShareHelper_->Query(uri, albumPredicates, column);
1566 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get albumName");
1567 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, MTP_ERROR_STORE_NOT_AVAILABLE, "no row");
1568 albumName = GetStringVal(MEDIA_DATA_DB_ALBUM_NAME, resultSet);
1569 resultSet->Close();
1570 return MTP_SUCCESS;
1571 }
1572
GetCopyAlbumObjectPath(uint32_t handle,PathMap & paths)1573 int32_t MtpMedialibraryManager::GetCopyAlbumObjectPath(uint32_t handle, PathMap &paths)
1574 {
1575 MEDIA_DEBUG_LOG("MtpMedialibraryManager::%{public}s is called", __func__);
1576 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "datasharehelper is null");
1577
1578 Uri uri(PAH_QUERY_PHOTO);
1579 DataShare::DataSharePredicates predicates;
1580 std::vector<std::string> burstKeys = GetBurstKeyFromPhotosInfo();
1581 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(handle));
1582 predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
1583 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, DEFAULT_PREDICATE);
1584 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, DEFAULT_PREDICATE);
1585 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, DEFAULT_PREDICATE);
1586 if (!burstKeys.empty()) {
1587 predicates.BeginWrap()
1588 ->BeginWrap()
1589 ->NotIn(PhotoColumn::PHOTO_BURST_KEY, burstKeys)
1590 ->Or()->IsNull(PhotoColumn::PHOTO_BURST_KEY)
1591 ->EndWrap()
1592 ->Or()->EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL)
1593 ->EndWrap();
1594 }
1595 auto resultSet = dataShareHelper_->Query(uri, predicates, g_photoColumns);
1596 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
1597 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, MTP_SUCCESS, "no row");
1598
1599 do {
1600 auto path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
1601 auto displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
1602 auto subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
1603 auto effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
1604 // if moving photo, add moving photo video
1605 if (MtpDataUtils::IsMtpMovingPhoto(subtype, effectMode)) {
1606 auto sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(path);
1607 auto name = GetMovingPhotoVideoDisplayName(displayName, sourcePath);
1608 paths.emplace(std::move(sourcePath), std::move(name));
1609 }
1610 paths.emplace(std::move(path), std::move(displayName));
1611 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
1612 resultSet->Close();
1613 return MTP_SUCCESS;
1614 }
1615
GetCopyPhotoObjectPath(uint32_t handle,PathMap & paths)1616 int32_t MtpMedialibraryManager::GetCopyPhotoObjectPath(uint32_t handle, PathMap &paths)
1617 {
1618 MEDIA_DEBUG_LOG("MtpMedialibraryManager::%{public}s is called", __func__);
1619 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "datasharehelper is null");
1620
1621 Uri uri(PAH_QUERY_PHOTO);
1622 DataShare::DataSharePredicates predicates;
1623 int32_t file_id = static_cast<int32_t>(handle % COMMON_PHOTOS_OFFSET);
1624 predicates.EqualTo(PhotoColumn::MEDIA_ID, std::to_string(file_id));
1625
1626 auto resultSet = dataShareHelper_->Query(uri, predicates, g_photoColumns);
1627 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
1628 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, MTP_SUCCESS, "no row");
1629
1630 do {
1631 auto path = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
1632 auto displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
1633 // moving photo video
1634 if (handle > COMMON_MOVING_OFFSET) {
1635 auto sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(std::move(path));
1636 auto name = GetMovingPhotoVideoDisplayName(std::move(displayName), sourcePath);
1637 paths.emplace(std::move(sourcePath), std::move(name));
1638 } else {
1639 paths.emplace(std::move(path), std::move(displayName));
1640 }
1641 } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
1642 resultSet->Close();
1643 return MTP_SUCCESS;
1644 }
1645
GetCopyObjectPath(uint32_t handle,PathMap & paths)1646 int32_t MtpMedialibraryManager::GetCopyObjectPath(uint32_t handle, PathMap &paths)
1647 {
1648 MEDIA_DEBUG_LOG("MtpMedialibraryManager::%{public}s is called", __func__);
1649 if (handle < COMMON_PHOTOS_OFFSET) {
1650 return GetCopyAlbumObjectPath(handle, paths);
1651 }
1652 return GetCopyPhotoObjectPath(handle, paths);
1653 }
1654
CountPhotosNumber(const std::shared_ptr<MtpOperationContext> & context,FileCountInfo & fileCountInfo)1655 void MtpMedialibraryManager::CountPhotosNumber(const std::shared_ptr<MtpOperationContext> &context,
1656 FileCountInfo &fileCountInfo)
1657 {
1658 CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
1659 string albumName;
1660 int32_t errCode = GetAlbumName(context->parent, albumName);
1661 CHECK_AND_RETURN_LOG(errCode == MTP_SUCCESS, "GetAlbumName failed");
1662 if (albumName.empty()) {
1663 MEDIA_ERR_LOG("GetAlbumName failed");
1664 } else {
1665 if (albumName.size() > ALBUM_NAME_MAX) {
1666 albumName = albumName.substr(0, ALBUM_NAME_MAX);
1667 }
1668 fileCountInfo.albumName = albumName;
1669 }
1670 int32_t cloudPhotoCount = GetCloudPhotoCountFromAlbum(context);
1671 fileCountInfo.onlyInCloudPhotoCount = (cloudPhotoCount < 0) ? 0 : cloudPhotoCount;
1672 MtpDfxReporter::GetInstance().DoFileCountInfoStatistics(fileCountInfo);
1673 }
1674
GetCloudPhotoCountFromAlbum(const std::shared_ptr<MtpOperationContext> & context)1675 int32_t MtpMedialibraryManager::GetCloudPhotoCountFromAlbum(const std::shared_ptr<MtpOperationContext> &context)
1676 {
1677 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1678 CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_HAS_DB_ERROR,
1679 "GetCloudPhotoCountFromAlbum fail to get datasharehelper");
1680 Uri uri(PAH_QUERY_PHOTO);
1681 DataShare::DataSharePredicates predicates;
1682 predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(context->parent));
1683 predicates.EqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
1684 predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
1685 predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
1686 predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
1687 predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL);
1688 predicates.EqualTo(MediaColumn::MEDIA_TYPE, MEDIA_PHOTO_TYPE);
1689 shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, g_photoColumns);
1690 CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_HAS_DB_ERROR, "have no row");
1691 int32_t count = 0;
1692 CHECK_AND_RETURN_RET_LOG(resultSet->GetRowCount(count) == NativeRdb::E_OK, E_HAS_DB_ERROR,
1693 "Cannot get row count of resultset");
1694 resultSet->Close();
1695 return count;
1696 }
1697 // LCOV_EXCL_STOP
1698 } // namespace Media
1699 } // namespace OHOS
1700