• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 "UserFileClientEx"
16 #include "userfile_client_ex.h"
17 
18 #include <map>
19 #include <string>
20 #include <unordered_map>
21 #include <unistd.h>
22 
23 #include "datashare_abs_result_set.h"
24 #include "datashare_predicates.h"
25 #include "directory_ex.h"
26 #include "iservice_registry.h"
27 #include "media_column.h"
28 #include "media_file_uri.h"
29 #include "media_file_utils.h"
30 #include "media_log.h"
31 #include "medialibrary_db_const.h"
32 #include "medialibrary_errno.h"
33 #include "mimetype_utils.h"
34 #include "scanner_utils.h"
35 #include "string_ex.h"
36 #include "system_ability_definition.h"
37 #include "thumbnail_const.h"
38 #include "uri.h"
39 #include "userfile_client.h"
40 #include "userfile_manager_types.h"
41 
42 using namespace OHOS::DataShare;
43 namespace OHOS {
44 namespace Media {
45 namespace MediaTool {
46 const std::string URI_DELIMITER = std::string(1, SLASH_CHAR);
47 const std::string URI_ARG_FIRST_DELIMITER = "?";
48 const std::string URI_API_VERSION_STR = std::to_string(static_cast<uint32_t>(MediaLibraryApi::API_10));
49 const std::string URI_API_VERSION = URI_PARAM_API_VERSION + "=" + URI_API_VERSION_STR;
50 
51 enum class MediaToolOperation {
52     INSERT,
53     QUERY,
54     CLOSE,
55     DELETE,
56     UPDATE,
57     LIST
58 };
59 
60 const std::map<MediaToolOperation, std::string> PHOTOOPRN_URI_MAP = {
61     { MediaToolOperation::INSERT, TOOL_CREATE_PHOTO },
62     { MediaToolOperation::QUERY, TOOL_QUERY_PHOTO },
63     { MediaToolOperation::LIST, TOOL_LIST_PHOTO },
64     { MediaToolOperation::CLOSE, TOOL_CLOSE_PHOTO },
65     { MediaToolOperation::DELETE, TOOL_DELETE_PHOTO },
66     { MediaToolOperation::UPDATE, TOOL_UPDATE_PHOTO }
67 };
68 
69 const std::map<MediaToolOperation, std::string> AUDIOOPRN_URI_MAP = {
70     { MediaToolOperation::INSERT, TOOL_CREATE_AUDIO },
71     { MediaToolOperation::QUERY, TOOL_QUERY_AUDIO },
72     { MediaToolOperation::LIST, TOOL_LIST_AUDIO },
73     { MediaToolOperation::CLOSE, TOOL_CLOSE_AUDIO },
74     { MediaToolOperation::DELETE, TOOL_DELETE_AUDIO },
75     { MediaToolOperation::UPDATE, TOOL_UPDATE_AUDIO }
76 };
77 
GetOperation(const std::string & tableName,MediaToolOperation oprn)78 static std::string GetOperation(const std::string &tableName, MediaToolOperation oprn)
79 {
80     if (tableName == PhotoColumn::PHOTOS_TABLE) {
81         auto item = PHOTOOPRN_URI_MAP.find(oprn);
82         if (item != PHOTOOPRN_URI_MAP.end()) {
83             return item->second;
84         }
85     } else if (tableName == AudioColumn::AUDIOS_TABLE) {
86         auto item = AUDIOOPRN_URI_MAP.find(oprn);
87         if (item != AUDIOOPRN_URI_MAP.end()) {
88             return item->second;
89         }
90     }
91     MEDIA_ERR_LOG("get operation failed. tableName:%{public}s", tableName.c_str());
92     return "";
93 }
94 
CheckTableName(const std::string & tableName)95 static bool CheckTableName(const std::string &tableName)
96 {
97     static const std::set<std::string> VALID_TABLENAME_WHITELIST = {
98         PhotoColumn::PHOTOS_TABLE,
99         AudioColumn::AUDIOS_TABLE
100     };
101     if (tableName.empty()) {
102         return false;
103     }
104     if (VALID_TABLENAME_WHITELIST.find(tableName) == VALID_TABLENAME_WHITELIST.end()) {
105         return false;
106     }
107     return true;
108 }
109 
GetUriInfo(const std::string & uri,std::string & uriId)110 static inline bool GetUriInfo(const std::string &uri, std::string &uriId)
111 {
112     MediaFileUri fileUri(uri);
113     if (!fileUri.IsValid()) {
114         MEDIA_ERR_LOG("uri %{public}s is invalid", uri.c_str());
115         return false;
116     }
117     uriId = fileUri.GetFileId();
118     return true;
119 }
120 
GetInsertUri(const std::string & tableName)121 static inline std::string GetInsertUri(const std::string &tableName)
122 {
123     std::string uri = GetOperation(tableName, MediaToolOperation::INSERT);
124     if (uri.empty()) {
125         MEDIA_ERR_LOG("get insert uri failed. tableName:%{public}s", tableName.c_str());
126         return uri;
127     }
128     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
129     return uri;
130 }
131 
GetQueryUri(const std::string & tableName)132 static inline std::string GetQueryUri(const std::string &tableName)
133 {
134     std::string uri = GetOperation(tableName, MediaToolOperation::QUERY);
135     if (uri.empty()) {
136         MEDIA_ERR_LOG("get query uri failed. tableName:%{public}s", tableName.c_str());
137         return uri;
138     }
139     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
140     return uri;
141 }
142 
GetListUri(const std::string & tableName)143 static inline std::string GetListUri(const std::string &tableName)
144 {
145     std::string uri = GetOperation(tableName, MediaToolOperation::LIST);
146     if (uri.empty()) {
147         MEDIA_ERR_LOG("get list uri failed. tableName:%{public}s", tableName.c_str());
148         return uri;
149     }
150     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
151     return uri;
152 }
153 
GetCloseUri(const std::string & tableName)154 static inline std::string GetCloseUri(const std::string &tableName)
155 {
156     std::string uri = GetOperation(tableName, MediaToolOperation::CLOSE);
157     if (uri.empty()) {
158         MEDIA_ERR_LOG("get close uri failed. tableName:%{public}s", tableName.c_str());
159         return uri;
160     }
161     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
162     return uri;
163 }
164 
GetUpdateUri(const std::string & tableName)165 static inline std::string GetUpdateUri(const std::string &tableName)
166 {
167     std::string uri = GetOperation(tableName, MediaToolOperation::UPDATE);
168     if (uri.empty()) {
169         MEDIA_ERR_LOG("get update uri failed. tableName:%{public}s", tableName.c_str());
170         return uri;
171     }
172     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
173     return uri;
174 }
175 
GetDeleteUri(const std::string & tableName)176 static inline std::string GetDeleteUri(const std::string &tableName)
177 {
178     std::string uri = GetOperation(tableName, MediaToolOperation::DELETE);
179     if (uri.empty()) {
180         MEDIA_ERR_LOG("get delete uri failed. tableName:%{public}s", tableName.c_str());
181         return uri;
182     }
183     uri.append(URI_ARG_FIRST_DELIMITER + URI_API_VERSION);
184     return uri;
185 }
186 
InitToken(const sptr<IRemoteObject> & token)187 static bool InitToken(const sptr<IRemoteObject> &token)
188 {
189     UserFileClient::Init(token);
190     return UserFileClient::IsValid();
191 }
192 
Init()193 int32_t UserFileClientEx::Init()
194 {
195     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
196     if (saManager == nullptr) {
197         MEDIA_ERR_LOG("get system ability mgr failed.");
198         return Media::E_ERR;
199     }
200     auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
201     if (remoteObj == nullptr) {
202         MEDIA_ERR_LOG("GetSystemAbility Service failed.");
203         return Media::E_ERR;
204     }
205     if (!InitToken(remoteObj)) {
206         MEDIA_ERR_LOG("set DataShareHelper failed.");
207         return Media::E_ERR;
208     }
209     return Media::E_OK;
210 }
211 
Clear()212 void UserFileClientEx::Clear()
213 {
214     UserFileClient::Clear();
215 }
216 
InsertExt(const std::string & tableName,const std::string & name,std::string & outString,bool isRestart)217 int32_t UserFileClientEx::InsertExt(const std::string &tableName, const std::string &name,
218     std::string &outString, bool isRestart)
219 {
220     if (isRestart && Init() != Media::E_OK) {
221         MEDIA_ERR_LOG("Init failed");
222         return Media::E_ERR;
223     }
224     std::string insertUriStr = GetInsertUri(tableName);
225     if (insertUriStr.empty()) {
226         MEDIA_ERR_LOG("insert failed. tableName:%{public}s, name:%{public}s", tableName.c_str(),
227             name.c_str());
228         return Media::E_ERR;
229     }
230     Uri insertUri(insertUriStr);
231     DataShare::DataShareValuesBucket values;
232     values.Put(MediaColumn::MEDIA_NAME, name);
233     string mimeType = MimeTypeUtils::GetMimeTypeFromExtension(ScannerUtils::GetFileExtension(name));
234     values.Put(MediaColumn::MEDIA_TYPE, MimeTypeUtils::GetMediaTypeFromMimeType(mimeType));
235     values.Put(MediaColumn::MEDIA_OWNER_PACKAGE, "com.mediatool.album");
236     values.Put(MediaColumn::MEDIA_OWNER_APPID, "mediatool.appid");
237     values.Put(MediaColumn::MEDIA_PACKAGE_NAME, "mediatool");
238     MEDIA_INFO_LOG("insertext. insertUri:%{public}s, name:%{public}s", insertUri.ToString().c_str(), name.c_str());
239     auto ret = UserFileClient::InsertExt(insertUri, values, outString);
240     if (ret <= 0) {
241         MEDIA_ERR_LOG("insertext failed. ret:%{public}d", ret);
242     }
243     return ret;
244 }
245 
Query(const std::string & tableName,const std::string & uri,std::shared_ptr<DataShare::DataShareResultSet> & resultSet,bool isRestart)246 int32_t UserFileClientEx::Query(const std::string &tableName, const std::string &uri,
247     std::shared_ptr<DataShare::DataShareResultSet> &resultSet, bool isRestart)
248 {
249     if (isRestart && Init() != Media::E_OK) {
250         MEDIA_ERR_LOG("Init failed");
251         return Media::E_ERR;
252     }
253     if (!CheckTableName(tableName)) {
254         MEDIA_ERR_LOG("tableName %{public}s is Invalid", tableName.c_str());
255         return Media::E_ERR;
256     }
257     resultSet = nullptr;
258     std::string id;
259     if ((!uri.empty()) && (!GetUriInfo(uri, id))) {
260         MEDIA_ERR_LOG("query failed, uri:%{public}s", uri.c_str());
261         return Media::E_ERR;
262     }
263     std::string queryUriStr = GetListUri(tableName);
264     if (queryUriStr.empty()) {
265         MEDIA_ERR_LOG("query failed. queryUriStr:empty, tableName:%{public}s", tableName.c_str());
266         return Media::E_ERR;
267     }
268     Uri queryUri(queryUriStr);
269     DataShare::DataSharePredicates predicates;
270     // Id is empty, meaning get all object from table
271     if (!id.empty()) {
272         predicates.And()->EqualTo(MediaColumn::MEDIA_ID, id);
273     }
274     std::vector<std::string> columns;
275     int errCode = 0;
276     MEDIA_INFO_LOG("query. queryUri:%{public}s, tableName:%{public}s, uri:%{public}s, "
277         "id:%{public}s", queryUri.ToString().c_str(), tableName.c_str(), uri.c_str(), id.c_str());
278     resultSet = UserFileClient::Query(queryUri, predicates, columns, errCode);
279     if (resultSet == nullptr) {
280         MEDIA_ERR_LOG("query failed. resultSet:null, errCode:%{public}d.", errCode);
281         return ((errCode == Media::E_OK) ? Media::E_OK : Media::E_ERR);
282     }
283     if (errCode != Media::E_OK) {
284         MEDIA_ERR_LOG("query failed. errCode:%{public}d.", errCode);
285         resultSet->Close();
286         return Media::E_ERR;
287     }
288     return Media::E_OK;
289 }
290 
Open(const std::string & uri,const std::string & mode,bool isRestart)291 int UserFileClientEx::Open(const std::string &uri, const std::string &mode, bool isRestart)
292 {
293     if (isRestart && Init() != Media::E_OK) {
294         MEDIA_ERR_LOG("Init failed");
295         return Media::E_ERR;
296     }
297     if (uri.empty()) {
298         return Media::E_FAIL;
299     }
300     std::string uriWithKey {uri};
301     MediaFileUtils::UriAppendKeyValue(uriWithKey, IS_TOOL_OPEN,
302         TOOL_OPEN_TRUE);
303     Uri openUri(uriWithKey);
304     MEDIA_INFO_LOG("open. uri:%{public}s, mode:%{public}s", uriWithKey.c_str(), mode.c_str());
305     return UserFileClient::OpenFile(openUri, mode);
306 }
307 
Close(const std::string & uri,const int fileFd,const std::string & mode,bool isCreateThumbSync,bool isRestart)308 int UserFileClientEx::Close(const std::string &uri, const int fileFd, const std::string &mode,
309     bool isCreateThumbSync, bool isRestart)
310 {
311     if (isRestart && Init() != Media::E_OK) {
312         MEDIA_ERR_LOG("Init failed");
313         return Media::E_ERR;
314     }
315     if (!UserFileClient::IsValid()) {
316         MEDIA_ERR_LOG("close failed. helper:null. uri:%{public}s, fileFd:%{public}d, mode:%{public}s",
317             uri.c_str(), fileFd, mode.c_str());
318         return Media::E_FAIL;
319     }
320     if (mode == Media::MEDIA_FILEMODE_READONLY) {
321         if (close(fileFd) != E_SUCCESS) {
322             MEDIA_ERR_LOG("close failed. uri:%{public}s, fileFd:%{public}d, mode:%{public}s",
323                 uri.c_str(), fileFd, mode.c_str());
324             return Media::E_FAIL;
325         }
326         return Media::E_OK;
327     }
328     DataShare::DataShareValuesBucket valuesBucket;
329     valuesBucket.Put(MEDIA_DATA_DB_URI, uri);
330     if (isCreateThumbSync) {
331         valuesBucket.Put(CLOSE_CREATE_THUMB_STATUS, CREATE_THUMB_SYNC_STATUS);
332     }
333     std::string closeUriStr = GetCloseUri(GetTableNameByUri(uri));
334     if (closeUriStr.empty()) {
335         MEDIA_ERR_LOG("get close uri failed. uri:%{public}s", uri.c_str());
336         return Media::E_FAIL;
337     }
338     Uri closeUri(closeUriStr);
339     MEDIA_INFO_LOG("close. closeUri:%{public}s, uri:%{public}s", closeUri.ToString().c_str(), uri.c_str());
340     auto ret = UserFileClient::Insert(closeUri, valuesBucket);
341     if (ret != Media::E_OK) {
342         MEDIA_ERR_LOG("close the file failed. ret:%{public}d, closeUri:%{public}s, uri:%{public}s",
343             ret, closeUri.ToString().c_str(), uri.c_str());
344     }
345     if (close(fileFd) != E_SUCCESS) {
346         MEDIA_ERR_LOG("close failed. uri:%{public}s, fileFd:%{public}d, mode:%{public}s",
347             uri.c_str(), fileFd, mode.c_str());
348         return Media::E_FAIL;
349     }
350     return ret;
351 }
352 
Trash(const std::string & uri,bool isRestart)353 int32_t UserFileClientEx::Trash(const std::string &uri, bool isRestart)
354 {
355     if (isRestart && Init() != Media::E_OK) {
356         MEDIA_ERR_LOG("Init failed");
357         return Media::E_ERR;
358     }
359     if (!UserFileClient::IsValid()) {
360         MEDIA_ERR_LOG("close failed. helper:null.");
361         return Media::E_FAIL;
362     }
363     MediaFileUri fileUri(uri);
364     if (!fileUri.IsValid()) {
365         MEDIA_ERR_LOG("FileUri %{public}s is not Valid", uri.c_str());
366         return Media::E_FAIL;
367     }
368     string tableName = GetTableNameByUri(uri);
369     std::string trashUriStr = GetUpdateUri(tableName);
370     if (trashUriStr.empty()) {
371         MEDIA_ERR_LOG("get trash uri failed. uri:%{public}s", uri.c_str());
372         return Media::E_FAIL;
373     }
374 
375     DataShare::DataShareValuesBucket valuesBucket;
376     valuesBucket.Put(MediaColumn::MEDIA_DATE_TRASHED, MediaFileUtils::UTCTimeMilliSeconds());
377     DataShare::DataSharePredicates predicates;
378     predicates.SetWhereClause(MediaColumn::MEDIA_ID + " = ? ");
379     predicates.SetWhereArgs({ fileUri.GetFileId() });
380     Uri trashUri(trashUriStr);
381     MEDIA_INFO_LOG("trash. trashUri:%{public}s, uri:%{public}s", trashUri.ToString().c_str(), uri.c_str());
382     auto ret = UserFileClient::Update(trashUri, predicates, valuesBucket);
383     if (ret < 0) {
384         MEDIA_ERR_LOG("trash the file failed. ret:%{public}d, trashUri:%{public}s, uri:%{public}s",
385             ret, trashUri.ToString().c_str(), uri.c_str());
386     }
387     return ret;
388 }
389 
Delete(const std::string & uri,bool isRestart)390 int32_t UserFileClientEx::Delete(const std::string &uri, bool isRestart)
391 {
392     if (isRestart && Init() != Media::E_OK) {
393         MEDIA_ERR_LOG("Init failed");
394         return Media::E_ERR;
395     }
396     if (!UserFileClient::IsValid()) {
397         MEDIA_ERR_LOG("close failed. helper:null.");
398         return Media::E_FAIL;
399     }
400     MediaFileUri fileUri(uri);
401     if (!fileUri.IsValid()) {
402         MEDIA_ERR_LOG("FileUri %{public}s is not Valid", uri.c_str());
403         return Media::E_FAIL;
404     }
405     string tableName = GetTableNameByUri(uri);
406     std::string deleteUriStr = GetDeleteUri(tableName);
407     if (deleteUriStr.empty()) {
408         MEDIA_ERR_LOG("get delete uri failed. uri:%{public}s", uri.c_str());
409         return Media::E_FAIL;
410     }
411 
412     DataShare::DataSharePredicates predicates;
413     predicates.EqualTo(MediaColumn::MEDIA_ID, fileUri.GetFileId());
414     DataShare::DataShareValuesBucket valuesBucket;
415     valuesBucket.Put(PhotoColumn::MEDIA_DATE_TRASHED, 0);
416     Uri deleteUri(deleteUriStr);
417     MEDIA_INFO_LOG("delete. deleteUri:%{public}s, uri:%{public}s", deleteUri.ToString().c_str(), uri.c_str());
418     int ret = 0;
419     if (tableName == PhotoColumn::PHOTOS_TABLE) {
420         ret = UserFileClient::Update(deleteUri, predicates, valuesBucket);
421     } else if (tableName == AudioColumn::AUDIOS_TABLE) {
422         ret = UserFileClient::Delete(deleteUri, predicates);
423     } else {
424         MEDIA_ERR_LOG("invalid table name: %{public}s", tableName.c_str());
425     }
426 
427     if (ret < 0) {
428         MEDIA_ERR_LOG("delete the file failed. ret:%{public}d, deleteUri:%{public}s, uri:%{public}s",
429             ret, deleteUri.ToString().c_str(), uri.c_str());
430     }
431     return ret;
432 }
433 
Delete(bool isOnlyDeleteDb,bool isRestart)434 int32_t UserFileClientEx::Delete(bool isOnlyDeleteDb, bool isRestart)
435 {
436     if (isRestart && Init() != Media::E_OK) {
437         MEDIA_ERR_LOG("Init failed");
438         return Media::E_ERR;
439     }
440     if (!UserFileClient::IsValid()) {
441         MEDIA_ERR_LOG("close failed. helper:null.");
442         return Media::E_FAIL;
443     }
444     DataShare::DataShareValuesBucket valuesBucket;
445     valuesBucket.Put(DELETE_TOOL_ONLY_DATABASE, isOnlyDeleteDb);
446     std::string uri = URI_DELETE_TOOL;
447     Uri deleteUri(uri);
448     auto ret = UserFileClient::Insert(deleteUri, valuesBucket);
449     if (ret != Media::E_OK) {
450         MEDIA_ERR_LOG("Delete all Files in MediaLibrary failed, ret=%{public}d", ret);
451     }
452     return ret;
453 }
454 
GetResultsetByDisplayName(const std::string & tableName,const std::string & displayName)455 std::shared_ptr<DataShare::DataShareResultSet> UserFileClientEx::GetResultsetByDisplayName(
456     const std::string &tableName, const std::string &displayName)
457 {
458     DataShare::DataSharePredicates predicates;
459     predicates.And()->EqualTo(MediaColumn::MEDIA_NAME, displayName);
460     std::vector<std::string> columns = { MediaColumn::MEDIA_FILE_PATH };
461     int queryErrCode = 0;
462     std::string queryUriStr = GetQueryUri(tableName);
463     if (queryUriStr.empty()) {
464         MEDIA_ERR_LOG("query failed. queryUriStr:empty, tableName:%{public}s", tableName.c_str());
465     }
466     Uri filesQueryUri(queryUriStr);
467     auto resultSet = UserFileClient::Query(filesQueryUri, predicates, columns, queryErrCode);
468     return resultSet;
469 }
470 
GetTableNameByMediaType(const MediaType mediaType)471 std::string UserFileClientEx::GetTableNameByMediaType(const MediaType mediaType)
472 {
473     static const std::map<MediaType, std::string> TYPE_TABLE_MAP = {
474         { MediaType::MEDIA_TYPE_AUDIO, AudioColumn::AUDIOS_TABLE },
475         { MediaType::MEDIA_TYPE_IMAGE, PhotoColumn::PHOTOS_TABLE },
476         { MediaType::MEDIA_TYPE_VIDEO, PhotoColumn::PHOTOS_TABLE },
477         { MediaType::MEDIA_TYPE_PHOTO, PhotoColumn::PHOTOS_TABLE }
478     };
479     std::string tableName;
480     auto item = TYPE_TABLE_MAP.find(mediaType);
481     if (item != TYPE_TABLE_MAP.end()) {
482         tableName = item->second;
483     } else {
484         MEDIA_ERR_LOG("get table name failed. mediaType:%{public}d", mediaType);
485     }
486     return tableName;
487 }
488 
GetTableNameByUri(const std::string & uri)489 std::string UserFileClientEx::GetTableNameByUri(const std::string &uri)
490 {
491     MediaFileUri fileUri(uri);
492     if (!fileUri.IsValid()) {
493         MEDIA_ERR_LOG("uri %{public}s is invalid", uri.c_str());
494         return "";
495     }
496     return fileUri.GetTableName();
497 }
498 
GetSupportTypes()499 const std::vector<MediaType> &UserFileClientEx::GetSupportTypes()
500 {
501     static const std::vector<MediaType> SUPPORT_TYPES = {
502         MediaType::MEDIA_TYPE_AUDIO,
503         MediaType::MEDIA_TYPE_IMAGE,
504         MediaType::MEDIA_TYPE_VIDEO
505     };
506     return SUPPORT_TYPES;
507 }
508 
GetSupportTables()509 const std::vector<std::string> &UserFileClientEx::GetSupportTables()
510 {
511     static const std::vector<std::string> SUPPORT_TABLES = {
512         PhotoColumn::PHOTOS_TABLE,
513         AudioColumn::AUDIOS_TABLE
514     };
515     return SUPPORT_TABLES;
516 }
517 } // namespace MediaTool
518 } // namespace Media
519 } // namespace OHOS
520