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