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