• 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 #define MLOG_TAG "MediaLibraryExtendManager"
16 
17 #include "media_library_extend_manager.h"
18 
19 #include "accesstoken_kit.h"
20 #include "datashare_abs_result_set.h"
21 #include "datashare_predicates.h"
22 #include "file_uri.h"
23 #include "iservice_registry.h"
24 #include "media_file_uri.h"
25 #include "media_file_utils.h"
26 #include "media_log.h"
27 #include "medialibrary_errno.h"
28 #include "medialibrary_tracer.h"
29 #include "medialibrary_type_const.h"
30 #include "media_app_uri_permission_column.h"
31 #include "media_app_uri_sensitive_column.h"
32 #include "moving_photo_file_utils.h"
33 #include "os_account_manager.h"
34 #include "permission_utils.h"
35 #include "result_set_utils.h"
36 #include "string_ex.h"
37 #include "system_ability_definition.h"
38 #include "unique_fd.h"
39 #include "userfilemgr_uri.h"
40 
41 using namespace std;
42 using namespace OHOS::NativeRdb;
43 using namespace OHOS::Security::AccessToken;
44 namespace OHOS {
45 namespace Media {
46 constexpr int32_t URI_MAX_SIZE = 1000;
47 constexpr uint32_t URI_PERMISSION_FLAG_READ = 1;
48 constexpr uint32_t URI_PERMISSION_FLAG_WRITE = 2;
49 constexpr uint32_t URI_PERMISSION_FLAG_READWRITE = 3;
50 constexpr int32_t DEFUALT_USER_ID = 100;
51 constexpr int32_t DATASHARE_ERR = -1;
52 
53 static map<string, TableType> tableMap = {
54     { MEDIALIBRARY_TYPE_IMAGE_URI, TableType::TYPE_PHOTOS },
55     { MEDIALIBRARY_TYPE_VIDEO_URI, TableType::TYPE_PHOTOS },
56     { MEDIALIBRARY_TYPE_AUDIO_URI, TableType::TYPE_AUDIOS },
57     { PhotoColumn::PHOTO_TYPE_URI, TableType::TYPE_PHOTOS },
58     { AudioColumn::AUDIO_TYPE_URI, TableType::TYPE_AUDIOS }
59 };
60 
GetMediaLibraryExtendManager()61 MediaLibraryExtendManager *MediaLibraryExtendManager::GetMediaLibraryExtendManager()
62 {
63     static MediaLibraryExtendManager mediaLibMgr;
64     return &mediaLibMgr;
65 }
66 
InitToken()67 static sptr<IRemoteObject> InitToken()
68 {
69     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70     CHECK_AND_RETURN_RET_LOG(saManager != nullptr, nullptr, "get system ability mgr failed.");
71 
72     auto remoteObj = saManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
73     CHECK_AND_RETURN_RET_LOG(remoteObj != nullptr, nullptr, "GetSystemAbility Service failed.");
74     return remoteObj;
75 }
76 
GetCurrentAccountId()77 static int32_t GetCurrentAccountId()
78 {
79     int32_t activeUserId = DEFUALT_USER_ID;
80     ErrCode ret = OHOS::AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(activeUserId);
81     if (ret != ERR_OK) {
82         MEDIA_ERR_LOG("fail to get activeUser:%{public}d", ret);
83     }
84     return activeUserId;
85 }
86 
InitMediaLibraryExtendManager()87 void MediaLibraryExtendManager::InitMediaLibraryExtendManager()
88 {
89     int32_t activeUser =  GetCurrentAccountId();
90     if (dataShareHelper_ == nullptr || activeUser != userId_) {
91         auto token = InitToken();
92         if (token == nullptr) {
93             MEDIA_ERR_LOG("fail to get token.");
94             return;
95         }
96         dataShareHelper_ = DataShare::DataShareHelper::Creator(token, MEDIALIBRARY_DATA_URI);
97         userId_ = activeUser;
98     }
99 }
100 
ForceReconnect()101 bool MediaLibraryExtendManager::ForceReconnect()
102 {
103     dataShareHelper_ = nullptr;
104     InitMediaLibraryExtendManager();
105     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, false, "init manager fail");
106     return true;
107 }
108 
UrisSourceMediaTypeClassify(const vector<string> & urisSource,vector<string> & photoFileIds,vector<string> & audioFileIds)109 static int32_t UrisSourceMediaTypeClassify(const vector<string> &urisSource,
110     vector<string> &photoFileIds, vector<string> &audioFileIds)
111 {
112     for (const auto &uri : urisSource) {
113         int32_t tableType = -1;
114         for (const auto &iter : tableMap) {
115             if (uri.find(iter.first) != string::npos) {
116                 tableType = static_cast<int32_t>(iter.second);
117             }
118         }
119 
120         CHECK_AND_RETURN_RET_LOG(tableType != -1, E_ERR, "Uri invalid error, uri:%{private}s", uri.c_str());
121         string fileId = MediaFileUtils::GetIdFromUri(uri);
122         if (tableType == static_cast<int32_t>(TableType::TYPE_PHOTOS)) {
123             photoFileIds.emplace_back(fileId);
124         } else if (tableType == static_cast<int32_t>(TableType::TYPE_AUDIOS)) {
125             audioFileIds.emplace_back(fileId);
126         } else {
127             MEDIA_ERR_LOG("Uri invalid error, uri:%{private}s", uri.c_str());
128             return E_ERR;
129         }
130     }
131     return E_SUCCESS;
132 }
133 
CheckAccessTokenPermissionExecute(uint32_t tokenId,uint32_t checkFlag,TableType mediaType,bool & isReadable,bool & isWritable)134 static void CheckAccessTokenPermissionExecute(uint32_t tokenId, uint32_t checkFlag, TableType mediaType,
135     bool &isReadable, bool &isWritable)
136 {
137     static map<TableType, string> readPermmisionMap = {
138         { TableType::TYPE_PHOTOS, PERM_READ_IMAGEVIDEO },
139         { TableType::TYPE_AUDIOS, PERM_READ_AUDIO }
140     };
141     static map<TableType, string> writePermmisionMap = {
142         { TableType::TYPE_PHOTOS, PERM_WRITE_IMAGEVIDEO },
143         { TableType::TYPE_AUDIOS, PERM_WRITE_AUDIO }
144     };
145     int checkReadResult = -1;
146     int checkWriteResult = -1;
147     if (checkFlag == URI_PERMISSION_FLAG_READ) {
148         checkReadResult = AccessTokenKit::VerifyAccessToken(tokenId, readPermmisionMap[mediaType]);
149         if (checkReadResult != PermissionState::PERMISSION_GRANTED) {
150             checkReadResult = AccessTokenKit::VerifyAccessToken(tokenId, writePermmisionMap[mediaType]);
151         }
152     } else if (checkFlag == URI_PERMISSION_FLAG_WRITE) {
153         checkWriteResult = AccessTokenKit::VerifyAccessToken(tokenId, writePermmisionMap[mediaType]);
154     } else if (checkFlag == URI_PERMISSION_FLAG_READWRITE) {
155         checkReadResult = AccessTokenKit::VerifyAccessToken(tokenId, readPermmisionMap[mediaType]);
156         if (checkReadResult != PermissionState::PERMISSION_GRANTED) {
157             checkReadResult = AccessTokenKit::VerifyAccessToken(tokenId, writePermmisionMap[mediaType]);
158         }
159         checkWriteResult = AccessTokenKit::VerifyAccessToken(tokenId, writePermmisionMap[mediaType]);
160     }
161     isReadable = checkReadResult == PermissionState::PERMISSION_GRANTED;
162     isWritable = checkWriteResult == PermissionState::PERMISSION_GRANTED;
163 }
CheckAccessTokenPermission(uint32_t tokenId,uint32_t checkFlag,TableType mediaType,int64_t & queryFlag)164 static void CheckAccessTokenPermission(uint32_t tokenId, uint32_t checkFlag,
165     TableType mediaType, int64_t &queryFlag)
166 {
167     bool isReadable = false;
168     bool isWritable = false;
169     CheckAccessTokenPermissionExecute(tokenId, checkFlag, mediaType, isReadable, isWritable);
170 
171     if (checkFlag == URI_PERMISSION_FLAG_READ) {
172         queryFlag = isReadable ? -1 : URI_PERMISSION_FLAG_READ;
173     } else if (checkFlag == URI_PERMISSION_FLAG_WRITE) {
174         queryFlag = isWritable ? -1 : URI_PERMISSION_FLAG_WRITE;
175     } else if (checkFlag == URI_PERMISSION_FLAG_READWRITE) {
176         if (isReadable && isWritable) {
177             queryFlag = -1;
178         } else if (isReadable) {
179             queryFlag = URI_PERMISSION_FLAG_WRITE;
180         } else if (isWritable) {
181             queryFlag = URI_PERMISSION_FLAG_READ;
182         } else {
183             queryFlag = URI_PERMISSION_FLAG_READWRITE;
184         }
185     }
186 }
187 
MakePredicatesForCheckPhotoUriPermission(int64_t & checkFlag,DataSharePredicates & predicates,uint32_t targetTokenId,TableType mediaType,vector<string> & fileIds)188 static void MakePredicatesForCheckPhotoUriPermission(int64_t &checkFlag, DataSharePredicates &predicates,
189     uint32_t targetTokenId, TableType mediaType, vector<string> &fileIds)
190 {
191     predicates.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, (int64_t)targetTokenId);
192     predicates.And()->EqualTo(AppUriPermissionColumn::URI_TYPE, to_string(static_cast<int32_t>(mediaType)));
193     predicates.And()->In(AppUriPermissionColumn::FILE_ID, fileIds);
194     vector<string> permissionTypes;
195     switch (checkFlag) {
196         case URI_PERMISSION_FLAG_READ:
197             permissionTypes.emplace_back(
198                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO)));
199             permissionTypes.emplace_back(
200                 to_string(static_cast<int32_t>(PhotoPermissionType::PERSIST_READ_IMAGEVIDEO)));
201             permissionTypes.emplace_back(
202                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
203             permissionTypes.emplace_back(
204                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
205             permissionTypes.emplace_back(
206                 to_string(static_cast<int32_t>(AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE)));
207             break;
208         case URI_PERMISSION_FLAG_WRITE:
209             permissionTypes.emplace_back(
210                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
211             permissionTypes.emplace_back(
212                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
213             permissionTypes.emplace_back(
214                 to_string(static_cast<int32_t>(AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE)));
215             break;
216         case URI_PERMISSION_FLAG_READWRITE:
217             permissionTypes.emplace_back(
218                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
219             permissionTypes.emplace_back(
220                 to_string(static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
221             permissionTypes.emplace_back(
222                 to_string(static_cast<int32_t>(AppUriPermissionColumn::PERMISSION_PERSIST_READ_WRITE)));
223             break;
224         default:
225             MEDIA_ERR_LOG("error flag object: %{public}ld", (long)checkFlag);
226             return;
227     }
228     predicates.And()->In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
229     predicates.OrderByDesc(AppUriPermissionColumn::PERMISSION_TYPE);
230 }
231 
CheckPhotoUriPermissionQueryOperation(const DataSharePredicates & predicates,map<string,int32_t> & resultMap)232 int32_t MediaLibraryExtendManager::CheckPhotoUriPermissionQueryOperation(const DataSharePredicates &predicates,
233     map<string, int32_t> &resultMap)
234 {
235     vector<string> columns = {
236         AppUriPermissionColumn::FILE_ID,
237         AppUriPermissionColumn::PERMISSION_TYPE
238     };
239     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR,
240         "Failed to checkPhotoUriPermission, datashareHelper is nullptr");
241 
242     Uri uri(MEDIALIBRARY_CHECK_URIPERM_URI);
243     auto queryResultSet = dataShareHelper_->Query(uri, predicates, columns);
244     if (queryResultSet == nullptr && ForceReconnect()) {
245         MEDIA_WARN_LOG("resultset is null, reconnect and retry");
246         queryResultSet = dataShareHelper_->Query(uri, predicates, columns);
247     }
248     CHECK_AND_RETURN_RET_LOG(queryResultSet != nullptr, E_ERR, "queryResultSet is null!");
249 
250     while (queryResultSet->GoToNextRow() == NativeRdb::E_OK) {
251         string fileId = GetStringVal(AppUriPermissionColumn::FILE_ID, queryResultSet);
252         int32_t permissionType = GetInt32Val(AppUriPermissionColumn::PERMISSION_TYPE, queryResultSet);
253         resultMap[fileId] = permissionType;
254     }
255     return E_SUCCESS;
256 }
257 
SetCheckPhotoUriPermissionResult(const vector<string> & urisSource,const map<string,int32_t> & photoResultMap,const map<string,int32_t> & audioResultMap,int32_t queryPhotoFlag,int32_t queryAudioFlag)258 static vector<bool> SetCheckPhotoUriPermissionResult(const vector<string> &urisSource,
259     const map<string, int32_t> &photoResultMap, const map<string, int32_t> &audioResultMap,
260     int32_t queryPhotoFlag, int32_t queryAudioFlag)
261 {
262     vector<bool> results;
263     for (const auto &uri : urisSource) {
264         int32_t tableType = -1;
265         for (const auto &iter : tableMap) {
266             if (uri.find(iter.first) != string::npos) {
267                 tableType = static_cast<int32_t>(iter.second);
268             }
269         }
270         string fileId = MediaFileUtils::GetIdFromUri(uri);
271         if (tableType == static_cast<int32_t>(TableType::TYPE_PHOTOS)) {
272             if (queryPhotoFlag == -1 || photoResultMap.find(fileId) != photoResultMap.end()) {
273                 results.emplace_back(true);
274             } else {
275                 results.emplace_back(false);
276             }
277         } else if (tableType == static_cast<int32_t>(TableType::TYPE_AUDIOS)) {
278             if (queryAudioFlag == -1 || audioResultMap.find(fileId) != audioResultMap.end()) {
279                 results.emplace_back(true);
280             } else {
281                 results.emplace_back(false);
282             }
283         }
284     }
285     return results;
286 }
287 
CheckInputParameters(const vector<string> & urisSource,uint32_t flag)288 static int32_t CheckInputParameters(const vector<string> &urisSource, uint32_t flag)
289 {
290     CHECK_AND_RETURN_RET_LOG(!urisSource.empty(), E_ERR, "Media Uri list is empty");
291     CHECK_AND_RETURN_RET_LOG(urisSource.size() <= URI_MAX_SIZE, E_ERR,
292         "Uri list is exceed one Thousand, current list size: %{public}d", (int)urisSource.size());
293     bool cond = (flag == 0 || flag > URI_PERMISSION_FLAG_READWRITE);
294     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "Flag is invalid, current flag is: %{public}d", flag);
295     return E_SUCCESS;
296 }
297 
CheckPhotoUriPermission(uint32_t tokenId,const vector<string> & urisSource,vector<bool> & results,uint32_t flag)298 int32_t MediaLibraryExtendManager::CheckPhotoUriPermission(uint32_t tokenId,
299     const vector<string> &urisSource, vector<bool> &results, uint32_t flag)
300 {
301     MediaLibraryTracer tracer;
302     tracer.Start("MediaLibraryExtendManager::CheckPhotoUriPermission");
303     auto ret = CheckInputParameters(urisSource, flag);
304     CHECK_AND_RETURN_RET(ret == E_SUCCESS, E_ERR);
305     vector<string> photoFileIds;
306     vector<string> audioFileIds;
307     ret = UrisSourceMediaTypeClassify(urisSource, photoFileIds, audioFileIds);
308     CHECK_AND_RETURN_RET(ret == E_SUCCESS, E_ERR);
309 
310     int64_t queryPhotoFlag = URI_PERMISSION_FLAG_READWRITE;
311     int64_t queryAudioFlag = URI_PERMISSION_FLAG_READWRITE;
312     if (photoFileIds.empty()) {
313         queryPhotoFlag = -1;
314     } else {
315         CheckAccessTokenPermission(tokenId, flag, TableType::TYPE_PHOTOS, queryPhotoFlag);
316     }
317     if (audioFileIds.empty()) {
318         queryAudioFlag = -1;
319     } else {
320         CheckAccessTokenPermission(tokenId, flag, TableType::TYPE_AUDIOS, queryAudioFlag);
321     }
322     map<string, int32_t> photoResultMap;
323     map<string, int32_t> audioResultMap;
324     if (queryPhotoFlag != -1) {
325         DataSharePredicates predicates;
326         MakePredicatesForCheckPhotoUriPermission(queryPhotoFlag, predicates,
327             tokenId, TableType::TYPE_PHOTOS, photoFileIds);
328         auto ret = CheckPhotoUriPermissionQueryOperation(predicates, photoResultMap);
329         CHECK_AND_RETURN_RET(ret == E_SUCCESS, E_ERR);
330     }
331     if (queryAudioFlag != -1) {
332         DataSharePredicates predicates;
333         MakePredicatesForCheckPhotoUriPermission(queryAudioFlag, predicates,
334             tokenId, TableType::TYPE_AUDIOS, audioFileIds);
335         auto ret = CheckPhotoUriPermissionQueryOperation(predicates, audioResultMap);
336         CHECK_AND_RETURN_RET(ret == E_SUCCESS, E_ERR);
337     }
338     results = SetCheckPhotoUriPermissionResult(urisSource, photoResultMap, audioResultMap,
339         queryPhotoFlag, queryAudioFlag);
340     return E_SUCCESS;
341 }
342 
GrantPhotoUriPermission(uint32_t srcTokenId,uint32_t targetTokenId,const std::vector<string> & uris,PhotoPermissionType photoPermissionType,HideSensitiveType hideSensitiveTpye)343 int32_t MediaLibraryExtendManager::GrantPhotoUriPermission(uint32_t srcTokenId, uint32_t targetTokenId,
344     const std::vector<string> &uris, PhotoPermissionType photoPermissionType, HideSensitiveType hideSensitiveTpye)
345 {
346     MediaLibraryTracer tracer;
347     tracer.Start("MediaLibraryExtendManager::GrantPhotoUriPermission");
348     vector<DataShareValuesBucket> valueSet;
349     bool cond = ((uris.empty()) || (uris.size() > URI_MAX_SIZE));
350     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "Media Uri list error, please check!");
351     cond = (photoPermissionType != PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO &&
352         photoPermissionType != PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO &&
353         photoPermissionType != PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO);
354     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "photoPermissionType error, please check param!");
355 
356     cond = (hideSensitiveTpye < HideSensitiveType::ALL_DESENSITIZE ||
357         hideSensitiveTpye > HideSensitiveType::NO_DESENSITIZE);
358     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "HideSensitiveType error, please check param!");
359     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR, "dataShareHelper is nullptr");
360 
361     for (const auto &uri : uris) {
362         int32_t tableType = -1;
363         for (const auto &iter : tableMap) {
364             if (uri.find(iter.first) != string::npos) {
365                 tableType = static_cast<int32_t>(iter.second);
366             }
367         }
368 
369         CHECK_AND_RETURN_RET_LOG(tableType != -1, E_ERR, "Uri invalid error, uri:%{private}s", uri.c_str());
370         string fileId = MediaFileUtils::GetIdFromUri(uri);
371         DataShareValuesBucket valuesBucket;
372         valuesBucket.Put(AppUriPermissionColumn::SOURCE_TOKENID, (int64_t)srcTokenId);
373         valuesBucket.Put(AppUriPermissionColumn::TARGET_TOKENID, (int64_t)targetTokenId);
374         valuesBucket.Put(AppUriPermissionColumn::FILE_ID, fileId);
375         valuesBucket.Put(AppUriPermissionColumn::URI_TYPE, tableType);
376         valuesBucket.Put(AppUriPermissionColumn::PERMISSION_TYPE, static_cast<int32_t>(photoPermissionType));
377         valuesBucket.Put(AppUriSensitiveColumn::HIDE_SENSITIVE_TYPE, static_cast<int32_t>(hideSensitiveTpye));
378         valueSet.push_back(valuesBucket);
379     }
380     Uri insertUri(MEDIALIBRARY_GRANT_URIPERM_URI);
381     auto ret = dataShareHelper_->BatchInsert(insertUri, valueSet);
382     if (ret == DATASHARE_ERR && ForceReconnect()) {
383         MEDIA_WARN_LOG("Failed to BatchInsert and retry");
384         ret = dataShareHelper_->BatchInsert(insertUri, valueSet);
385     }
386     return ret;
387 }
388 
CancelPhotoUriPermission(uint32_t srcTokenId,uint32_t targetTokenId,const std::vector<string> & uris)389 int32_t MediaLibraryExtendManager::CancelPhotoUriPermission(uint32_t srcTokenId, uint32_t targetTokenId,
390     const std::vector<string> &uris)
391 {
392     MediaLibraryTracer tracer;
393     tracer.Start("MediaLibraryExtendManager::CancelPhotoUriPermission");
394     MEDIA_DEBUG_LOG("CancelPermission begin, srcToken:%{private}d, targetToken:%{private}d", srcTokenId, targetTokenId);
395     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR, "dataShareHelper is nullptr");
396     vector<DataShareValuesBucket> valueSet;
397     bool cond = ((uris.empty()) || (uris.size() > URI_MAX_SIZE));
398     CHECK_AND_RETURN_RET_LOG(!cond, E_ERR, "Media Uri list error, please check!");
399 
400     DataSharePredicates predicates;
401     for (size_t i = 0; i < uris.size(); i++) {
402         string uri = uris[i];
403         int32_t tableType = -1;
404         for (const auto &iter : tableMap) {
405             if (uri.find(iter.first) != string::npos) {
406                 tableType = static_cast<int32_t>(iter.second);
407             }
408         }
409         CHECK_AND_RETURN_RET_LOG(tableType != -1, E_ERR, "Uri invalid error, uri:%{private}s", uri.c_str());
410         string fileId = MediaFileUtils::GetIdFromUri(uri);
411         if (i > 0) {
412             predicates.Or();
413         }
414         MEDIA_DEBUG_LOG("CancelPermission fileId:%{private}s, tableType:%{private}d", fileId.c_str(), tableType);
415         predicates.BeginWrap();
416         predicates.BeginWrap();
417         predicates.EqualTo(AppUriPermissionColumn::SOURCE_TOKENID, (int64_t)srcTokenId);
418         predicates.Or();
419         predicates.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, (int64_t)srcTokenId);
420         predicates.EndWrap();
421         predicates.EqualTo(AppUriPermissionColumn::FILE_ID, fileId);
422         predicates.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, (int64_t)targetTokenId);
423         predicates.EqualTo(AppUriPermissionColumn::URI_TYPE, tableType);
424         predicates.NotEqualTo(AppUriPermissionColumn::PERMISSION_TYPE,
425             static_cast<int>(PhotoPermissionType::PERSIST_READ_IMAGEVIDEO));
426         predicates.NotEqualTo(AppUriPermissionColumn::PERMISSION_TYPE,
427             static_cast<int>(PhotoPermissionType::PERSIST_READWRITE_IMAGEVIDEO));
428         predicates.EndWrap();
429     }
430     Uri deleteUri(MEDIALIBRARY_GRANT_URIPERM_URI);
431     return dataShareHelper_->Delete(deleteUri, predicates);
432 }
433 
CheckUri(string & uri)434 static bool CheckUri(string &uri)
435 {
436     if (uri.find("../") != string::npos) {
437         return false;
438     }
439     string uriprex = "file://media";
440     return uri.substr(0, uriprex.size()) == uriprex;
441 }
442 
OpenAsset(string & uri,const string openMode,HideSensitiveType type)443 int32_t MediaLibraryExtendManager::OpenAsset(string &uri, const string openMode, HideSensitiveType type)
444 {
445     CHECK_AND_RETURN_RET(!openMode.empty(), E_ERR);
446     CHECK_AND_RETURN_RET_LOG(CheckUri(uri), E_ERR, "invalid uri");
447 
448     string originOpenMode = openMode;
449     std::transform(originOpenMode.begin(), originOpenMode.end(),
450         originOpenMode.begin(), [](unsigned char c) {return std::tolower(c);});
451     CHECK_AND_RETURN_RET(MEDIA_OPEN_MODES.count(originOpenMode), E_ERR);
452     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR, "Failed to open Asset, datashareHelper is nullptr");
453 
454     string assetUri = uri;
455     MediaFileUtils::UriAppendKeyValue(assetUri, "type", to_string(static_cast<int32_t>(type)));
456     MEDIA_DEBUG_LOG("merged uri = %{public}s", assetUri.c_str());
457     Uri openUri(assetUri);
458     int ret = dataShareHelper_->OpenFile(openUri, openMode);
459     if (ret == DATASHARE_ERR && ForceReconnect()) {
460         MEDIA_WARN_LOG("Failed to OpenFile and retry");
461         ret = dataShareHelper_->OpenFile(openUri, openMode);
462     }
463     return ret;
464 }
465 
ReadPrivateMovingPhoto(string & uri,const HideSensitiveType type)466 int32_t MediaLibraryExtendManager::ReadPrivateMovingPhoto(string &uri, const HideSensitiveType type)
467 {
468     CHECK_AND_RETURN_RET_LOG(CheckUri(uri), E_ERR, "invalid uri: %{public}s", uri.c_str());
469     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, E_ERR,
470         "Failed to read video of moving photo, datashareHelper is nullptr");
471 
472     string movingPhotoUri = uri;
473     MediaFileUtils::UriAppendKeyValue(movingPhotoUri, "type", to_string(static_cast<int32_t>(type)));
474     MediaFileUtils::UriAppendKeyValue(movingPhotoUri, MEDIA_MOVING_PHOTO_OPRN_KEYWORD, OPEN_PRIVATE_LIVE_PHOTO);
475     Uri openMovingPhotoUri(movingPhotoUri);
476     int ret = dataShareHelper_->OpenFile(openMovingPhotoUri, MEDIA_FILEMODE_READONLY);
477     if (ret == DATASHARE_ERR && ForceReconnect()) {
478         MEDIA_WARN_LOG("Failed to OpenFile and retry");
479         ret = dataShareHelper_->OpenFile(openMovingPhotoUri, MEDIA_FILEMODE_READONLY);
480     }
481     return ret;
482 }
483 
CheckPhotoUri(const string & uri)484 static bool CheckPhotoUri(const string &uri)
485 {
486     if (uri.find("../") != string::npos) {
487         return false;
488     }
489     string photoUriPrefix = "file://media/Photo/";
490     return MediaFileUtils::StartsWith(uri, photoUriPrefix);
491 }
492 
GetResultSetFromPhotos(const string & value,vector<string> & columns)493 std::shared_ptr<DataShareResultSet> MediaLibraryExtendManager::GetResultSetFromPhotos(const string &value,
494     vector<string> &columns)
495 {
496     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr, "datashareHelper is nullptr");
497     if (!CheckPhotoUri(value)) {
498         MEDIA_ERR_LOG("Failed to check invalid uri: %{public}s", value.c_str());
499         return nullptr;
500     }
501     Uri queryUri(PAH_QUERY_PHOTO);
502     DataSharePredicates predicates;
503     string fileId = MediaFileUtils::GetIdFromUri(value);
504     predicates.EqualTo(MediaColumn::MEDIA_ID, fileId);
505     DatashareBusinessError businessError;
506     auto resultSet = dataShareHelper_->Query(queryUri, predicates, columns, &businessError);
507     if (resultSet == nullptr && ForceReconnect()) {
508         MEDIA_WARN_LOG("resultset is null, reconnect and retry");
509         return dataShareHelper_->Query(queryUri, predicates, columns, &businessError);
510     } else {
511         return resultSet;
512     }
513 }
514 
GetResultSetFromDb(string columnName,const string & value,vector<string> & columns)515 std::shared_ptr<DataShareResultSet> MediaLibraryExtendManager::GetResultSetFromDb(string columnName,
516     const string &value, vector<string> &columns)
517 {
518     CHECK_AND_RETURN_RET_LOG(dataShareHelper_ != nullptr, nullptr, "dataShareHelper is null");
519     if (columnName == MEDIA_DATA_DB_URI) {
520         return GetResultSetFromPhotos(value, columns);
521     }
522     Uri uri(MEDIALIBRARY_MEDIA_PREFIX);
523     DataSharePredicates predicates;
524     predicates.EqualTo(columnName, value);
525     predicates.And()->EqualTo(MEDIA_DATA_DB_IS_TRASH, to_string(NOT_TRASHED));
526     DatashareBusinessError businessError;
527     auto resultSet = dataShareHelper_->Query(uri, predicates, columns, &businessError);
528     if (resultSet == nullptr && ForceReconnect()) {
529         MEDIA_WARN_LOG("resultset is null, reconnect and retry");
530         return dataShareHelper_->Query(uri, predicates, columns, &businessError);
531     } else {
532         return resultSet;
533     }
534 }
535 } // namespace Media
536 } // namespace OHOS