• 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 "system_ability_definition.h"
45 #include "userfilemgr_uri.h"
46 
47 using namespace std;
48 
49 namespace OHOS {
50 namespace Media {
51 
52 sptr<IRemoteObject> MtpMedialibraryManager::getThumbToken_ = nullptr;
53 constexpr int32_t NORMAL_WIDTH = 256;
54 constexpr int32_t NORMAL_HEIGHT = 256;
55 const string THUMBNAIL_WIDTH = "256";
56 const string THUMBNAIL_HEIGHT = "256";
57 constexpr int32_t COMPRE_SIZE_LEVEL_1 = 256;
58 constexpr int32_t COMPRE_SIZE_LEVEL_2 = 204800;
59 constexpr size_t SIZE_ONE = 1;
60 const string NORMAL_MEDIA_URI = "file://media/Photo/";
61 const string THUMBNAIL_FORMAT = "image/jpeg";
62 static constexpr uint8_t THUMBNAIL_MID = 90;
63 constexpr int32_t PARENT_ID = 0;
64 const string API_VERSION = "api_version";
65 const string POSITION_CLOUD_FLAG = "2";
66 const string IS_LOCAL = "2";
67 const string ALBUM_MEDIA_TYPE = "7";
68 const int64_t DATE_UNTRASHED = 0;
69 const int32_t SPECIAL_PTHOTO_TYPE = 2;
70 const std::string PARENT = "parent";
71 const std::string HIDDEN_ALBUM = ".hiddenAlbum";
72 const string BURST_COVER_LEVEL = "1";
73 const string EMPTY_COLUMN_NAME = "0";
74 const string PARENT_ID_STRING = "0";
75 const std::string MOVING_PHOTO_SUFFIX = ".mp4";
76 constexpr int32_t MILLI_TO_SECOND = 1000;
77 constexpr int32_t PATH_TIMEVAL_MAX = 2;
78 constexpr int32_t MOVING_PHOTO_TYPE = 3;
79 namespace {
80 std::vector<std::string> g_photoColumns = {
81     MediaColumn::MEDIA_ID + " + " + to_string(COMMON_PHOTOS_OFFSET) + " as " + MEDIA_DATA_DB_ID,
82     MediaColumn::MEDIA_SIZE,
83     MediaColumn::MEDIA_NAME,
84     PhotoColumn::PHOTO_OWNER_ALBUM_ID +" as " + PARENT,
85     MediaColumn::MEDIA_DATE_ADDED,
86     MediaColumn::MEDIA_DURATION,
87     MediaColumn::MEDIA_TYPE,
88     MediaColumn::MEDIA_FILE_PATH,
89     PhotoColumn::PHOTO_SUBTYPE,
90     PhotoColumn::MEDIA_DATE_MODIFIED,
91     PhotoColumn::PHOTO_THUMB_SIZE,
92 };
93 const std::string ZERO = "0";
94 } // namespace
95 
96 std::shared_ptr<MtpMedialibraryManager> MtpMedialibraryManager::instance_ = nullptr;
97 std::mutex MtpMedialibraryManager::mutex_;
98 shared_ptr<DataShare::DataShareHelper> MtpMedialibraryManager::dataShareHelper_ = nullptr;
99 std::shared_ptr<MediaSyncObserver> mediaPhotoObserver_ = nullptr;
100 
GetHmdfsPath(const std::string & path)101 std::string MtpMedialibraryManager::GetHmdfsPath(const std::string &path)
102 {
103     const std::string FILES = "/files/";
104     const std::string HMDFS_DIR = "/mnt/hmdfs/100/account/device_view/local";
105     size_t filesPos = path.find(FILES);
106     if (filesPos == std::string::npos) {
107         MEDIA_WARN_LOG("path:%{public}s", path.c_str());
108         return path;
109     }
110     return HMDFS_DIR + path.substr(filesPos);
111 }
112 
MtpMedialibraryManager(void)113 MtpMedialibraryManager::MtpMedialibraryManager(void)
114 {
115 }
116 
~MtpMedialibraryManager(void)117 MtpMedialibraryManager::~MtpMedialibraryManager(void)
118 {
119 }
120 
GetInstance()121 std::shared_ptr<MtpMedialibraryManager> MtpMedialibraryManager::GetInstance()
122 {
123     if (instance_ == nullptr) {
124         std::lock_guard<std::mutex> lock(mutex_);
125         if (instance_ == nullptr) {
126             instance_ = std::make_shared<MtpMedialibraryManager>();
127         }
128     }
129     return instance_;
130 }
131 
Init(const sptr<IRemoteObject> & token,const std::shared_ptr<MtpOperationContext> & context)132 void MtpMedialibraryManager::Init(const sptr<IRemoteObject> &token, const std::shared_ptr<MtpOperationContext> &context)
133 {
134     std::lock_guard<std::mutex> lock(mutex_);
135     if (dataShareHelper_ == nullptr) {
136         dataShareHelper_ = DataShare::DataShareHelper::Creator(token, MEDIALIBRARY_DATA_URI);
137     }
138     if (mediaPhotoObserver_ == nullptr) {
139         mediaPhotoObserver_ = std::make_shared<MediaSyncObserver>();
140     }
141     CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr, "fail to get dataShareHelper");
142     CHECK_AND_RETURN_LOG(mediaPhotoObserver_ != nullptr, "fail to get mediaPhotoObserver");
143     getThumbToken_ = token;
144     mediaPhotoObserver_->context_ = context;
145     mediaPhotoObserver_->dataShareHelper_ = dataShareHelper_;
146     mediaPhotoObserver_->StartNotifyThread();
147     dataShareHelper_->RegisterObserverExt(Uri(PhotoColumn::PHOTO_URI_PREFIX), mediaPhotoObserver_, true);
148     dataShareHelper_->RegisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_URI_PREFIX), mediaPhotoObserver_, true);
149 }
150 
Clear()151 void MtpMedialibraryManager::Clear()
152 {
153     MEDIA_INFO_LOG("MtpMediaLibrary::Ptp Clear is called");
154     std::lock_guard<std::mutex> lock(mutex_);
155     if (mediaPhotoObserver_ != nullptr) {
156         mediaPhotoObserver_->StopNotifyThread();
157     }
158     if (dataShareHelper_ != nullptr) {
159         dataShareHelper_->UnregisterObserverExt(Uri(PhotoColumn::PHOTO_URI_PREFIX), mediaPhotoObserver_);
160         dataShareHelper_->UnregisterObserverExt(Uri(PhotoAlbumColumns::ALBUM_URI_PREFIX), mediaPhotoObserver_);
161     }
162     mediaPhotoObserver_ = nullptr;
163     dataShareHelper_ = nullptr;
164 }
165 
GetHandles(int32_t parentId,vector<int> & outHandles,MediaType mediaType)166 int32_t MtpMedialibraryManager::GetHandles(int32_t parentId, vector<int> &outHandles, MediaType mediaType)
167 {
168     shared_ptr<DataShare::DataShareResultSet> resultSet;
169     DataShare::DataSharePredicates predicates;
170     vector<string> columns;
171     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
172         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
173     if (parentId == PARENT_ID) {
174         Uri uri(PAH_QUERY_PHOTO_ALBUM);
175         columns.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
176         columns.push_back(PhotoAlbumColumns::ALBUM_NAME + " as " + MEDIA_DATA_DB_NAME);
177         columns.push_back(ALBUM_MEDIA_TYPE + " as " + MEDIA_DATA_DB_MEDIA_TYPE);
178         columns.push_back(PhotoAlbumColumns::ALBUM_DATE_MODIFIED);
179         columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_SIZE);
180         columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_PARENT_ID);
181         columns.push_back(PhotoAlbumColumns::ALBUM_DATE_ADDED);
182         predicates.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
183         predicates.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
184         predicates.NotEqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
185         resultSet = dataShareHelper_->Query(uri, predicates, columns);
186     } else {
187         Uri uri(PAH_QUERY_PHOTO);
188         columns.push_back(MediaColumn::MEDIA_ID + " + " + to_string(COMMON_PHOTOS_OFFSET) + " as " + MEDIA_DATA_DB_ID);
189         columns.push_back(MediaColumn::MEDIA_SIZE);
190         columns.push_back(MediaColumn::MEDIA_NAME);
191         columns.push_back(PhotoColumn::PHOTO_OWNER_ALBUM_ID +" as " + PARENT);
192         columns.push_back(MediaColumn::MEDIA_DATE_ADDED);
193         columns.push_back(MediaColumn::MEDIA_DURATION);
194         columns.push_back(MediaColumn::MEDIA_TYPE);
195         columns.push_back(PhotoColumn::PHOTO_SUBTYPE);
196         columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_NAME);
197         DataShare::DataSharePredicates predicates;
198         predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(parentId));
199         predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
200         predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
201         predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
202         predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
203         resultSet = dataShareHelper_->Query(uri, predicates, columns);
204     }
205     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
206         MtpErrorUtils::SolveGetHandlesError(E_NO_SUCH_FILE), "fail to get handles");
207     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
208         MtpErrorUtils::SolveGetHandlesError(E_SUCCESS), "have no handles");
209     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
210         int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
211         outHandles.push_back(id);
212     }
213     resultSet->GoToFirstRow();
214     return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
215 }
216 
GetAlbumCloud()217 int32_t MtpMedialibraryManager::GetAlbumCloud()
218 {
219     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
220         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
221     DataShare::DataSharePredicates predicatesCloud;
222     Uri uri(PAH_QUERY_PHOTO_ALBUM);
223     vector<string> columnsCloud;
224     columnsCloud.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
225     predicatesCloud.EqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
226     shared_ptr<DataShare::DataShareResultSet> resultSetcloud = dataShareHelper_->Query(uri, predicatesCloud,
227         columnsCloud);
228     CHECK_AND_RETURN_RET_LOG(resultSetcloud != nullptr,
229         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to GetAlbumCloud");
230     int cloudCount = 0;
231     resultSetcloud->GetRowCount(cloudCount);
232     MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumCloud cloudCount:%{public}d", cloudCount);
233     resultSetcloud->Close();
234     return MTP_SUCCESS;
235 }
236 
GetAlbumCloudDisplay(vector<string> & ownerAlbumIds)237 int32_t MtpMedialibraryManager::GetAlbumCloudDisplay(vector<string> &ownerAlbumIds)
238 {
239     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
240         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
241     DataShare::DataSharePredicates predicatesCloudDisplay;
242     vector<string> columnsCloudDisplay;
243     Uri uri(PAH_QUERY_PHOTO_ALBUM);
244     columnsCloudDisplay.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
245     predicatesCloudDisplay.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
246     predicatesCloudDisplay.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
247     predicatesCloudDisplay.EqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
248     predicatesCloudDisplay.In(PhotoAlbumColumns::ALBUM_ID, ownerAlbumIds);
249     shared_ptr<DataShare::DataShareResultSet> resultSetcloudDisplay = dataShareHelper_->Query(uri,
250         predicatesCloudDisplay, columnsCloudDisplay);
251     CHECK_AND_RETURN_RET_LOG(resultSetcloudDisplay != nullptr,
252         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to GetAlbumCloudDisplay");
253     int cloudCountDisplay = 0;
254     resultSetcloudDisplay->GetRowCount(cloudCountDisplay);
255     MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumCloudDisplay cloudCountDisplay:%{public}d", cloudCountDisplay);
256     resultSetcloudDisplay->Close();
257     return MTP_SUCCESS;
258 }
259 
GetAlbumInfo(const shared_ptr<MtpOperationContext> & context,bool isHandle)260 shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetAlbumInfo(
261     const shared_ptr<MtpOperationContext> &context, bool isHandle)
262 {
263     CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "context is nullptr");
264     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr, "GetAlbumInfo fail to get datasharehelper");
265     DataShare::DataSharePredicates predicates;
266     Uri uri(PAH_QUERY_PHOTO_ALBUM);
267     vector<string> columns;
268     columns.push_back(PhotoAlbumColumns::ALBUM_ID + " as " + MEDIA_DATA_DB_ID);
269     columns.push_back(PhotoAlbumColumns::ALBUM_NAME + " as " + MEDIA_DATA_DB_NAME);
270     columns.push_back(ALBUM_MEDIA_TYPE + " as " + MEDIA_DATA_DB_MEDIA_TYPE);
271     columns.push_back(PhotoAlbumColumns::ALBUM_DATE_MODIFIED);
272     columns.push_back(PARENT_ID_STRING + " as " + PARENT);
273     columns.push_back(EMPTY_COLUMN_NAME + " as " + MEDIA_DATA_DB_SIZE);
274     columns.push_back(PhotoAlbumColumns::ALBUM_DATE_ADDED);
275     if (!isHandle) {
276         predicates.EqualTo(MEDIA_DATA_DB_ALBUM_ID, to_string(context->handle));
277         return dataShareHelper_->Query(uri, predicates, columns);
278     }
279     vector<string> ownerAlbumIds;
280     shared_ptr<DataShare::DataShareResultSet> resultSet = GetOwnerAlbumIdList();
281     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, nullptr, "fail to GetPhotosInfo");
282     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
283         string ownerAlbumId = GetStringVal(PhotoColumn::PHOTO_OWNER_ALBUM_ID, resultSet);
284         ownerAlbumIds.push_back(ownerAlbumId);
285     }
286     int32_t errCode = GetAlbumCloud();
287     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, nullptr, "fail to GetAlbumCloud");
288     errCode = GetAlbumCloudDisplay(ownerAlbumIds);
289     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, nullptr, "fail to GetAlbumCloudDisplay");
290     predicates.BeginWrap();
291     predicates.IsNotNull(MEDIA_DATA_DB_ALBUM_NAME);
292     predicates.NotEqualTo(MEDIA_DATA_DB_ALBUM_NAME, HIDDEN_ALBUM);
293     predicates.BeginWrap();
294     predicates.NotEqualTo(MEDIA_DATA_DB_IS_LOCAL, IS_LOCAL);
295     predicates.Or();
296     predicates.IsNull(MEDIA_DATA_DB_IS_LOCAL);
297     predicates.EndWrap();
298     predicates.EndWrap();
299     predicates.Or();
300     predicates.In(PhotoAlbumColumns::ALBUM_ID, ownerAlbumIds);
301     shared_ptr<DataShare::DataShareResultSet> resultSetAll = dataShareHelper_->Query(uri, predicates, columns);
302     CHECK_AND_RETURN_RET_LOG(resultSetAll != nullptr, nullptr, "fail to GetAlbumInfo");
303     int count = 0;
304     resultSetAll->GetRowCount(count);
305     MEDIA_INFO_LOG("MtpMedialibraryManager::GetAlbumInfo count:%{public}d", count);
306     return resultSetAll;
307 }
308 
GetOwnerAlbumIdList()309 std::shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetOwnerAlbumIdList()
310 {
311     Uri uri(PAH_QUERY_PHOTO);
312     vector<string> columns;
313     columns.push_back(PhotoColumn::PHOTO_OWNER_ALBUM_ID);
314     DataShare::DataSharePredicates predicates;
315     predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
316     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
317     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
318     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
319     predicates.Distinct();
320     return dataShareHelper_->Query(uri, predicates, columns);
321 }
322 
GetPhotosInfo(const shared_ptr<MtpOperationContext> & context,bool isHandle)323 shared_ptr<DataShare::DataShareResultSet> MtpMedialibraryManager::GetPhotosInfo(
324     const shared_ptr<MtpOperationContext> &context, bool isHandle)
325 {
326     CHECK_AND_RETURN_RET_LOG(context != nullptr, nullptr, "context is nullptr");
327     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr,
328         "MtpMedialibraryManager::GetPhotosInfo fail to get datasharehelper");
329     Uri uri(PAH_QUERY_PHOTO);
330     DataShare::DataSharePredicates predicates;
331     if (isHandle) {
332         vector<string> burstKeys = GetBurstKeyFromPhotosInfo();
333         predicates.EqualTo(PhotoColumn::PHOTO_OWNER_ALBUM_ID, to_string(context->parent));
334         predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
335         predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, "0");
336         predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, "0");
337         predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, "0");
338         if (!burstKeys.empty()) {
339             predicates.BeginWrap()
340                 ->BeginWrap()
341                 ->NotIn(PhotoColumn::PHOTO_BURST_KEY, burstKeys)
342                 ->Or()
343                 ->IsNull(PhotoColumn::PHOTO_BURST_KEY)
344                 ->EndWrap()
345                 ->Or()
346                 ->EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL)
347                 ->EndWrap();
348         }
349     } else {
350         int32_t file_id = static_cast<int32_t>(context->handle % COMMON_PHOTOS_OFFSET);
351         predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(file_id));
352     }
353     return dataShareHelper_->Query(uri, predicates, g_photoColumns);
354 }
355 
GetBurstKeyFromPhotosInfo()356 vector<string> MtpMedialibraryManager::GetBurstKeyFromPhotosInfo()
357 {
358     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, vector<string>(),
359         "MtpMedialibraryManager::GetBurstKeyFromPhotosInfo fail to get datasharehelper");
360     vector<string> bustKeys;
361     Uri uri(PAH_QUERY_PHOTO);
362     vector<string> columns;
363     columns.push_back(PhotoColumn::PHOTO_BURST_KEY);
364     DataShare::DataSharePredicates predicates;
365     predicates.NotEqualTo(PhotoColumn::MEDIA_DATE_TRASHED, "0");
366     predicates.EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL);
367     predicates.IsNotNull(PhotoColumn::PHOTO_BURST_KEY);
368     shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
369     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
370         vector<string>(), "fail to get handles");
371     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
372         vector<string>(), "have no handles");
373     do {
374         string bustKey = GetStringVal(PhotoColumn::PHOTO_BURST_KEY, resultSet);
375         bustKeys.push_back(bustKey);
376     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
377     return bustKeys;
378 }
379 
HaveMovingPhotesHandle(const shared_ptr<DataShare::DataShareResultSet> resultSet,shared_ptr<UInt32List> & outHandles,const uint32_t parent)380 int32_t MtpMedialibraryManager::HaveMovingPhotesHandle(const shared_ptr<DataShare::DataShareResultSet> resultSet,
381     shared_ptr<UInt32List> &outHandles, const uint32_t parent)
382 {
383     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_HAS_DB_ERROR, "resultSet is nullptr");
384 
385     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS, "have no handles");
386     do {
387         uint32_t id = static_cast<uint32_t>(GetInt32Val(MediaColumn::MEDIA_ID, resultSet));
388         outHandles->push_back(id);
389         if (id < COMMON_PHOTOS_OFFSET) {
390             continue;
391         }
392         int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
393         if (subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) {
394             uint32_t videoId = id + (COMMON_MOVING_OFFSET - COMMON_PHOTOS_OFFSET);
395             outHandles->push_back(videoId);
396         }
397     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
398     return E_SUCCESS;
399 }
400 
GetHandles(const shared_ptr<MtpOperationContext> & context,shared_ptr<UInt32List> & outHandles)401 int32_t MtpMedialibraryManager::GetHandles(const shared_ptr<MtpOperationContext> &context,
402     shared_ptr<UInt32List> &outHandles)
403 {
404     string extension;
405     MediaType mediaType;
406     CHECK_AND_RETURN_RET_LOG(context != nullptr,
407         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "context is nullptr");
408     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
409         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
410     int32_t errCode = MtpDataUtils::SolveHandlesFormatData(context->format, extension, mediaType);
411     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS,
412         MtpErrorUtils::SolveGetHandlesError(errCode), "fail to SolveHandlesFormatData");
413     shared_ptr<DataShare::DataShareResultSet> resultSet;
414     if (context->parent == PARENT_ID) {
415         resultSet = GetAlbumInfo(context, true);
416         auto albumHandles = PtpAlbumHandles::GetInstance();
417         if (albumHandles != nullptr) {
418             albumHandles->AddAlbumHandles(resultSet);
419         }
420         CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
421             MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get handles");
422         CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS, "have no handles");
423         do {
424             int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
425             outHandles->push_back(id);
426         } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
427         return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
428     }
429     resultSet = GetPhotosInfo(context, true);
430     errCode = HaveMovingPhotesHandle(resultSet, outHandles, context->parent);
431     return MtpErrorUtils::SolveGetHandlesError(errCode);
432 }
433 
GetAllHandles(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt32List> & out)434 int32_t MtpMedialibraryManager::GetAllHandles(
435     const std::shared_ptr<MtpOperationContext> &context, std::shared_ptr<UInt32List> &out)
436 {
437     CHECK_AND_RETURN_RET_LOG((context != nullptr && dataShareHelper_ != nullptr && out != nullptr),
438         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "context is nullptr");
439     auto resultSet = GetAlbumInfo(context, true);
440     auto albumHandles = PtpAlbumHandles::GetInstance();
441     if (albumHandles != nullptr) {
442         albumHandles->AddAlbumHandles(resultSet);
443     }
444     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr && resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS,
445         "have no handles");
446     do {
447         int32_t id = GetInt32Val(MediaColumn::MEDIA_ID, resultSet);
448         out->push_back(id);
449     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
450 
451     DataShare::DataSharePredicates predicates;
452     predicates.NotEqualTo(PhotoColumn::PHOTO_POSITION, POSITION_CLOUD_FLAG);
453     predicates.EqualTo(MediaColumn::MEDIA_DATE_TRASHED, ZERO);
454     predicates.EqualTo(MediaColumn::MEDIA_TIME_PENDING, ZERO);
455     predicates.EqualTo(MediaColumn::MEDIA_HIDDEN, ZERO);
456 
457     auto burstKeys = GetBurstKeyFromPhotosInfo();
458     if (!burstKeys.empty()) {
459         predicates.BeginWrap()
460             ->BeginWrap()
461             ->NotIn(PhotoColumn::PHOTO_BURST_KEY, burstKeys)
462             ->Or()->IsNull(PhotoColumn::PHOTO_BURST_KEY)
463             ->EndWrap()
464             ->Or()->EqualTo(PhotoColumn::PHOTO_BURST_COVER_LEVEL, BURST_COVER_LEVEL)
465             ->EndWrap();
466     }
467 
468     Uri uri(PAH_QUERY_PHOTO);
469     resultSet = dataShareHelper_->Query(uri, predicates, g_photoColumns);
470     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr && resultSet->GoToFirstRow() == NativeRdb::E_OK, E_SUCCESS,
471         "have no handles");
472     do {
473         uint32_t id = static_cast<uint32_t>(GetInt32Val(MediaColumn::MEDIA_ID, resultSet));
474         out->push_back(id);
475         if (id < COMMON_PHOTOS_OFFSET) {
476             continue;
477         }
478         int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
479         if (subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) {
480             uint32_t videoId = id + (COMMON_MOVING_OFFSET - COMMON_PHOTOS_OFFSET);
481             out->push_back(videoId);
482         }
483     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
484     return MtpErrorUtils::SolveGetHandlesError(E_SUCCESS);
485 }
486 
GetObjectInfo(const shared_ptr<MtpOperationContext> & context,shared_ptr<ObjectInfo> & outObjectInfo)487 int32_t MtpMedialibraryManager::GetObjectInfo(const shared_ptr<MtpOperationContext> &context,
488     shared_ptr<ObjectInfo> &outObjectInfo)
489 {
490     CHECK_AND_RETURN_RET_LOG(context != nullptr,
491         MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "context is nullptr");
492     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
493         MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "fail to get datasharehelper");
494     DataShare::DataSharePredicates predicates;
495     MEDIA_INFO_LOG("GetObjectInfo %{public}d,%{public}d", context->handle, context ->parent);
496     shared_ptr<DataShare::DataShareResultSet> resultSet;
497     if (context->parent == PARENT_ID && context->handle < COMMON_PHOTOS_OFFSET) {
498         resultSet = GetAlbumInfo(context, false);
499     } else {
500         resultSet = GetPhotosInfo(context, false);
501     }
502     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
503         MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "fail to get object set");
504     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
505         MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "have no handles");
506     return SetObject(resultSet, context, outObjectInfo);
507 }
508 
GetSizeFromOfft(const off_t & size)509 uint32_t MtpMedialibraryManager::GetSizeFromOfft(const off_t &size)
510 {
511     return size > std::numeric_limits<uint32_t>::max() ? std::numeric_limits<uint32_t>::max() : size;
512 }
513 
SetObject(const std::shared_ptr<DataShare::DataShareResultSet> & resultSet,const shared_ptr<MtpOperationContext> & context,std::shared_ptr<ObjectInfo> & outObjectInfo)514 int32_t MtpMedialibraryManager::SetObject(const std::shared_ptr<DataShare::DataShareResultSet> &resultSet,
515     const shared_ptr<MtpOperationContext> &context, std::shared_ptr<ObjectInfo> &outObjectInfo)
516 {
517     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
518     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
519         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "resultSet is nullptr");
520     do {
521         if (static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) < SPECIAL_PTHOTO_TYPE) {
522             unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
523             CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
524                 MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
525             unique_ptr<FileAsset> fileAsset = fetchFileResult->GetFirstObject();
526             return SetObjectInfo(fileAsset, outObjectInfo);
527         }
528         string display_name = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
529         string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
530         int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
531         string sourcePath = MtpDataUtils::GetMovingOrEnditSourcePath(data, subtype, context);
532         if (sourcePath.empty()) {
533             MEDIA_ERR_LOG("MtpMedialibraryManager::SetObject get sourcePath failed");
534             return MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE);
535         }
536         outObjectInfo->handle = context->handle;
537         outObjectInfo->name = display_name;
538         outObjectInfo->parent = context->parent;
539         outObjectInfo->storageID = context->storageID;
540         struct stat statInfo;
541         CHECK_AND_RETURN_RET_LOG(stat(sourcePath.c_str(), &statInfo) == 0,
542             MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE),
543             "MtpMedialibraryManager::SetObject stat failed");
544         outObjectInfo->size = GetSizeFromOfft(statInfo.st_size);
545         outObjectInfo->dateCreated = statInfo.st_ctime;
546         outObjectInfo->dateModified = statInfo.st_mtime;
547         outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
548         outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
549         outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
550         outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
551     } while (resultSet->GoToNextRow() == NativeRdb::E_OK);
552     return MtpErrorUtils::SolveGetObjectInfoError(E_SUCCESS);
553 }
554 
SetObjectInfo(const unique_ptr<FileAsset> & fileAsset,shared_ptr<ObjectInfo> & outObjectInfo)555 int32_t MtpMedialibraryManager::SetObjectInfo(const unique_ptr<FileAsset> &fileAsset,
556     shared_ptr<ObjectInfo> &outObjectInfo)
557 {
558     CHECK_AND_RETURN_RET_LOG(outObjectInfo != nullptr,
559         MtpErrorUtils::SolveGetObjectInfoError(E_HAS_DB_ERROR), "outObjectInfo is nullptr");
560     outObjectInfo->handle = static_cast<uint32_t>(fileAsset->GetId());
561     outObjectInfo->name = fileAsset->GetDisplayName();
562     if (fileAsset->GetPhotoSubType() == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO) &&
563         fileAsset->GetMediaType() != MEDIA_TYPE_ALBUM) {
564         struct stat statInfo;
565         CHECK_AND_RETURN_RET_LOG(stat(fileAsset->GetPath().c_str(), &statInfo) == 0,
566             MtpErrorUtils::SolveGetObjectInfoError(E_NO_SUCH_FILE), "SetObjectInfo stat failed");
567         outObjectInfo->size = GetSizeFromOfft(statInfo.st_size);
568     } else {
569         outObjectInfo->size = static_cast<uint32_t>(fileAsset->GetSize()); // need support larger than 4GB file
570     }
571     outObjectInfo->parent = static_cast<uint32_t>(fileAsset->GetParent());
572     outObjectInfo->dateCreated = fileAsset->GetDateAdded() / MILLI_TO_SECOND;
573     outObjectInfo->dateModified = fileAsset->GetDateModified() / MILLI_TO_SECOND;
574     outObjectInfo->storageID = DEFAULT_STORAGE_ID;
575     if (fileAsset->GetMediaType() == MEDIA_TYPE_ALBUM) {
576         outObjectInfo->format = MTP_FORMAT_ASSOCIATION_CODE;
577     } else if (fileAsset->GetMediaType() == MEDIA_TYPE_IMAGE) {
578         outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_1;
579         outObjectInfo->format = MTP_FORMAT_EXIF_JPEG_CODE;
580         outObjectInfo->storageID = DEFAULT_STORAGE_ID;
581         outObjectInfo->imagePixelHeight = static_cast<uint32_t>(fileAsset->GetHeight());
582         outObjectInfo->imagePixelWidth = static_cast<uint32_t>(fileAsset->GetWidth());
583         outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
584         outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
585         outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
586         outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
587     } else if (fileAsset->GetMediaType() == MEDIA_TYPE_VIDEO) {
588         MEDIA_INFO_LOG("SetObjectInfo MEDIA_TYPE_VIDEO");
589         outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_1;
590         outObjectInfo->format = MTP_FORMAT_MPEG_CODE;
591         outObjectInfo->storageID = DEFAULT_STORAGE_ID;
592         outObjectInfo->imagePixelHeight = static_cast<uint32_t>(fileAsset->GetHeight());
593         outObjectInfo->imagePixelWidth = static_cast<uint32_t>(fileAsset->GetWidth());
594         outObjectInfo->thumbCompressedSize = COMPRE_SIZE_LEVEL_2;
595         outObjectInfo->thumbFormat = MTP_FORMAT_EXIF_JPEG_CODE;
596         outObjectInfo->thumbPixelHeight = NORMAL_HEIGHT;
597         outObjectInfo->thumbPixelWidth = NORMAL_WIDTH;
598     }
599     return MtpErrorUtils::SolveGetObjectInfoError(E_SUCCESS);
600 }
601 
GetFd(const shared_ptr<MtpOperationContext> & context,int32_t & outFd,const std::string & mode)602 int32_t MtpMedialibraryManager::GetFd(const shared_ptr<MtpOperationContext> &context, int32_t &outFd,
603     const std::string &mode)
604 {
605     CHECK_AND_RETURN_RET_LOG(context != nullptr,
606         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "context is nullptr");
607     MEDIA_DEBUG_LOG("GetFd  handle::%{public}u", context->handle);
608     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
609         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
610     shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
611     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
612         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get handles");
613     std::string sourcePath;
614     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
615         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "have no row");
616     string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
617     if (context->handle > COMMON_MOVING_OFFSET) {
618         sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(data);
619     } else {
620         sourcePath = data;
621     }
622     std::string realPath;
623     CHECK_AND_RETURN_RET_LOG(PathToRealPath(sourcePath, realPath),
624         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get realPath");
625     MEDIA_DEBUG_LOG("mtp Getfd realPath %{public}s", realPath.c_str());
626     std::error_code ec;
627     int openMode = (mode.compare(MEDIA_FILEMODE_READWRITE) == 0) ? O_RDWR : O_RDONLY;
628     outFd = open(realPath.c_str(), openMode);
629     if (outFd > 0) {
630         MEDIA_DEBUG_LOG("mtp GetFd outhd %{public}d", outFd);
631         return MtpErrorUtils::SolveGetFdError(E_SUCCESS);
632     } else {
633         return MtpErrorUtils::SolveGetFdError(E_HAS_FS_ERROR);
634     }
635 }
636 
GetFdByOpenFile(const shared_ptr<MtpOperationContext> & context,int32_t & outFd)637 int32_t MtpMedialibraryManager::GetFdByOpenFile(const shared_ptr<MtpOperationContext> &context, int32_t &outFd)
638 {
639     CHECK_AND_RETURN_RET_LOG(context != nullptr,
640         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "context is nullptr");
641     MEDIA_DEBUG_LOG("GetFdByOpenFile  handle::%{public}u", context->handle);
642     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
643         MtpErrorUtils::SolveGetFdError(E_HAS_DB_ERROR), "fail to get datasharehelper");
644     uint32_t id = context->handle % COMMON_PHOTOS_OFFSET;
645     string uri = URI_MTP_OPERATION + "/" + to_string(id);
646     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
647     Uri openUri(uri);
648     outFd = dataShareHelper_->OpenFile(openUri, MEDIA_FILEMODE_READWRITE);
649 
650     if (outFd > 0) {
651         MEDIA_DEBUG_LOG("mtp GetFdByOpenFile outFd %{public}d", outFd);
652         return MtpErrorUtils::SolveGetFdError(E_SUCCESS);
653     } else {
654         return MtpErrorUtils::SolveGetFdError(E_HAS_FS_ERROR);
655     }
656 }
657 
CompressImage(std::unique_ptr<PixelMap> & pixelMap,std::vector<uint8_t> & data)658 bool MtpMedialibraryManager::CompressImage(std::unique_ptr<PixelMap> &pixelMap, std::vector<uint8_t> &data)
659 {
660     PackOption option = {
661         .format = THUMBNAIL_FORMAT,
662         .quality = THUMBNAIL_MID,
663         .numberHint = SIZE_ONE
664     };
665     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "pixelMap is nullptr");
666     data.resize(pixelMap->GetByteCount());
667     ImagePacker imagePacker;
668     uint32_t errorCode = imagePacker.StartPacking(data.data(), data.size(), option);
669     CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to StartPacking %{public}d", errorCode);
670     errorCode = imagePacker.AddImage(*pixelMap);
671     CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to AddImage %{public}d", errorCode);
672     int64_t packedSize = 0;
673     errorCode = imagePacker.FinalizePacking(packedSize);
674     CHECK_AND_RETURN_RET_LOG(errorCode == E_SUCCESS, false, "Failed to FinalizePacking %{public}d", errorCode);
675 
676     data.resize(packedSize);
677     return true;
678 }
679 
GetThumb(const shared_ptr<MtpOperationContext> & context,shared_ptr<UInt8List> & outThumb)680 int32_t MtpMedialibraryManager::GetThumb(const shared_ptr<MtpOperationContext> &context,
681     shared_ptr<UInt8List> &outThumb)
682 {
683     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
684     MEDIA_DEBUG_LOG("GetThumb handle::%{public}u", context->handle);
685     if (context->handle < COMMON_PHOTOS_OFFSET) {
686         MEDIA_INFO_LOG("handle is album");
687         return MTP_SUCCESS;
688     }
689     shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
690     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
691         MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
692     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
693         MTP_ERROR_STORE_NOT_AVAILABLE, "have no row");
694     unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
695     CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
696         MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
697     unique_ptr<FileAsset> fileAsset = fetchFileResult->GetFirstObject();
698     CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fileAsset is nullptr");
699     std::string dataPath = fileAsset->GetFilePath();
700     if (fileAsset->GetId() < static_cast<int32_t>(COMMON_PHOTOS_OFFSET)) {
701         return MTP_SUCCESS;
702     }
703     int32_t id = fileAsset->GetId() % COMMON_PHOTOS_OFFSET;
704     auto thumbSizeValue = fileAsset->GetStrMember(PhotoColumn::PHOTO_THUMB_SIZE);
705     std::string path = GetThumbUri(id, thumbSizeValue, dataPath);
706     std::string startUri = NORMAL_MEDIA_URI;
707     startUri += to_string(id);
708     if (GetThumbnailFromPath(startUri, outThumb) == MTP_SUCCESS) {
709         MEDIA_DEBUG_LOG("mtp GetThumbnailFromPath SUCESSE");
710         return MTP_SUCCESS;
711     }
712     auto mediaLibraryManager = MediaLibraryManager::GetMediaLibraryManager();
713     CHECK_AND_RETURN_RET_LOG(mediaLibraryManager != nullptr,
714         MTP_ERROR_ACCESS_DENIED, "mediaLibraryManager is nullptr");
715     mediaLibraryManager->InitMediaLibraryManager(getThumbToken_);
716     CHECK_AND_RETURN_RET_LOG(path.size() != 0, MTP_ERROR_NO_THIS_FILE, "path is null");
717     MEDIA_DEBUG_LOG("GetThumb path:%{private}s", path.c_str());
718 
719     Uri resultUri(path);
720     auto pixelMap = mediaLibraryManager->GetThumbnail(resultUri);
721     CHECK_AND_RETURN_RET_LOG(pixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetThumbnail failed");
722 
723     bool ret = CompressImage(pixelMap, *outThumb);
724     CHECK_AND_RETURN_RET_LOG(ret == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressImage failed");
725     return MTP_SUCCESS;
726 }
727 
GetThumbnailFromPath(string & path,shared_ptr<UInt8List> & outThumb)728 int32_t MtpMedialibraryManager::GetThumbnailFromPath(string &path, shared_ptr<UInt8List> &outThumb)
729 {
730     MediaLibraryTracer tracer;
731     tracer.Start("MTP MtpMedialibraryManager::GetThumbnailFromPath");
732     CHECK_AND_RETURN_RET_LOG(outThumb != nullptr, E_ERR, "mtp outThumb is null");
733     CHECK_AND_RETURN_RET_LOG(!path.empty(), E_ERR, "mtp path is null");
734     string openUriStr = path + "?" + MEDIA_OPERN_KEYWORD + "=" + MEDIA_DATA_DB_THUMBNAIL + "&" + MEDIA_DATA_DB_WIDTH +
735         "=" + THUMBNAIL_WIDTH + "&" + MEDIA_DATA_DB_HEIGHT + "=" + THUMBNAIL_HEIGHT;
736     MEDIA_DEBUG_LOG("mtp openUriStr::%{public}s", openUriStr.c_str());
737     Uri openUri(openUriStr);
738     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
739         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
740     int32_t fd = dataShareHelper_->OpenFile(openUri, "R");
741     CHECK_AND_RETURN_RET_LOG(fd >= 0, E_ERR, "mtp get fd fail");
742     struct stat fileInfo;
743     if (fstat(fd, &fileInfo) != E_OK) {
744         int32_t ret = close(fd);
745         CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
746         return E_ERR;
747     }
748     outThumb->resize(fileInfo.st_size);
749     ssize_t numBytes = read(fd, outThumb->data(), fileInfo.st_size);
750     if (numBytes == E_ERR) {
751         int32_t ret = close(fd);
752         CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
753         MEDIA_ERR_LOG("mtp fread fail");
754         return E_ERR;
755     }
756     int32_t ret = close(fd);
757     CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "CloseFd fail!");
758     return MTP_SUCCESS;
759 }
760 
GetThumbUri(const int32_t & id,const std::string & thumbSizeValue,const std::string & dataPath)761 std::string MtpMedialibraryManager::GetThumbUri(const int32_t &id,
762     const std::string &thumbSizeValue, const std::string &dataPath)
763 {
764     std::string startUri = NORMAL_MEDIA_URI;
765     size_t commaPos = dataPath.rfind(".");
766     size_t underlinePos = dataPath.rfind("/");
767     if (commaPos == std::string::npos || underlinePos == std::string::npos || commaPos < underlinePos) {
768         MEDIA_DEBUG_LOG("fail to query datapath");
769         return "";
770     }
771     std::string suffixStr = dataPath.substr(commaPos);
772     std::string lastStr = dataPath.substr(underlinePos, commaPos - underlinePos);
773     startUri += to_string(id);
774     startUri += lastStr;
775     startUri += lastStr;
776     startUri += suffixStr;
777 
778     size_t colonPos = thumbSizeValue.find(':');
779     if (colonPos == std::string::npos || colonPos + SIZE_ONE >= thumbSizeValue.size()) {
780         MEDIA_DEBUG_LOG("fail to query thumbnail size");
781         return startUri + "?oper=thumbnail";
782     }
783     std::string widthStr = thumbSizeValue.substr(0, colonPos);
784     std::string heightStr = thumbSizeValue.substr(colonPos + SIZE_ONE);
785 
786     return startUri + "?oper=thumbnail" + "&width=" +
787         widthStr + "&height=" + heightStr + "&path=" + dataPath;
788 }
789 
CondCloseFd(bool isConditionTrue,const int fd)790 void MtpMedialibraryManager::CondCloseFd(bool isConditionTrue, const int fd)
791 {
792     bool cond = (!isConditionTrue || fd <= 0);
793     CHECK_AND_RETURN_LOG(!cond, "fd error");
794     int32_t ret = close(fd);
795     CHECK_AND_PRINT_LOG(ret == MTP_SUCCESS, "DealFd CloseFd fail!");
796 }
797 
GetPictureThumb(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt8List> & outThumb)798 int32_t MtpMedialibraryManager::GetPictureThumb(const std::shared_ptr<MtpOperationContext> &context,
799     std::shared_ptr<UInt8List> &outThumb)
800 {
801     int fd = 0;
802     int error = GetFd(context, fd, MEDIA_FILEMODE_READONLY);
803     CHECK_AND_RETURN_RET_LOG(error == MTP_SUCCESS, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetFd failed");
804     uint32_t errorCode = 0;
805     SourceOptions opts;
806     std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(fd, opts, errorCode);
807     CondCloseFd(imageSource == nullptr, fd);
808     CHECK_AND_RETURN_RET_LOG(imageSource != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "imageSource is nullptr");
809     DecodeOptions decodeOpts;
810     decodeOpts.desiredSize = {
811         .width = NORMAL_WIDTH,
812         .height = NORMAL_HEIGHT
813     };
814     std::unique_ptr<PixelMap> cropPixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
815     CondCloseFd(cropPixelMap == nullptr, fd);
816     CHECK_AND_RETURN_RET_LOG(cropPixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "PixelMap is nullptr");
817 
818     bool ret = CompressImage(cropPixelMap, *outThumb);
819     CHECK_AND_RETURN_RET_LOG(ret == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressImage failed");
820     return MTP_SUCCESS;
821 }
822 
GetVideoThumb(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<UInt8List> & outThumb)823 int32_t MtpMedialibraryManager::GetVideoThumb(const std::shared_ptr<MtpOperationContext> &context,
824     std::shared_ptr<UInt8List> &outThumb)
825 {
826     int fd = 0;
827     int error = GetFd(context, fd, MEDIA_FILEMODE_READONLY);
828     CHECK_AND_RETURN_RET_LOG(error == MTP_SUCCESS, MTP_ERROR_NO_THUMBNAIL_PRESENT, "GetFd failed");
829     shared_ptr<AVMetadataHelper> avMetadataHelper = AVMetadataHelperFactory::CreateAVMetadataHelper();
830     CHECK_AND_RETURN_RET_LOG(avMetadataHelper != nullptr,
831         MTP_ERROR_NO_THUMBNAIL_PRESENT, "avMetadataHelper is nullptr");
832     struct stat64 st;
833     int32_t ret = fstat64(fd, &st);
834     CondCloseFd(ret != 0, fd);
835     CHECK_AND_RETURN_RET_LOG(ret == 0, MTP_ERROR_NO_THUMBNAIL_PRESENT, "Get file state failed, err %{public}d", errno);
836     int64_t length = static_cast<int64_t>(st.st_size);
837     ret = avMetadataHelper->SetSource(fd, 0, length, AV_META_USAGE_PIXEL_MAP);
838     CondCloseFd(ret != 0, fd);
839     CHECK_AND_RETURN_RET_LOG(ret == 0, MTP_ERROR_NO_THUMBNAIL_PRESENT, "SetSource failed, ret %{public}d", ret);
840     PixelMapParams param;
841     param.colorFormat = PixelFormat::RGBA_8888;
842     param.dstWidth = NORMAL_WIDTH;
843     param.dstHeight = NORMAL_HEIGHT;
844     shared_ptr<PixelMap> sPixelMap = avMetadataHelper->FetchFrameYuv(0,
845         AVMetadataQueryOption::AV_META_QUERY_NEXT_SYNC, param);
846     CondCloseFd(sPixelMap == nullptr, fd);
847     CHECK_AND_RETURN_RET_LOG(sPixelMap != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "sPixelMap is nullptr");
848     if (sPixelMap->GetPixelFormat() == PixelFormat::YCBCR_P010) {
849         uint32_t ret = ImageFormatConvert::ConvertImageFormat(sPixelMap, PixelFormat::RGBA_1010102);
850         CondCloseFd(ret != E_OK, fd);
851         CHECK_AND_RETURN_RET_LOG(ret == E_OK, MTP_ERROR_NO_THUMBNAIL_PRESENT,
852             "PixelMapYuv10ToRGBA_1010102: source ConvertImageFormat fail");
853     }
854     InitializationOptions opts = {
855         .pixelFormat = PixelFormat::RGBA_8888,
856         .alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL
857     };
858     unique_ptr<PixelMap> compressImage = PixelMap::Create(*sPixelMap, opts);
859     CondCloseFd(sPixelMap == nullptr, fd);
860     CHECK_AND_RETURN_RET_LOG(compressImage != nullptr, MTP_ERROR_NO_THUMBNAIL_PRESENT, "compressImage is nullptr");
861     CloseFdForGet(context, fd);
862     bool retparam = CompressImage(compressImage, *outThumb);
863     CHECK_AND_RETURN_RET_LOG(retparam == true, MTP_ERROR_NO_THUMBNAIL_PRESENT, "CompressVideo failed");
864     return MTP_SUCCESS;
865 }
866 
GetAssetById(const int32_t id,shared_ptr<FileAsset> & outFileAsset)867 int32_t MtpMedialibraryManager::GetAssetById(const int32_t id, shared_ptr<FileAsset> &outFileAsset)
868 {
869     DataShare::DataSharePredicates predicates;
870     string whereClause = MEDIA_DATA_DB_ID + " = ?";
871     uint32_t field_id = id;
872     if (field_id > COMMON_PHOTOS_OFFSET) {
873         field_id = id - COMMON_PHOTOS_OFFSET;
874     }
875     vector<string> whereArgs = {to_string(field_id)};
876     predicates.SetWhereClause(whereClause);
877     predicates.SetWhereArgs(whereArgs);
878     Uri uri(PAH_QUERY_PHOTO);
879     vector<string> columns;
880     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
881         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
882     shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
883     CHECK_AND_RETURN_RET(resultSet != nullptr, E_NO_SUCH_FILE);
884     unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
885     CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
886         MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
887     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
888         E_NO_SUCH_FILE, "no such file");
889     unique_ptr<FileAsset> fileUniAsset = fetchFileResult->GetFirstObject();
890     outFileAsset = move(fileUniAsset);
891     return E_SUCCESS;
892 }
893 
GetPathById(const int32_t id,string & outPath)894 int32_t MtpMedialibraryManager::GetPathById(const int32_t id, string &outPath)
895 {
896     shared_ptr<FileAsset> fileAsset;
897     int errCode = GetAssetById(id, fileAsset);
898     CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, E_HAS_DB_ERROR, "fileAsset is nullptr, assetId: %{public}d", id);
899     outPath = fileAsset->GetPath();
900     return errCode;
901 }
902 
GetIdByPath(const std::string & path,uint32_t & outId)903 int32_t MtpMedialibraryManager::GetIdByPath(const std::string &path, uint32_t &outId)
904 {
905     DataShare::DataSharePredicates predicates;
906     string whereClause = MEDIA_DATA_DB_FILE_PATH + " = ?";
907     vector<string> whereArgs = {path};
908     predicates.SetWhereClause(whereClause);
909     predicates.SetWhereArgs(whereArgs);
910     Uri uri(PAH_QUERY_PHOTO);
911     vector<string> columns;
912     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
913         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
914     shared_ptr<DataShare::DataShareResultSet> resultSet = dataShareHelper_->Query(uri, predicates, columns);
915     CHECK_AND_RETURN_RET(resultSet != nullptr, E_NO_SUCH_FILE);
916     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
917         MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
918     unique_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
919     CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
920         MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
921     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
922         E_NO_SUCH_FILE, "no such file");
923     unique_ptr<FileAsset> fileUniAsset = fetchFileResult->GetFirstObject();
924     outId = static_cast<uint32_t>(fileUniAsset->GetId());
925     return E_SUCCESS;
926 }
927 
SendObjectInfo(const std::shared_ptr<MtpOperationContext> & context,uint32_t & outStorageID,uint32_t & outParent,uint32_t & outHandle)928 int32_t MtpMedialibraryManager::SendObjectInfo(const std::shared_ptr<MtpOperationContext> &context,
929     uint32_t &outStorageID, uint32_t &outParent, uint32_t &outHandle)
930 {
931     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
932     DataShare::DataShareValuesBucket valuesBucket;
933     MediaType mediaType;
934     int errCode = MtpDataUtils::GetMediaTypeByName(context->name, mediaType);
935     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetMediaTypeByName");
936     bool cond = ((mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO) || context->parent == uint32_t(-1));
937     CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTHANDLE, "file type not support");
938     string uri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CREATEASSET;
939     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
940     Uri createFileUri(uri);
941     valuesBucket.Put(MEDIA_DATA_DB_NAME, context->name);
942     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
943     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
944         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
945     int outRowId = dataShareHelper_->Insert(createFileUri, valuesBucket);
946     CHECK_AND_RETURN_RET_LOG(outRowId > 0,
947         MtpErrorUtils::SolveSendObjectInfoError(E_HAS_DB_ERROR), "fail to create assset");
948     outHandle = static_cast<uint32_t>(outRowId + COMMON_PHOTOS_OFFSET);
949     outStorageID = DEFAULT_STORAGE_ID;
950     outParent = context->parent;
951     return MtpErrorUtils::SolveSendObjectInfoError(E_SUCCESS);
952 }
953 
MoveObject(const std::shared_ptr<MtpOperationContext> & context)954 int32_t MtpMedialibraryManager::MoveObject(const std::shared_ptr<MtpOperationContext> &context)
955 {
956     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
957     return MtpErrorUtils::SolveCloseFdError(MTP_STORE_READ_ONLY);
958 }
959 
GetFileAssetFromPhotosInfo(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<FileAsset> & fileAsset)960 int32_t MtpMedialibraryManager::GetFileAssetFromPhotosInfo(const std::shared_ptr<MtpOperationContext> &context,
961     std::shared_ptr<FileAsset> &fileAsset)
962 {
963     std::shared_ptr<DataShare::DataShareResultSet> resultSet = GetPhotosInfo(context, false);
964     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
965         MTP_ERROR_STORE_NOT_AVAILABLE, "fail to get handles");
966     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
967         MTP_ERROR_STORE_NOT_AVAILABLE, "have no row");
968     std::shared_ptr<FetchResult<FileAsset>> fetchFileResult = make_unique<FetchResult<FileAsset>>(resultSet);
969     CHECK_AND_RETURN_RET_LOG(fetchFileResult != nullptr,
970         MTP_ERROR_INVALID_OBJECTHANDLE, "fetchFileResult is nullptr");
971     fileAsset = fetchFileResult->GetFirstObject();
972     CHECK_AND_RETURN_RET_LOG(fileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fileAsset is nullptr");
973     return MTP_SUCCESS;
974 }
975 
GetMovingPhotoVideoPath(const std::string & dataPath,std::string & displayName,std::string & movingPhotoDataPath,MediaType & mediaType)976 int32_t MtpMedialibraryManager::GetMovingPhotoVideoPath(const std::string &dataPath,
977     std::string &displayName, std::string &movingPhotoDataPath, MediaType &mediaType)
978 {
979     mediaType = MEDIA_TYPE_VIDEO;
980     movingPhotoDataPath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(dataPath);
981     MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving movingPhotoDataPath:%{public}s",
982         movingPhotoDataPath.c_str());
983     size_t indexPos = displayName.rfind(".");
984     CHECK_AND_RETURN_RET_LOG(indexPos != std::string::npos, MTP_ERROR_NO_THIS_FILE, "can not find displayname suffix");
985     if (indexPos + SIZE_ONE >= movingPhotoDataPath.size()) {
986         MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving movingPhotoDataPath is error");
987         return E_ERR;
988     }
989     displayName.resize(indexPos);
990     displayName += MOVING_PHOTO_SUFFIX;
991     MEDIA_DEBUG_LOG("MTP CopyObjectMovingPhotoFix moving displayName:%{public}s", displayName.c_str());
992     return MTP_SUCCESS;
993 }
994 
InsertCopyObject(const std::string & displayName,const MediaType & mediaType)995 int32_t MtpMedialibraryManager::InsertCopyObject(const std::string &displayName, const MediaType &mediaType)
996 {
997     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
998         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
999     string uri = MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CREATEASSET;
1000     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1001     Uri createFileUri(uri);
1002     DataShare::DataShareValuesBucket valuesBucket;
1003     valuesBucket.Put(MEDIA_DATA_DB_NAME, displayName);
1004     valuesBucket.Put(MEDIA_DATA_DB_MEDIA_TYPE, mediaType);
1005     int insertId = dataShareHelper_->Insert(createFileUri, valuesBucket);
1006     MEDIA_DEBUG_LOG("MTP InsertCopyObject insertId:%{public}d", insertId);
1007     return insertId;
1008 }
1009 
CopyAndDumpFile(const std::shared_ptr<MtpOperationContext> & context,const std::string & oldDataPath,std::shared_ptr<FileAsset> & oldFileAsset)1010 int32_t MtpMedialibraryManager::CopyAndDumpFile(const std::shared_ptr<MtpOperationContext> &context,
1011     const std::string &oldDataPath, std::shared_ptr<FileAsset> &oldFileAsset)
1012 {
1013     CHECK_AND_RETURN_RET_LOG(oldFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "oldFileAsset is nullptr");
1014 
1015     std::shared_ptr<FileAsset> newFileAsset;
1016     int32_t errCode = GetFileAssetFromPhotosInfo(context, newFileAsset);
1017     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetFileAssetFromPhotosInfo");
1018     CHECK_AND_RETURN_RET_LOG(newFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "newFileAsset is nullptr");
1019 
1020     int newFd = 0;
1021     errCode = GetFdByOpenFile(context, newFd);
1022     CHECK_AND_RETURN_RET_LOG((newFd > 0) && (errCode == MTP_SUCCESS), MTP_ERROR_NO_THIS_FILE,
1023         "MTP GetFdByOpenFile open file failed newfd:%{public}d, errCode:%{public}d", newFd, errCode);
1024     bool copyRet = MediaFileUtils::CopyFileUtil(oldDataPath, newFileAsset->GetFilePath());
1025     if (copyRet && errCode == MTP_SUCCESS) {
1026         struct timeval times[PATH_TIMEVAL_MAX] = { { 0, 0 }, { 0, 0 } };
1027         times[0].tv_sec = oldFileAsset->GetDateAdded() / MILLI_TO_SECOND;
1028         times[1].tv_sec = oldFileAsset->GetDateModified() / MILLI_TO_SECOND;
1029         std::string hdfsPath = GetHmdfsPath(newFileAsset->GetFilePath());
1030         if (utimes(hdfsPath.c_str(), times) != 0) {
1031             MEDIA_WARN_LOG("utimes hdfsPath:%{public}s failed", hdfsPath.c_str());
1032         }
1033         errCode = CloseFd(context, newFd);
1034         return errCode;
1035     }
1036     MEDIA_ERR_LOG("MTP oldDataPath:%{public}s copy failed", oldDataPath.c_str());
1037     errCode = close(newFd);
1038     return errCode;
1039 }
1040 
CopyObject(const std::shared_ptr<MtpOperationContext> & context,uint32_t & outObjectHandle)1041 int32_t MtpMedialibraryManager::CopyObject(const std::shared_ptr<MtpOperationContext> &context,
1042     uint32_t &outObjectHandle)
1043 {
1044     CHECK_AND_RETURN_RET_LOG((context != nullptr) && (context->parent != 0),
1045         MTP_ERROR_INVALID_OBJECTHANDLE, "context is invailed");
1046     CHECK_AND_RETURN_RET_LOG(context->handle > COMMON_PHOTOS_OFFSET, MTP_ERROR_PARAMETER_NOT_SUPPORTED,
1047         "not allow to copy folder in PTP");
1048     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1049         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1050     int32_t errCode = E_ERR;
1051     std::shared_ptr<FileAsset> oldFileAsset;
1052     errCode = GetFileAssetFromPhotosInfo(context, oldFileAsset);
1053     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetFileAssetFromPhotosInfo");
1054     CHECK_AND_RETURN_RET_LOG(oldFileAsset != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "oldFileAsset is nullptr");
1055     std::string oldDataPath = oldFileAsset->GetFilePath();
1056     context->name = oldFileAsset->GetDisplayName();
1057     MediaType mediaType;
1058     std::string displayName = context->name;
1059     std::string movingPhotoDataPath = oldDataPath;
1060     if (context->handle > COMMON_MOVING_OFFSET) {
1061         errCode = GetMovingPhotoVideoPath(oldDataPath, displayName, movingPhotoDataPath, mediaType);
1062         CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to GetMovingPhotoVideoPath");
1063     } else {
1064         mediaType = oldFileAsset->GetMediaType();
1065     }
1066     bool cond = (mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO) || context->parent == uint32_t(-1);
1067     CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTHANDLE, "file type not support");
1068     int insertId = InsertCopyObject(displayName, mediaType);
1069     CHECK_AND_RETURN_RET_LOG(insertId > 0,
1070         MtpErrorUtils::SolveSendObjectInfoError(E_HAS_DB_ERROR), "fail to create assset");
1071     std::shared_ptr<MtpOperationContext> newFileContext = std::make_shared<MtpOperationContext>();
1072     newFileContext->handle = static_cast<uint32_t>(insertId) + COMMON_PHOTOS_OFFSET;
1073     newFileContext->parent = context->parent;
1074     errCode = CopyAndDumpFile(newFileContext, movingPhotoDataPath, oldFileAsset);
1075     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, errCode, "fail to CopyObjectSub");
1076     outObjectHandle = newFileContext->handle;
1077     return MTP_SUCCESS;
1078 }
1079 
DeleteObject(const std::shared_ptr<MtpOperationContext> & context)1080 int32_t MtpMedialibraryManager::DeleteObject(const std::shared_ptr<MtpOperationContext> &context)
1081 {
1082     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1083     return MtpErrorUtils::SolveCloseFdError(MTP_STORE_READ_ONLY);
1084 }
1085 
SetObjectPropValue(const std::shared_ptr<MtpOperationContext> & context)1086 int32_t MtpMedialibraryManager::SetObjectPropValue(const std::shared_ptr<MtpOperationContext> &context)
1087 {
1088     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1089     return MtpErrorUtils::SolveCloseFdError(MTP_STORE_READ_ONLY);
1090 }
1091 
CloseFdForGet(const std::shared_ptr<MtpOperationContext> & context,int32_t fd)1092 int32_t MtpMedialibraryManager::CloseFdForGet(const std::shared_ptr<MtpOperationContext> &context, int32_t fd)
1093 {
1094     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1095     MEDIA_INFO_LOG("CloseFd  handle::%{public}u", context->handle);
1096     CHECK_AND_RETURN_RET_LOG(fd > 0, E_ERR, "wrong fd");
1097     int errCode = close(fd);
1098     return MtpErrorUtils::SolveCloseFdError(errCode);
1099 }
1100 
CloseFd(const shared_ptr<MtpOperationContext> & context,int32_t fd)1101 int32_t MtpMedialibraryManager::CloseFd(const shared_ptr<MtpOperationContext> &context, int32_t fd)
1102 {
1103     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1104     MEDIA_INFO_LOG("CloseFd  handle::%{public}u", context->handle);
1105     int32_t errCode = E_SUCCESS;
1106     CHECK_AND_RETURN_RET_LOG(fd > 0, E_ERR, "wrong fd");
1107     if (context->handle > EDITED_PHOTOS_OFFSET) {
1108         errCode = close(fd);
1109         return MtpErrorUtils::SolveCloseFdError(errCode);
1110     }
1111     shared_ptr<FileAsset> fileAsset;
1112     errCode = GetAssetById(context->handle, fileAsset);
1113     CHECK_AND_RETURN_RET_LOG(errCode == E_SUCCESS,
1114         MtpErrorUtils::SolveCloseFdError(errCode), "fail to GetAssetById");
1115     DataShare::DataShareValuesBucket valuesBucket;
1116     valuesBucket.Put(MEDIA_DATA_DB_URI, MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CLOSEASSET +
1117         "/" + to_string(context->handle - COMMON_PHOTOS_OFFSET));
1118     MEDIA_INFO_LOG("CloseFd %{public}s, FilePath  %{public}s", fileAsset->GetUri().c_str(),
1119         fileAsset->GetFilePath().c_str());
1120     Uri closeAssetUri(MEDIALIBRARY_DATA_URI + "/" + PTP_OPERATION + "/" + MEDIA_FILEOPRN_CLOSEASSET);
1121     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr,
1122         MtpErrorUtils::SolveGetHandlesError(E_HAS_DB_ERROR), "fail to get datasharehelper");
1123     if (close(fd) == MTP_SUCCESS) {
1124         errCode = dataShareHelper_->Insert(closeAssetUri, valuesBucket);
1125     }
1126     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to Close file");
1127     DataShare::DataShareValuesBucket valuesBucketForOwnerAlbumId;
1128     string uri = URI_MTP_OPERATION + "/" + OPRN_UPDATE_OWNER_ALBUM_ID;
1129     MediaFileUtils::UriAppendKeyValue(uri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1130     Uri updateOwnerAlbumIdUri(uri);
1131     DataShare::DataSharePredicates predicates;
1132     predicates.EqualTo(PhotoColumn::MEDIA_ID, to_string(context->handle - COMMON_PHOTOS_OFFSET));
1133     valuesBucketForOwnerAlbumId.Put(PhotoColumn::PHOTO_OWNER_ALBUM_ID, static_cast<int32_t>(context->parent));
1134     int32_t changedRows = dataShareHelper_->Update(updateOwnerAlbumIdUri, predicates, valuesBucketForOwnerAlbumId);
1135     CHECK_AND_RETURN_RET_LOG(changedRows > 0,
1136         MtpErrorUtils::SolveCloseFdError(E_HAS_DB_ERROR), "fail to update owneralbumid");
1137     return MtpErrorUtils::SolveCloseFdError(E_SUCCESS);
1138 }
1139 
GetObjectPropList(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<std::vector<Property>> & outProps)1140 int32_t MtpMedialibraryManager::GetObjectPropList(const std::shared_ptr<MtpOperationContext> &context,
1141     std::shared_ptr<std::vector<Property>> &outProps)
1142 {
1143     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1144     if (context->property == 0) {
1145         CHECK_AND_RETURN_RET_LOG(context->groupCode != 0, MTP_ERROR_PARAMETER_NOT_SUPPORTED, "groupCode error");
1146         MEDIA_ERR_LOG("context property = 0");
1147         return MTP_ERROR_SPECIFICATION_BY_GROUP_UNSUPPORTED;
1148     }
1149     shared_ptr<DataShare::DataShareResultSet> resultSet;
1150     if (context->handle < COMMON_PHOTOS_OFFSET) {
1151         context->parent = PARENT_ID;
1152     }
1153     if (context->parent == PARENT_ID && context->handle < COMMON_PHOTOS_OFFSET) {
1154         resultSet = GetAlbumInfo(context, false);
1155     } else {
1156         resultSet = GetPhotosInfo(context, false);
1157     }
1158     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr,
1159         MTP_ERROR_INVALID_OBJECTHANDLE, "fail to getSet");
1160     return MtpDataUtils::GetPropListBySet(context, resultSet, outProps);
1161 }
1162 
GetObjectPropValue(const shared_ptr<MtpOperationContext> & context,uint64_t & outIntVal,uint128_t & outLongVal,string & outStrVal)1163 int32_t MtpMedialibraryManager::GetObjectPropValue(const shared_ptr<MtpOperationContext> &context,
1164     uint64_t &outIntVal, uint128_t &outLongVal, string &outStrVal)
1165 {
1166     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_STORE_NOT_AVAILABLE, "context is nullptr");
1167     shared_ptr<DataShare::DataShareResultSet> resultSet;
1168     if (context->parent == PARENT_ID) {
1169         resultSet = GetAlbumInfo(context, false);
1170     } else {
1171         resultSet = GetPhotosInfo(context, false);
1172     }
1173     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to getSet");
1174     CHECK_AND_RETURN_RET_LOG(resultSet->GoToFirstRow() == NativeRdb::E_OK,
1175         MTP_ERROR_INVALID_OBJECTHANDLE, "have no row");
1176     PropertyValue propValue;
1177     bool isVideoOfMovingPhoto = static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) == MOVING_PHOTO_TYPE;
1178     int32_t errCode = MtpDataUtils::GetPropValueBySet(context->property, resultSet, propValue, isVideoOfMovingPhoto);
1179     CHECK_AND_RETURN_RET_LOG(errCode == MTP_SUCCESS, MTP_ERROR_INVALID_OBJECTHANDLE, "fail to get GetPropValueBySet");
1180     outIntVal = propValue.outIntVal;
1181     outStrVal = propValue.outStrVal;
1182     return errCode;
1183 }
1184 
DeleteCanceledObject(uint32_t id)1185 void MtpMedialibraryManager::DeleteCanceledObject(uint32_t id)
1186 {
1187     CHECK_AND_RETURN_LOG(dataShareHelper_ != nullptr,
1188         "MtpMedialibraryManager::DeleteCanceledObject fail to get datasharehelpe");
1189 
1190     string trashUri = PAH_TRASH_PHOTO;
1191     MediaFileUtils::UriAppendKeyValue(trashUri, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1192     Uri trashAssetUri(trashUri);
1193     DataShare::DataShareValuesBucket valuesBucketTrashed;
1194     valuesBucketTrashed.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
1195     DataShare::DataSharePredicates predicatesTrashed;
1196     predicatesTrashed.EqualTo(MediaColumn::MEDIA_ID, to_string(id - COMMON_PHOTOS_OFFSET));
1197     dataShareHelper_->Update(trashAssetUri, predicatesTrashed, valuesBucketTrashed);
1198     MEDIA_INFO_LOG("Update file date_trashed SUCCESS");
1199 
1200     std::string deleteUriStr = TOOL_DELETE_PHOTO;
1201     MediaFileUtils::UriAppendKeyValue(deleteUriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
1202     Uri deleteUri(deleteUriStr);
1203     DataShare::DataSharePredicates predicates;
1204     predicates.EqualTo(MediaColumn::MEDIA_ID, to_string(id - COMMON_PHOTOS_OFFSET));
1205     DataShare::DataShareValuesBucket valuesBucket;
1206     valuesBucket.Put(PhotoColumn::MEDIA_DATE_TRASHED, DATE_UNTRASHED);
1207     dataShareHelper_->Update(deleteUri, predicates, valuesBucket);
1208     MEDIA_INFO_LOG("DeleteCaneledObject SUCCESS");
1209 }
1210 
1211 }  // namespace Media
1212 }  // namespace OHOS
1213