• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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