1 /*
2 * Copyright (C) 2024 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
16 #include "media_asset_manager_ffi.h"
17
18 #include <fcntl.h>
19 #include <string>
20 #include <sys/sendfile.h>
21 #include <unordered_map>
22 #include <uuid.h>
23
24 #include "access_token.h"
25 #include "accesstoken_kit.h"
26 #include "directory_ex.h"
27 #include "file_uri.h"
28 #include "image_source.h"
29 #include "image_source_impl.h"
30 #include "ipc_skeleton.h"
31 #include "media_call_transcode.h"
32 #include "media_column.h"
33 #include "media_file_utils.h"
34 #include "media_file_uri.h"
35 #include "moving_photo_impl.h"
36 #include "permission_utils.h"
37 #include "picture_handle_client.h"
38 #include "ui_extension_context.h"
39 #include "userfile_client.h"
40
41 using namespace std;
42 using namespace OHOS::FFI;
43 using namespace OHOS::Security::AccessToken;
44
45 namespace OHOS {
46 namespace Media {
47 const int32_t LOW_QUALITY_IMAGE = 1;
48 const int32_t HIGH_QUALITY_IMAGE = 0;
49 const int32_t UUID_STR_LENGTH = 37;
50 const int32_t MAX_URI_SIZE = 384; // 256 for display name and 128 for relative path
51 const int32_t REQUEST_ID_MAX_LEN = 64;
52
53 static mutex multiStagesCaptureLock;
54 static mutex registerTaskLock;
55 static map<string, shared_ptr<MultiStagesTaskObserver>> multiStagesObserverMap;
56 static std::map<std::string, std::map<std::string, AssetHandler*>> inProcessUriMap;
57 static SafeMap<string, AssetHandler*> inProcessFastRequests;
58 static SafeMap<std::string, AssetHandler*> onPreparedResult_;
59 static SafeMap<std::string, HashMapArray> onPreparedResultValue_;
60 static SafeMap<std::string, bool> isTranscoderMap_;
61 static const string HIGH_QUALITY_STRING = "high";
62 static const string LOW_QUALITY_STRING = "low";
63
ParseArgGetPhotoAsset(int64_t photoAssetId,int & fileId,string & uri,string & displayName,PhotoSubType & subType)64 bool ParseArgGetPhotoAsset(int64_t photoAssetId, int &fileId, string &uri,
65 string &displayName, PhotoSubType &subType)
66 {
67 auto photoAssetImpl = FFIData::GetData<PhotoAssetImpl>(photoAssetId);
68 if (photoAssetImpl == nullptr) {
69 LOGE("Invalid object PhotoAssetImpl");
70 return false;
71 }
72 fileId = photoAssetImpl->GetFileId();
73 uri = photoAssetImpl->GetFileUri();
74 displayName = photoAssetImpl->GetFileDisplayName();
75 std::shared_ptr<FileAsset> fileAsset = photoAssetImpl->GetFileAssetInstance();
76 if (fileAsset == nullptr) {
77 LOGE("Invalid object FileAsset");
78 return false;
79 }
80 subType = static_cast<PhotoSubType>(fileAsset->GetPhotoSubType());
81 return true;
82 }
83
ParseArgGetRequestOption(RequestOptions & requestOptions,DeliveryMode & deliveryMode,SourceMode & sourceMode)84 bool ParseArgGetRequestOption(RequestOptions &requestOptions, DeliveryMode &deliveryMode, SourceMode &sourceMode)
85 {
86 if (requestOptions.deliveryMode < static_cast<int32_t>(DeliveryMode::FAST) ||
87 requestOptions.deliveryMode > static_cast<int32_t>(DeliveryMode::BALANCED_MODE)) {
88 LOGE("delivery mode invalid argument.");
89 return false;
90 }
91 deliveryMode = static_cast<DeliveryMode>(requestOptions.deliveryMode);
92 sourceMode = SourceMode::EDITED_MODE; // public API just support deliveryMode.
93 return true;
94 }
95
HasReadPermission()96 static bool HasReadPermission()
97 {
98 AccessTokenID tokenCaller = IPCSkeleton::GetSelfTokenID();
99 int result = AccessTokenKit::VerifyAccessToken(tokenCaller, PERM_READ_IMAGEVIDEO);
100 return result == PermissionState::PERMISSION_GRANTED;
101 }
102
IsMovingPhoto(int32_t photoSubType)103 static bool IsMovingPhoto(int32_t photoSubType)
104 {
105 return photoSubType == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO);
106 }
107
ParseRequestMediaArgs(int64_t photoAssetId,RequestOptions & requestOptions,unique_ptr<MediaAssetManagerContext> & asyncContext)108 bool MediaAssetManagerImpl::ParseRequestMediaArgs(int64_t photoAssetId,
109 RequestOptions &requestOptions, unique_ptr<MediaAssetManagerContext> &asyncContext)
110 {
111 if (!ParseArgGetPhotoAsset(photoAssetId, asyncContext->fileId, asyncContext->photoUri,
112 asyncContext->displayName, asyncContext->subType)) {
113 LOGE("requestMedia ParseArgGetPhotoAsset error");
114 return false;
115 }
116 if (!ParseArgGetRequestOption(requestOptions, asyncContext->deliveryMode,
117 asyncContext->sourceMode)) {
118 LOGE("requestMedia ParseArgGetRequestOption error");
119 return false;
120 }
121 asyncContext->hasReadPermission = HasReadPermission();
122 return true;
123 }
124
GenerateRequestId()125 static string GenerateRequestId()
126 {
127 uuid_t uuid;
128 uuid_generate(uuid);
129 char str[UUID_STR_LENGTH] = {};
130 uuid_unparse(uuid, str);
131 return str;
132 }
133
QueryPhotoStatus(int fileId,const string & photoUri,string & photoId,bool hasReadPermission)134 MultiStagesCapturePhotoStatus MediaAssetManagerImpl::QueryPhotoStatus(int fileId,
135 const string& photoUri, string &photoId, bool hasReadPermission)
136 {
137 photoId = "";
138 DataShare::DataSharePredicates predicates;
139 predicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
140 std::vector<std::string> fetchColumn { PhotoColumn::PHOTO_QUALITY, PhotoColumn::PHOTO_ID};
141 string queryUri;
142 if (hasReadPermission) {
143 queryUri = PAH_QUERY_PHOTO;
144 } else {
145 queryUri = photoUri;
146 MediaFileUri::RemoveAllFragment(queryUri);
147 }
148 Uri uri(queryUri);
149 int errCode = 0;
150 auto resultSet = UserFileClient::Query(uri, predicates, fetchColumn, errCode);
151 if (resultSet == nullptr || resultSet->GoToFirstRow() != E_OK) {
152 LOGE("query resultSet is nullptr");
153 return MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
154 }
155 int indexOfPhotoId = -1;
156 resultSet->GetColumnIndex(PhotoColumn::PHOTO_ID, indexOfPhotoId);
157 resultSet->GetString(indexOfPhotoId, photoId);
158
159 int columnIndexQuality = -1;
160 resultSet->GetColumnIndex(PhotoColumn::PHOTO_QUALITY, columnIndexQuality);
161 int currentPhotoQuality = HIGH_QUALITY_IMAGE;
162 resultSet->GetInt(columnIndexQuality, currentPhotoQuality);
163 if (currentPhotoQuality == LOW_QUALITY_IMAGE) {
164 LOGE("query photo status : lowQuality");
165 return MultiStagesCapturePhotoStatus::LOW_QUALITY_STATUS;
166 }
167 LOGE("query photo status quality: %{public}d", currentPhotoQuality);
168 return MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
169 }
170
InsertInProcessMapRecord(const string & requestUri,const string & requestId,AssetHandler * handler)171 static void InsertInProcessMapRecord(const string &requestUri, const string &requestId,
172 AssetHandler *handler)
173 {
174 std::lock_guard<std::mutex> lock(multiStagesCaptureLock);
175 std::map<std::string, AssetHandler*> assetHandler;
176 auto uriLocal = MediaFileUtils::GetUriWithoutDisplayname(requestUri);
177 if (inProcessUriMap.find(uriLocal) != inProcessUriMap.end()) {
178 assetHandler = inProcessUriMap[uriLocal];
179 assetHandler[requestId] = handler;
180 inProcessUriMap[uriLocal] = assetHandler;
181 } else {
182 assetHandler[requestId] = handler;
183 inProcessUriMap[uriLocal] = assetHandler;
184 }
185 }
186
InsertDataHandler(NotifyMode notifyMode,unique_ptr<MediaAssetManagerContext> & asyncContext)187 static AssetHandler* InsertDataHandler(NotifyMode notifyMode,
188 unique_ptr<MediaAssetManagerContext> &asyncContext)
189 {
190 int64_t dataHandlerRef = asyncContext->dataHandler;
191 AssetHandler *assetHandler = new AssetHandler(asyncContext->photoId, asyncContext->requestId,
192 asyncContext->photoUri, dataHandlerRef, asyncContext->returnDataType);
193 if (assetHandler == nullptr) {
194 LOGE("assetHandler is nullptr");
195 return nullptr;
196 }
197
198 assetHandler->photoQuality = asyncContext->photoQuality;
199 assetHandler->needsExtraInfo = asyncContext->needsExtraInfo;
200 assetHandler->notifyMode = notifyMode;
201 assetHandler->sourceMode = asyncContext->sourceMode;
202 assetHandler->compatibleMode = asyncContext->compatibleMode;
203 assetHandler->destUri = asyncContext->destUri;
204 switch (notifyMode) {
205 case NotifyMode::FAST_NOTIFY: {
206 inProcessFastRequests.EnsureInsert(asyncContext->requestId, assetHandler);
207 break;
208 }
209 case NotifyMode::WAIT_FOR_HIGH_QUALITY: {
210 InsertInProcessMapRecord(asyncContext->photoUri, asyncContext->requestId, assetHandler);
211 break;
212 }
213 default:
214 break;
215 }
216 return assetHandler;
217 }
218
NotifyDataPreparedWithoutRegister(unique_ptr<MediaAssetManagerContext> & asyncContext)219 void MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(unique_ptr<MediaAssetManagerContext> &asyncContext)
220 {
221 AssetHandler *assetHandler = InsertDataHandler(NotifyMode::FAST_NOTIFY, asyncContext);
222 if (assetHandler == nullptr) {
223 LOGE("assetHandler is nullptr");
224 return;
225 }
226 asyncContext->assetHandler = assetHandler;
227 }
228
ProcessImage(const int fileId,const int deliveryMode)229 void MediaAssetManagerImpl::ProcessImage(const int fileId, const int deliveryMode)
230 {
231 string uriStr = PAH_PROCESS_IMAGE;
232 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
233 Uri uri(uriStr);
234 DataShare::DataSharePredicates predicates;
235 int errCode = 0;
236 vector<string> columns { to_string(fileId), to_string(deliveryMode) };
237 UserFileClient::Query(uri, predicates, columns, errCode);
238 }
239
RegisterTaskObserver(unique_ptr<MediaAssetManagerContext> & asyncContext)240 void MediaAssetManagerImpl::RegisterTaskObserver(unique_ptr<MediaAssetManagerContext> &asyncContext)
241 {
242 auto dataObserver = make_shared<MultiStagesTaskObserver>(asyncContext->fileId);
243 auto uriLocal = MediaFileUtils::GetUriWithoutDisplayname(asyncContext->photoUri);
244 Uri uri(asyncContext->photoUri);
245 std::unique_lock<std::mutex> registerLock(registerTaskLock);
246 if (multiStagesObserverMap.find(uriLocal) == multiStagesObserverMap.end()) {
247 UserFileClient::RegisterObserverExt(Uri(uriLocal),
248 static_cast<shared_ptr<DataShare::DataShareObserver>>(dataObserver), false);
249 multiStagesObserverMap.insert(make_pair(uriLocal, dataObserver));
250 }
251 registerLock.unlock();
252 InsertDataHandler(NotifyMode::WAIT_FOR_HIGH_QUALITY, asyncContext);
253 MediaAssetManagerImpl::ProcessImage(asyncContext->fileId, static_cast<int32_t>(asyncContext->deliveryMode));
254 }
255
OnHandleRequestImage(unique_ptr<MediaAssetManagerContext> & asyncContext)256 void MediaAssetManagerImpl::OnHandleRequestImage(unique_ptr<MediaAssetManagerContext> &asyncContext)
257 {
258 MultiStagesCapturePhotoStatus status = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
259 switch (asyncContext->deliveryMode) {
260 case DeliveryMode::FAST:
261 if (asyncContext->needsExtraInfo) {
262 asyncContext->photoQuality = MediaAssetManagerImpl::QueryPhotoStatus(asyncContext->fileId,
263 asyncContext->photoUri, asyncContext->photoId, asyncContext->hasReadPermission);
264 }
265 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
266 break;
267 case DeliveryMode::HIGH_QUALITY:
268 status = MediaAssetManagerImpl::QueryPhotoStatus(asyncContext->fileId,
269 asyncContext->photoUri, asyncContext->photoId, asyncContext->hasReadPermission);
270 asyncContext->photoQuality = status;
271 if (status == MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS) {
272 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
273 } else {
274 RegisterTaskObserver(asyncContext);
275 }
276 break;
277 case DeliveryMode::BALANCED_MODE:
278 status = MediaAssetManagerImpl::QueryPhotoStatus(asyncContext->fileId,
279 asyncContext->photoUri, asyncContext->photoId, asyncContext->hasReadPermission);
280 asyncContext->photoQuality = status;
281 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
282 if (status == MultiStagesCapturePhotoStatus::LOW_QUALITY_STATUS) {
283 RegisterTaskObserver(asyncContext);
284 }
285 break;
286 default:
287 LOGE("invalid delivery mode");
288 return;
289 }
290 }
291
DeleteAssetHandlerSafe(AssetHandler * handler)292 static void DeleteAssetHandlerSafe(AssetHandler *handler)
293 {
294 if (handler != nullptr) {
295 delete handler;
296 handler = nullptr;
297 }
298 }
299
PhotoQualityToString(MultiStagesCapturePhotoStatus photoQuality)300 static string PhotoQualityToString(MultiStagesCapturePhotoStatus photoQuality)
301 {
302 if (photoQuality != MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS &&
303 photoQuality != MultiStagesCapturePhotoStatus::LOW_QUALITY_STATUS) {
304 LOGE("Invalid photo quality: %{public}d", static_cast<int>(photoQuality));
305 return HIGH_QUALITY_STRING;
306 }
307
308 return (photoQuality == MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS) ? HIGH_QUALITY_STRING :
309 LOW_QUALITY_STRING;
310 }
311
GetInfoMapValue(AssetHandler * assetHandler,HashMapArray & valueOfInfoMap)312 static void GetInfoMapValue(AssetHandler* assetHandler, HashMapArray &valueOfInfoMap)
313 {
314 int64_t mapValueLength = 1; // only support quality
315 KeyValue* head = static_cast<KeyValue*>(malloc(sizeof(KeyValue) * mapValueLength));
316 if (head != nullptr) {
317 string quality = "quality";
318 string qualityInfo = PhotoQualityToString(assetHandler->photoQuality);
319 for (int64_t i = 0; i < mapValueLength; i++) {
320 head[i].key = MallocCString(quality);
321 head[i].value = MallocCString(qualityInfo);
322 }
323 valueOfInfoMap.head = head;
324 valueOfInfoMap.size = mapValueLength;
325 } else {
326 LOGE("malloc KeyValue failed.");
327 }
328 }
329
OnDataPrepared(MediaObject & mediaObject,AssetHandler * assetHandler,HashMapArray & valueOfInfoMap)330 static void OnDataPrepared(MediaObject &mediaObject, AssetHandler* assetHandler, HashMapArray &valueOfInfoMap)
331 {
332 if (mediaObject.returnDataType == ReturnDataType::TYPE_ARRAY_BUFFER) {
333 if (mediaObject.imageData.head == nullptr) {
334 LOGE("ArrayBuffer is null.");
335 return;
336 }
337 auto func = reinterpret_cast<void(*)(CArrUI8, HashMapArray)>(assetHandler->dataHandler);
338 auto callbackRef = CJLambda::Create(func);
339 if (callbackRef == nullptr) {
340 LOGE("OnDataPrepared create callbackRef of ArrayBuffer failed.");
341 return;
342 }
343 callbackRef(mediaObject.imageData, valueOfInfoMap);
344 } else if (mediaObject.returnDataType == ReturnDataType::TYPE_IMAGE_SOURCE) {
345 if (mediaObject.imageId == -1) {
346 LOGE("get ImageSource failed.");
347 return;
348 }
349 auto func = reinterpret_cast<void(*)(int64_t, HashMapArray)>(assetHandler->dataHandler);
350 auto callbackRef = CJLambda::Create(func);
351 if (callbackRef == nullptr) {
352 LOGE("OnDataPrepared create callbackRef of ImageSource failed.");
353 return;
354 }
355 callbackRef(mediaObject.imageId, valueOfInfoMap);
356 } else if (mediaObject.returnDataType == ReturnDataType::TYPE_TARGET_PATH) {
357 auto func = reinterpret_cast<void(*)(bool, HashMapArray)>(assetHandler->dataHandler);
358 auto callbackRef = CJLambda::Create(func);
359 if (callbackRef == nullptr) {
360 LOGE("OnDataPrepared create callbackRef of videoFile failed.");
361 return;
362 }
363 callbackRef(mediaObject.videoFile, valueOfInfoMap);
364 } else if (mediaObject.returnDataType == ReturnDataType::TYPE_MOVING_PHOTO) {
365 if (mediaObject.movingPhotoId == -1) {
366 LOGE("get MovingPhoto failed.");
367 return;
368 }
369 auto func = reinterpret_cast<void(*)(int64_t, HashMapArray)>(assetHandler->dataHandler);
370 auto callbackRef = CJLambda::Create(func);
371 if (callbackRef == nullptr) {
372 LOGE("OnDataPrepared create callbackRef of MovingPhoto failed.");
373 return;
374 }
375 callbackRef(mediaObject.movingPhotoId, valueOfInfoMap);
376 } else {
377 LOGE("source mode type invalid");
378 }
379 }
380
IsSaveCallbackInfoByTranscoder(MediaObject & mediaObject,AssetHandler * assetHandler,HashMapArray & valueOfInfoMap)381 bool IsSaveCallbackInfoByTranscoder(MediaObject &mediaObject,
382 AssetHandler* assetHandler, HashMapArray &valueOfInfoMap)
383 {
384 int64_t dataHandler = assetHandler->dataHandler;
385 if (dataHandler == -1) {
386 LOGE("data handler is error");
387 DeleteAssetHandlerSafe(assetHandler);
388 return false;
389 }
390 bool isTranscoder;
391 if (!isTranscoderMap_.Find(assetHandler->requestId, isTranscoder)) {
392 LOGI("not find key from map");
393 isTranscoder = false;
394 }
395 if (isTranscoder) {
396 onPreparedResult_.EnsureInsert(assetHandler->requestId, assetHandler);
397 onPreparedResultValue_.EnsureInsert(assetHandler->requestId, valueOfInfoMap);
398 return true;
399 }
400 OnDataPrepared(mediaObject, assetHandler, valueOfInfoMap);
401 return false;
402 }
403
SavePicture(std::string & fileUri)404 static void SavePicture(std::string &fileUri)
405 {
406 std::string uriStr = PATH_SAVE_PICTURE;
407 std::string tempStr = fileUri.substr(PhotoColumn::PHOTO_URI_PREFIX.length());
408 std::size_t index = tempStr.find("/");
409 std::string fileId = tempStr.substr(0, index);
410 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
411 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, PhotoColumn::MEDIA_ID, fileId);
412 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, IMAGE_FILE_TYPE, "1");
413 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, "uri", fileUri);
414 Uri uri(uriStr);
415 DataShare::DataShareValuesBucket valuesBucket;
416 valuesBucket.Put(PhotoColumn::PHOTO_IS_TEMP, false);
417 DataShare::DataSharePredicates predicate;
418 UserFileClient::Update(uri, predicate, valuesBucket);
419 }
420
GetByteArrayObject(const string & requestUri,MediaObject & mediaObject,bool isSource)421 void MediaAssetManagerImpl::GetByteArrayObject(const string &requestUri,
422 MediaObject &mediaObject, bool isSource)
423 {
424 std::string tmpUri = requestUri;
425 if (isSource) {
426 MediaFileUtils::UriAppendKeyValue(tmpUri, MEDIA_OPERN_KEYWORD, SOURCE_REQUEST);
427 }
428 Uri uri(tmpUri);
429 int imageFd = UserFileClient::OpenFile(uri, MEDIA_FILEMODE_READONLY);
430 if (imageFd < 0) {
431 LOGE("get image fd failed, %{public}d", errno);
432 return;
433 }
434 ssize_t imgLen = lseek(imageFd, 0, SEEK_END);
435 if (imgLen <= 0) {
436 LOGE("imgLen is error");
437 close(imageFd);
438 return;
439 }
440 void* buffer = malloc(imgLen);
441 if (buffer == nullptr) {
442 LOGE("malloc buffer failed");
443 close(imageFd);
444 return;
445 }
446 lseek(imageFd, 0, SEEK_SET);
447 ssize_t readRet = read(imageFd, buffer, imgLen);
448 close(imageFd);
449 if (readRet != imgLen) {
450 LOGE("read image failed");
451 free(buffer);
452 return;
453 }
454 mediaObject.imageData.head = static_cast<uint8_t*>(buffer);
455 mediaObject.imageData.size = static_cast<int64_t>(readRet);
456 }
457
GetImageSourceObject(const std::string & fileUri,MediaObject & mediaObject,bool isSource)458 void MediaAssetManagerImpl::GetImageSourceObject(const std::string &fileUri,
459 MediaObject &mediaObject, bool isSource)
460 {
461 std::string tmpUri = fileUri;
462 if (isSource) {
463 MediaFileUtils::UriAppendKeyValue(tmpUri, MEDIA_OPERN_KEYWORD, SOURCE_REQUEST);
464 LOGI("request source image's imageSource");
465 }
466 Uri uri(tmpUri);
467 int fd = UserFileClient::OpenFile(uri, MEDIA_FILEMODE_READONLY);
468 if (fd < 0) {
469 LOGE("get image fd failed, errno: %{public}d", errno);
470 return;
471 }
472 SourceOptions opts;
473 uint32_t errCode = 0;
474 auto nativeImageSourcePtr = ImageSource::CreateImageSource(fd, opts, errCode);
475 close(fd);
476 if (nativeImageSourcePtr == nullptr) {
477 LOGE("get ImageSource::CreateImageSource failed nullptr");
478 return;
479 }
480 auto nativeImageSource = FFIData::Create<ImageSourceImpl>(move(nativeImageSourcePtr));
481 if (!nativeImageSource) {
482 LOGE("get ImageSourceImpl::Create failed");
483 return;
484 }
485 mediaObject.imageId = nativeImageSource->GetID();
486 }
487
GetFdFromSandBoxUri(const std::string & sandBoxUri)488 int32_t MediaAssetManagerImpl::GetFdFromSandBoxUri(const std::string &sandBoxUri)
489 {
490 AppFileService::ModuleFileUri::FileUri destUri(sandBoxUri);
491 string destPath = destUri.GetRealPath();
492 if (!MediaFileUtils::IsFileExists(destPath) && !MediaFileUtils::CreateFile(destPath)) {
493 LOGE("Create empty dest file in sandbox failed, path:%{private}s", destPath.c_str());
494 return E_ERR;
495 }
496 string absDestPath;
497 if (!PathToRealPath(destPath, absDestPath)) {
498 LOGE("PathToRealPath failed, path:%{private}s", destPath.c_str());
499 return E_ERR;
500 }
501 return MediaFileUtils::OpenFile(absDestPath, MEDIA_FILEMODE_WRITETRUNCATE);
502 }
503
WriteDataToDestPath(WriteData & writeData,MediaObject & mediaObject,std::string requestId)504 void MediaAssetManagerImpl::WriteDataToDestPath(WriteData &writeData, MediaObject &mediaObject, std::string requestId)
505 {
506 if (writeData.requestUri.empty() || writeData.destUri.empty()) {
507 mediaObject.videoFile = false;
508 LOGE("requestUri or responseUri is nullptr");
509 return;
510 }
511 std::string tmpUri = writeData.requestUri;
512 if (writeData.isSource) {
513 MediaFileUtils::UriAppendKeyValue(tmpUri, MEDIA_OPERN_KEYWORD, SOURCE_REQUEST);
514 }
515 Uri srcUri(tmpUri);
516 int srcFd = UserFileClient::OpenFile(srcUri, MEDIA_FILEMODE_READONLY);
517 if (srcFd < 0) {
518 mediaObject.videoFile = false;
519 LOGE("get source file fd failed %{public}d", srcFd);
520 return;
521 }
522 struct stat statSrc;
523 if (fstat(srcFd, &statSrc) == -1) {
524 close(srcFd);
525 mediaObject.videoFile = false;
526 LOGE("File get stat failed, %{public}d", errno);
527 return;
528 }
529 int32_t destFd = GetFdFromSandBoxUri(writeData.destUri);
530 if (destFd < 0) {
531 close(srcFd);
532 mediaObject.videoFile = false;
533 LOGE("get dest fd failed %{public}d", destFd);
534 return;
535 }
536 if (writeData.compatibleMode == CompatibleMode::ORIGINAL_FORMAT_MODE) {
537 SendFile(mediaObject, writeData, srcFd, destFd, statSrc.st_size);
538 }
539 close(srcFd);
540 close(destFd);
541 }
542
SendFile(MediaObject & mediaObject,WriteData & writeData,int srcFd,int destFd,off_t fileSize)543 void MediaAssetManagerImpl::SendFile(MediaObject &mediaObject, WriteData &writeData,
544 int srcFd, int destFd, off_t fileSize)
545 {
546 if (srcFd < 0 || destFd < 0) {
547 LOGE("srcFd or destFd is invalid");
548 mediaObject.videoFile = false;
549 return;
550 }
551 if (sendfile(destFd, srcFd, nullptr, fileSize) == -1) {
552 close(srcFd);
553 close(destFd);
554 mediaObject.videoFile = false;
555 LOGE("send file failed, %{public}d", errno);
556 return;
557 }
558 mediaObject.videoFile = true;
559 }
560
GetMovingPhotoObject(const string & requestUri,SourceMode sourceMode,MediaObject & mediaObject)561 void MediaAssetManagerImpl::GetMovingPhotoObject(const string &requestUri,
562 SourceMode sourceMode, MediaObject &mediaObject)
563 {
564 auto nativeMovingPhoto = FFIData::Create<FfiMovingPhotoImpl>(requestUri, sourceMode);
565 if (!nativeMovingPhoto) {
566 LOGE("get nativeMovingPhoto failed");
567 return;
568 }
569 mediaObject.movingPhotoId = nativeMovingPhoto->GetID();
570 }
571
GetValueOfMedia(AssetHandler * assetHandler,MediaObject & mediaObject)572 static void GetValueOfMedia(AssetHandler *assetHandler, MediaObject &mediaObject)
573 {
574 mediaObject.returnDataType = assetHandler->returnDataType;
575 if (assetHandler->returnDataType == ReturnDataType::TYPE_ARRAY_BUFFER) {
576 MediaAssetManagerImpl::GetByteArrayObject(assetHandler->requestUri, mediaObject,
577 assetHandler->sourceMode == SourceMode::ORIGINAL_MODE);
578 } else if (assetHandler->returnDataType == ReturnDataType::TYPE_IMAGE_SOURCE) {
579 MediaAssetManagerImpl::GetImageSourceObject(assetHandler->requestUri, mediaObject,
580 assetHandler->sourceMode == SourceMode::ORIGINAL_MODE);
581 } else if (assetHandler->returnDataType == ReturnDataType::TYPE_TARGET_PATH) {
582 WriteData param;
583 param.compatibleMode = assetHandler->compatibleMode;
584 param.destUri = assetHandler->destUri;
585 param.requestUri = assetHandler->requestUri;
586 param.isSource = assetHandler->sourceMode == SourceMode::ORIGINAL_MODE;
587 MediaAssetManagerImpl::WriteDataToDestPath(param, mediaObject, assetHandler->requestId);
588 } else if (assetHandler->returnDataType == ReturnDataType::TYPE_MOVING_PHOTO) {
589 MediaAssetManagerImpl::GetMovingPhotoObject(assetHandler->requestUri, assetHandler->sourceMode, mediaObject);
590 } else {
591 LOGE("source mode type invalid");
592 }
593 }
594
DeleteInProcessMapRecord(const string & requestUri,const string & requestId)595 static void DeleteInProcessMapRecord(const string &requestUri, const string &requestId)
596 {
597 std::lock_guard<std::mutex> lock(multiStagesCaptureLock);
598 auto uriLocal = MediaFileUtils::GetUriWithoutDisplayname(requestUri);
599 if (inProcessUriMap.find(uriLocal) == inProcessUriMap.end()) {
600 return;
601 }
602 std::map<std::string, AssetHandler*> assetHandlers = inProcessUriMap[uriLocal];
603 if (assetHandlers.find(requestId) == assetHandlers.end()) {
604 return;
605 }
606 assetHandlers.erase(requestId);
607 if (!assetHandlers.empty()) {
608 inProcessUriMap[uriLocal] = assetHandlers;
609 return;
610 }
611 inProcessUriMap.erase(uriLocal);
612 if (multiStagesObserverMap.find(uriLocal) != multiStagesObserverMap.end()) {
613 UserFileClient::UnregisterObserverExt(Uri(uriLocal),
614 static_cast<std::shared_ptr<DataShare::DataShareObserver>>(multiStagesObserverMap[uriLocal]));
615 }
616 multiStagesObserverMap.erase(uriLocal);
617 }
618
DeleteDataHandler(NotifyMode notifyMode,const string & requestUri,const string & requestId)619 static void DeleteDataHandler(NotifyMode notifyMode, const string &requestUri, const string &requestId)
620 {
621 auto uriLocal = MediaFileUtils::GetUriWithoutDisplayname(requestUri);
622 LOGI("Rmv %{public}d, %{public}s, %{public}s", notifyMode, requestUri.c_str(), requestId.c_str());
623 if (notifyMode == NotifyMode::WAIT_FOR_HIGH_QUALITY) {
624 DeleteInProcessMapRecord(uriLocal, requestId);
625 }
626 inProcessFastRequests.Erase(requestId);
627 }
628
FreeArrAndMap(CArrUI8 & arr,HashMapArray & map)629 void FreeArrAndMap(CArrUI8 &arr, HashMapArray &map)
630 {
631 if (arr.head != nullptr) {
632 free(arr.head);
633 arr.size = 0;
634 }
635 if (map.head != nullptr) {
636 for (int64_t i = 0; i < map.size; i++) {
637 free(map.head[i].key);
638 free(map.head[i].value);
639 }
640 free(map.head);
641 map.size = 0;
642 }
643 }
644
NotifyMediaDataPrepared(AssetHandler * assetHandler)645 void MediaAssetManagerImpl::NotifyMediaDataPrepared(AssetHandler *assetHandler)
646 {
647 if (assetHandler->dataHandler == -1) {
648 LOGE("data handler is error");
649 DeleteAssetHandlerSafe(assetHandler);
650 return;
651 }
652 if (assetHandler->notifyMode == NotifyMode::FAST_NOTIFY) {
653 AssetHandler *tmp;
654 if (!inProcessFastRequests.Find(assetHandler->requestId, tmp)) {
655 LOGE("The request has been canceled");
656 DeleteAssetHandlerSafe(assetHandler);
657 return;
658 }
659 }
660 HashMapArray valueOfInfoMap = { .head = nullptr, .size = 0};
661 if (assetHandler->needsExtraInfo) {
662 GetInfoMapValue(assetHandler, valueOfInfoMap);
663 if (valueOfInfoMap.head == nullptr || valueOfInfoMap.size == 0) {
664 LOGE("Failed to get info map");
665 }
666 }
667 if (assetHandler->returnDataType == ReturnDataType::TYPE_ARRAY_BUFFER ||
668 assetHandler->returnDataType == ReturnDataType::TYPE_IMAGE_SOURCE) {
669 string uri = assetHandler->requestUri;
670 SavePicture(uri);
671 }
672 MediaObject mediaObject;
673 GetValueOfMedia(assetHandler, mediaObject);
674 if (IsSaveCallbackInfoByTranscoder(mediaObject, assetHandler, valueOfInfoMap)) {
675 FreeArrAndMap(mediaObject.imageData, valueOfInfoMap);
676 return;
677 }
678 FreeArrAndMap(mediaObject.imageData, valueOfInfoMap);
679 DeleteDataHandler(assetHandler->notifyMode, assetHandler->requestUri, assetHandler->requestId);
680 DeleteAssetHandlerSafe(assetHandler);
681 }
682
OnChange(const ChangeInfo & changeInfo)683 void MultiStagesTaskObserver::OnChange(const ChangeInfo &changeInfo)
684 {
685 if (changeInfo.changeType_ != static_cast<int32_t>(NotifyType::NOTIFY_UPDATE)) {
686 LOGE("ignore notify change, type: %{public}d", changeInfo.changeType_);
687 return;
688 }
689 for (auto &uri : changeInfo.uris_) {
690 string uriString = uri.ToString();
691 string photoId = "";
692 if (MediaAssetManagerImpl::QueryPhotoStatus(fileId_, uriString, photoId, true) !=
693 MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS) {
694 LOGE("requested data not prepared");
695 continue;
696 }
697
698 std::lock_guard<std::mutex> lock(multiStagesCaptureLock);
699 if (inProcessUriMap.find(uriString) == inProcessUriMap.end()) {
700 LOGI("current uri does not in process, uri: %{public}s", uriString.c_str());
701 return;
702 }
703 std::map<std::string, AssetHandler *> assetHandlers = inProcessUriMap[uriString];
704 for (auto handler : assetHandlers) {
705 auto assetHandler = handler.second;
706 if (assetHandler == nullptr) {
707 continue;
708 }
709 assetHandler->photoQuality = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
710 MediaAssetManagerImpl::NotifyMediaDataPrepared(assetHandler);
711 }
712 }
713 }
714
RequestImage(int64_t contextId,int64_t photoAssetId,RequestOptions requestOptions,int64_t funcId,int32_t & errCode)715 char* MediaAssetManagerImpl::RequestImage(int64_t contextId, int64_t photoAssetId,
716 RequestOptions requestOptions, int64_t funcId, int32_t &errCode)
717 {
718 auto context = FFIData::GetData<AbilityRuntime::CJAbilityContext>(contextId);
719 if (context == nullptr) {
720 LOGE("get context failed.");
721 errCode = OHOS_INVALID_PARAM_CODE;
722 return nullptr;
723 }
724 sptr<IRemoteObject> token = context->GetToken();
725 if (!PhotoAccessHelperImpl::CheckWhetherInitSuccess(token)) {
726 LOGE("RequestImage init user file client failed");
727 errCode = JS_INNER_FAIL;
728 return nullptr;
729 }
730 unique_ptr<MediaAssetManagerContext> asyncContext = make_unique<MediaAssetManagerContext>();
731 asyncContext->returnDataType = ReturnDataType::TYPE_IMAGE_SOURCE;
732 if (!ParseRequestMediaArgs(photoAssetId, requestOptions, asyncContext)) {
733 LOGE("failed to parse requestImage args");
734 errCode = OHOS_INVALID_PARAM_CODE;
735 return nullptr;
736 }
737 if (funcId == -1) {
738 LOGE("requestMedia ParseArgGetDataHandler error");
739 errCode = OHOS_INVALID_PARAM_CODE;
740 return nullptr;
741 }
742 asyncContext->dataHandler = funcId;
743 asyncContext->requestId = GenerateRequestId();
744 OnHandleRequestImage(asyncContext);
745 if (asyncContext->subType == PhotoSubType::MOVING_PHOTO) {
746 string uri = LOG_MOVING_PHOTO;
747 Uri logMovingPhotoUri(uri);
748 DataShare::DataShareValuesBucket valuesBucket;
749 string result;
750 valuesBucket.Put("adapted", asyncContext->returnDataType == ReturnDataType::TYPE_MOVING_PHOTO);
751 UserFileClient::InsertExt(logMovingPhotoUri, valuesBucket, result);
752 }
753 if (asyncContext->assetHandler) {
754 NotifyMediaDataPrepared(asyncContext->assetHandler);
755 asyncContext->assetHandler = nullptr;
756 }
757 if (errCode == ERR_DEFAULT) {
758 char* result = MallocCString(asyncContext->requestId);
759 return result;
760 } else {
761 return nullptr;
762 }
763 }
764
RequestImageData(int64_t contextId,int64_t photoAssetId,RequestOptions requestOptions,int64_t funcId,int32_t & errCode)765 char* MediaAssetManagerImpl::RequestImageData(int64_t contextId, int64_t photoAssetId,
766 RequestOptions requestOptions, int64_t funcId, int32_t &errCode)
767 {
768 auto context = FFIData::GetData<AbilityRuntime::CJAbilityContext>(contextId);
769 if (context == nullptr) {
770 LOGE("get context failed.");
771 errCode = OHOS_INVALID_PARAM_CODE;
772 return nullptr;
773 }
774 sptr<IRemoteObject> token = context->GetToken();
775 if (!PhotoAccessHelperImpl::CheckWhetherInitSuccess(token)) {
776 LOGE("RequestImage init user file client failed");
777 errCode = JS_INNER_FAIL;
778 return nullptr;
779 }
780 unique_ptr<MediaAssetManagerContext> asyncContext = make_unique<MediaAssetManagerContext>();
781 asyncContext->returnDataType = ReturnDataType::TYPE_ARRAY_BUFFER;
782 if (!ParseRequestMediaArgs(photoAssetId, requestOptions, asyncContext)) {
783 LOGE("failed to parse requestImage args");
784 errCode = OHOS_INVALID_PARAM_CODE;
785 return nullptr;
786 }
787 if (funcId == -1) {
788 LOGE("requestMedia ParseArgGetDataHandler error");
789 errCode = OHOS_INVALID_PARAM_CODE;
790 return nullptr;
791 }
792 asyncContext->dataHandler = funcId;
793 asyncContext->requestId = GenerateRequestId();
794 MediaAssetManagerImpl::OnHandleRequestImage(asyncContext);
795 if (asyncContext->subType == PhotoSubType::MOVING_PHOTO) {
796 string uri = LOG_MOVING_PHOTO;
797 Uri logMovingPhotoUri(uri);
798 DataShare::DataShareValuesBucket valuesBucket;
799 string result;
800 valuesBucket.Put("adapted", asyncContext->returnDataType == ReturnDataType::TYPE_MOVING_PHOTO);
801 UserFileClient::InsertExt(logMovingPhotoUri, valuesBucket, result);
802 }
803 if (asyncContext->assetHandler) {
804 NotifyMediaDataPrepared(asyncContext->assetHandler);
805 asyncContext->assetHandler = nullptr;
806 }
807 if (errCode == ERR_DEFAULT) {
808 char* result = MallocCString(asyncContext->requestId);
809 return result;
810 } else {
811 return nullptr;
812 }
813 }
814
RequestMovingPhoto(int64_t contextId,int64_t photoAssetId,RequestOptions requestOptions,int64_t funcId,int32_t & errCode)815 char* MediaAssetManagerImpl::RequestMovingPhoto(int64_t contextId, int64_t photoAssetId,
816 RequestOptions requestOptions, int64_t funcId, int32_t &errCode)
817 {
818 auto context = FFIData::GetData<AbilityRuntime::CJAbilityContext>(contextId);
819 if (context == nullptr) {
820 LOGE("get context failed.");
821 errCode = OHOS_INVALID_PARAM_CODE;
822 return nullptr;
823 }
824 sptr<IRemoteObject> token = context->GetToken();
825 if (!PhotoAccessHelperImpl::CheckWhetherInitSuccess(token)) {
826 LOGE("RequestImage init user file client failed");
827 errCode = JS_INNER_FAIL;
828 return nullptr;
829 }
830 unique_ptr<MediaAssetManagerContext> asyncContext = make_unique<MediaAssetManagerContext>();
831 asyncContext->returnDataType = ReturnDataType::TYPE_MOVING_PHOTO;
832 if (!ParseRequestMediaArgs(photoAssetId, requestOptions, asyncContext)) {
833 LOGE("failed to parse requestImage args");
834 errCode = OHOS_INVALID_PARAM_CODE;
835 return nullptr;
836 }
837 if (!IsMovingPhoto(static_cast<int32_t>(asyncContext->subType))) {
838 LOGE("Asset is not a moving photo");
839 errCode = OHOS_INVALID_PARAM_CODE;
840 return nullptr;
841 }
842 asyncContext->dataHandler = funcId;
843 asyncContext->requestId = GenerateRequestId();
844 OnHandleRequestImage(asyncContext);
845 string uri = LOG_MOVING_PHOTO;
846 Uri logMovingPhotoUri(uri);
847 DataShare::DataShareValuesBucket valuesBucket;
848 string result;
849 valuesBucket.Put("adapted", asyncContext->returnDataType == ReturnDataType::TYPE_MOVING_PHOTO);
850 UserFileClient::InsertExt(logMovingPhotoUri, valuesBucket, result);
851 if (asyncContext->assetHandler) {
852 NotifyMediaDataPrepared(asyncContext->assetHandler);
853 asyncContext->assetHandler = nullptr;
854 }
855 if (errCode == ERR_DEFAULT) {
856 char* result = MallocCString(asyncContext->requestId);
857 return result;
858 } else {
859 return nullptr;
860 }
861 }
862
ParseArgGetDestPath(char * fileUri,unique_ptr<MediaAssetManagerContext> & asyncContext)863 static bool ParseArgGetDestPath(char* fileUri, unique_ptr<MediaAssetManagerContext> &asyncContext)
864 {
865 string destPath(fileUri);
866 if (destPath.empty()) {
867 LOGE("failed to get destPath.");
868 return false;
869 }
870 asyncContext->destUri = destPath;
871 if (asyncContext->photoUri.length() > MAX_URI_SIZE || asyncContext->destUri.length() > MAX_URI_SIZE) {
872 LOGE("request video file uri lens out of limit photoUri lens: %{public}zu, destUri lens: %{public}zu",
873 asyncContext->photoUri.length(), asyncContext->destUri.length());
874 return false;
875 }
876 if (MediaFileUtils::GetMediaType(asyncContext->displayName) != MEDIA_TYPE_VIDEO ||
877 MediaFileUtils::GetMediaType(MediaFileUtils::GetFileName(asyncContext->destUri)) != MEDIA_TYPE_VIDEO) {
878 LOGE("request video file type invalid");
879 return false;
880 }
881 return true;
882 }
883
OnHandleRequestVideo(unique_ptr<MediaAssetManagerContext> & asyncContext)884 void MediaAssetManagerImpl::OnHandleRequestVideo(unique_ptr<MediaAssetManagerContext> &asyncContext)
885 {
886 switch (asyncContext->deliveryMode) {
887 case DeliveryMode::FAST:
888 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
889 break;
890 case DeliveryMode::HIGH_QUALITY:
891 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
892 break;
893 case DeliveryMode::BALANCED_MODE:
894 MediaAssetManagerImpl::NotifyDataPreparedWithoutRegister(asyncContext);
895 break;
896 default: {
897 LOGE("invalid delivery mode");
898 return;
899 }
900 }
901 }
902
RequestVideoFile(int64_t contextId,int64_t photoAssetId,RequestOptions requestOptions,char * fileUri,int64_t funcId,int32_t & errCode)903 char* MediaAssetManagerImpl::RequestVideoFile(int64_t contextId, int64_t photoAssetId,
904 RequestOptions requestOptions, char* fileUri, int64_t funcId, int32_t &errCode)
905 {
906 auto context = FFIData::GetData<AbilityRuntime::CJAbilityContext>(contextId);
907 if (context == nullptr) {
908 LOGE("get context failed.");
909 errCode = OHOS_INVALID_PARAM_CODE;
910 return nullptr;
911 }
912 sptr<IRemoteObject> token = context->GetToken();
913 if (!PhotoAccessHelperImpl::CheckWhetherInitSuccess(token)) {
914 LOGE("RequestImage init user file client failed");
915 errCode = JS_INNER_FAIL;
916 return nullptr;
917 }
918 unique_ptr<MediaAssetManagerContext> asyncContext = make_unique<MediaAssetManagerContext>();
919 asyncContext->returnDataType = ReturnDataType::TYPE_TARGET_PATH;
920 if (!ParseRequestMediaArgs(photoAssetId, requestOptions, asyncContext)) {
921 LOGE("failed to parse requestVideo args");
922 errCode = OHOS_INVALID_PARAM_CODE;
923 return nullptr;
924 }
925 if (!ParseArgGetDestPath(fileUri, asyncContext)) {
926 errCode = OHOS_INVALID_PARAM_CODE;
927 return nullptr;
928 }
929 asyncContext->dataHandler = funcId;
930 asyncContext->requestId = GenerateRequestId();
931 OnHandleRequestVideo(asyncContext);
932 if (asyncContext->assetHandler) {
933 NotifyMediaDataPrepared(asyncContext->assetHandler);
934 asyncContext->assetHandler = nullptr;
935 }
936 if (errCode == ERR_DEFAULT) {
937 char* result = MallocCString(asyncContext->requestId);
938 return result;
939 } else {
940 return nullptr;
941 }
942 }
943
IsFastRequestCanceled(const std::string & requestId,std::string & photoId)944 static bool IsFastRequestCanceled(const std::string &requestId, std::string &photoId)
945 {
946 AssetHandler *assetHandler = nullptr;
947 if (!inProcessFastRequests.Find(requestId, assetHandler)) {
948 LOGE("requestId(%{public}s) not in progress.", requestId.c_str());
949 return false;
950 }
951
952 if (assetHandler == nullptr) {
953 LOGE("assetHandler is nullptr.");
954 return false;
955 }
956 photoId = assetHandler->photoId;
957 inProcessFastRequests.Erase(requestId);
958 return true;
959 }
960
IsInProcessInMapRecord(const string & requestId,AssetHandler * & handler)961 static int32_t IsInProcessInMapRecord(const string &requestId, AssetHandler* &handler)
962 {
963 std::lock_guard<std::mutex> lock(multiStagesCaptureLock);
964 for (auto record : inProcessUriMap) {
965 if (record.second.find(requestId) != record.second.end()) {
966 handler = record.second[requestId];
967 return true;
968 }
969 }
970 return false;
971 }
972
IsMapRecordCanceled(const std::string & requestId,std::string & photoId)973 static bool IsMapRecordCanceled(const std::string &requestId, std::string &photoId)
974 {
975 AssetHandler *assetHandler = nullptr;
976 if (!IsInProcessInMapRecord(requestId, assetHandler)) {
977 LOGE("requestId(%{public}s) not in progress.", requestId.c_str());
978 return false;
979 }
980
981 if (assetHandler == nullptr) {
982 LOGE("assetHandler is nullptr.");
983 return false;
984 }
985 photoId = assetHandler->photoId;
986 DeleteInProcessMapRecord(assetHandler->requestUri, assetHandler->requestId);
987 DeleteAssetHandlerSafe(assetHandler);
988 return true;
989 }
990
CancelProcessImage(const string & photoId)991 void MediaAssetManagerImpl::CancelProcessImage(const string &photoId)
992 {
993 string uriStr = PAH_CANCEL_PROCESS_IMAGE;
994 MediaLibraryNapiUtils::UriAppendKeyValue(uriStr, API_VERSION, to_string(MEDIA_API_VERSION_V10));
995 Uri uri(uriStr);
996 DataShare::DataSharePredicates predicates;
997 int errCode = 0;
998 std::vector<std::string> columns { photoId };
999 UserFileClient::Query(uri, predicates, columns, errCode);
1000 }
1001
CancelRequest(int64_t contextId,char * cRequestId,int32_t & errCode)1002 void MediaAssetManagerImpl::CancelRequest(int64_t contextId, char* cRequestId, int32_t &errCode)
1003 {
1004 auto context = FFIData::GetData<AbilityRuntime::CJAbilityContext>(contextId);
1005 if (context == nullptr) {
1006 LOGE("get context failed.");
1007 errCode = OHOS_INVALID_PARAM_CODE;
1008 return;
1009 }
1010 sptr<IRemoteObject> token = context->GetToken();
1011 if (!PhotoAccessHelperImpl::CheckWhetherInitSuccess(token)) {
1012 LOGE("RequestImage init user file client failed");
1013 errCode = JS_INNER_FAIL;
1014 return;
1015 }
1016 string requestId(cRequestId);
1017 if (requestId.size() > REQUEST_ID_MAX_LEN) {
1018 requestId = requestId.substr(0, REQUEST_ID_MAX_LEN);
1019 }
1020 string photoId = "";
1021 bool hasFastRequestInProcess = IsFastRequestCanceled(requestId, photoId);
1022 bool hasMapRecordInProcess = IsMapRecordCanceled(requestId, photoId);
1023 if (hasFastRequestInProcess || hasMapRecordInProcess) {
1024 unique_ptr<MediaAssetManagerContext> asyncContext = make_unique<MediaAssetManagerContext>();
1025 asyncContext->photoId = photoId;
1026 MediaAssetManagerImpl::CancelProcessImage(asyncContext->photoId);
1027 }
1028 }
1029
LoadMovingPhoto(int64_t contextId,char * cImageFileUri,char * cVideoFileUri,int32_t & errCode)1030 int64_t MediaAssetManagerImpl::LoadMovingPhoto(int64_t contextId,
1031 char* cImageFileUri, char* cVideoFileUri, int32_t &errCode)
1032 {
1033 if (contextId == -1) {
1034 LOGE("Get context failed.");
1035 errCode = OHOS_INVALID_PARAM_CODE;
1036 return -1;
1037 }
1038 string imageFileUri(cImageFileUri);
1039 string videoFileUri(cVideoFileUri);
1040 string uri(imageFileUri + MOVING_PHOTO_URI_SPLIT + videoFileUri);
1041 auto nativeMovingPhoto = FFIData::Create<FfiMovingPhotoImpl>(uri, SourceMode::EDITED_MODE);
1042 if (!nativeMovingPhoto) {
1043 LOGE("get nativeMovingPhoto failed");
1044 errCode = JS_INNER_FAIL;
1045 return -1;
1046 }
1047 return nativeMovingPhoto->GetID();
1048 }
1049 }
1050 }