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