• 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 #include "media_library_tab_old_photos_client.h"
16 
17 #include <limits>
18 #include <string>
19 #include <vector>
20 #include <unordered_map>
21 
22 #include "userfilemgr_uri.h"
23 #include "media_column.h"
24 #include "media_log.h"
25 #include "media_old_photos_column.h"
26 #include "medialibrary_errno.h"
27 #include "result_set_utils.h"
28 #include "datashare_helper.h"
29 #include "user_inner_ipc_client.h"
30 #include "medialibrary_business_code.h"
31 #include "get_uris_by_old_uris_inner_vo.h"
32 
33 using namespace std;
34 
35 namespace OHOS::Media {
36 
37 static constexpr int32_t FIRST = 0;
38 static constexpr int32_t SECOND = 1;
39 static constexpr int32_t THIRD = 2;
40 
UrisByOldUrisTest(std::vector<std::string> & uris,std::vector<std::vector<int32_t>> & file_and_outFile_Ids,std::vector<std::vector<std::string>> & stringParams)41 std::unordered_map<std::string, std::string> TabOldPhotosClient::UrisByOldUrisTest(std::vector<std::string>& uris,
42     std::vector<std::vector<int32_t>>& file_and_outFile_Ids,
43     std::vector<std::vector<std::string>>& stringParams)
44 {
45     std::vector<int32_t>& fileIds = file_and_outFile_Ids[FIRST];
46     std::vector<int32_t> oldFileIds = file_and_outFile_Ids[SECOND];
47     std::vector<std::string> datas = stringParams[FIRST];
48     std::vector<std::string> displayNames = stringParams[SECOND];
49     std::vector<std::string> oldDatas = stringParams[THIRD];
50     std::vector<TabOldPhotosClient::TabOldPhotosClientObj> dataMapping;
51     for (size_t i = 0; i < fileIds.size(); i++) {
52         TabOldPhotosClient::TabOldPhotosClientObj obj;
53         obj.fileId = fileIds[i];
54         obj.data = datas[i];
55         obj.displayName = displayNames[i];
56         obj.oldFileId = oldFileIds[i];
57         obj.oldData = oldDatas[i];
58         dataMapping.emplace_back(obj);
59     }
60     std::vector<TabOldPhotosClient::RequestUriObj> uriList = this->Parse(uris);
61     return this->Parse(dataMapping, uriList);
62 }
63 
GetUrisByOldUris(std::vector<std::string> & uris)64 std::unordered_map<std::string, std::string> TabOldPhotosClient::GetUrisByOldUris(std::vector<std::string>& uris)
65 {
66     std::unordered_map<std::string, std::string> resultMap;
67     bool cond = (uris.empty() || static_cast<std::int32_t>(uris.size()) > this->URI_MAX_SIZE);
68     CHECK_AND_RETURN_RET_LOG(!cond, resultMap, "the size is invalid, size = %{public}d",
69         static_cast<std::int32_t>(uris.size()));
70     std::vector<std::string> column;
71     column.push_back(TabOldPhotosColumn::OLD_PHOTOS_TABLE + "." + "file_id");
72     column.push_back(TabOldPhotosColumn::OLD_PHOTOS_TABLE + "." + "data");
73     column.push_back(TabOldPhotosColumn::OLD_PHOTOS_TABLE + "." + "old_file_id");
74     column.push_back(TabOldPhotosColumn::OLD_PHOTOS_TABLE + "." + "old_data");
75     column.push_back(PhotoColumn::PHOTOS_TABLE + "." + "display_name");
76     return this->GetResultSetFromTabOldPhotos(uris, column);
77 }
78 
GetResultSetFromTabOldPhotos(std::vector<std::string> & uris,std::vector<std::string> & columns)79 std::unordered_map<std::string, std::string> TabOldPhotosClient::GetResultSetFromTabOldPhotos(
80     std::vector<std::string>& uris, std::vector<std::string> &columns)
81 {
82     std::unordered_map<std::string, std::string> resultMap;
83     sptr<IRemoteObject> token = this->mediaLibraryManager_.InitToken();
84     std::shared_ptr<DataShare::DataShareHelper> dataShareHelper =
85         DataShare::DataShareHelper::Creator(token, MEDIALIBRARY_DATA_URI);
86     CHECK_AND_RETURN_RET_LOG(dataShareHelper != nullptr, resultMap, "dataShareHelper is nullptr");
87     GetUrisByOldUrisInnerReqBody reqBody;
88     GetUrisByOldUrisInnerRespBody respBody;
89     reqBody.uris = uris;
90     reqBody.columns = columns;
91     uint32_t businessCode = static_cast<uint32_t>(MediaLibraryBusinessCode::INNER_GET_URIS_BY_OLD_URIS);
92     MEDIA_INFO_LOG("before IPC::UserDefineIPCClient().Call, INNER_GET_URIS_BY_OLD_URIS");
93     int32_t result =
94         IPC::UserInnerIPCClient().SetDataShareHelper(dataShareHelper).Call(businessCode, reqBody, respBody);
95     CHECK_AND_RETURN_RET_LOG(result == E_OK, resultMap, "GetResultSetFromTabOldPhotos IPC Call Failed");
96     auto fileIds_size = respBody.fileIds.size();
97     auto datas_size = respBody.datas.size();
98     auto displayNames_size = respBody.displayNames.size();
99     auto oldFileIds_size = respBody.oldFileIds.size();
100     auto oldDatas_size = respBody.oldDatas.size();
101     bool isValid = true;
102     isValid &= fileIds_size == datas_size;
103     isValid &= datas_size == displayNames_size;
104     isValid &= displayNames_size == oldFileIds_size;
105     isValid &= oldFileIds_size == oldDatas_size;
106     CHECK_AND_RETURN_RET_LOG(isValid, resultMap, "GetResultSetFromTabOldPhotos Failed");
107     std::vector<TabOldPhotosClient::TabOldPhotosClientObj> dataMapping;
108     for (size_t i = 0; i < respBody.fileIds.size(); i++) {
109         TabOldPhotosClient::TabOldPhotosClientObj obj;
110         obj.fileId = respBody.fileIds[i];
111         obj.data = respBody.datas[i];
112         obj.displayName = respBody.displayNames[i];
113         obj.oldFileId = respBody.oldFileIds[i];
114         obj.oldData = respBody.oldDatas[i];
115         dataMapping.emplace_back(obj);
116     }
117     std::vector<TabOldPhotosClient::RequestUriObj> uriList = this->Parse(uris);
118     return this->Parse(dataMapping, uriList);
119 }
120 
BuildPredicates(const std::vector<std::string> & queryTabOldPhotosUris,DataShare::DataSharePredicates & predicates)121 int TabOldPhotosClient::BuildPredicates(const std::vector<std::string> &queryTabOldPhotosUris,
122     DataShare::DataSharePredicates &predicates)
123 {
124     const std::string GALLERY_URI_PREFIX = "//media";
125     const std::string GALLERY_PATH = "/storage/emulated";
126 
127     vector<string> clauses;
128         clauses.push_back(PhotoColumn::PHOTOS_TABLE + "." + MediaColumn::MEDIA_ID + " = " +
129         TabOldPhotosColumn::OLD_PHOTOS_TABLE + "." + TabOldPhotosColumn::MEDIA_ID);
130     predicates.InnerJoin(PhotoColumn::PHOTOS_TABLE)->On(clauses);
131 
132     int conditionCount = 0;
133     for (const auto &uri : queryTabOldPhotosUris) {
134         if (uri.find(GALLERY_URI_PREFIX) != std::string::npos) {
135             size_t lastSlashPos = uri.rfind('/');
136             if (lastSlashPos != std::string::npos && lastSlashPos + 1 < uri.length()) {
137                 std::string idStr = uri.substr(lastSlashPos + 1);
138                 predicates.Or()->EqualTo(TabOldPhotosColumn::MEDIA_OLD_ID, idStr);
139                 conditionCount += 1;
140             }
141         } else if (uri.find(GALLERY_PATH) != std::string::npos) {
142             predicates.Or()->EqualTo(TabOldPhotosColumn::MEDIA_OLD_FILE_PATH, uri);
143             conditionCount += 1;
144         } else if (!uri.empty() && std::all_of(uri.begin(), uri.end(), ::isdigit)) {
145             predicates.Or()->EqualTo(TabOldPhotosColumn::MEDIA_OLD_ID, uri);
146             conditionCount += 1;
147         }
148     }
149     CHECK_AND_RETURN_RET_LOG(conditionCount != 0, E_FAIL, "Zero uri condition");
150     return E_OK;
151 }
152 
Parse(std::shared_ptr<DataShare::DataShareResultSet> & resultSet)153 std::vector<TabOldPhotosClient::TabOldPhotosClientObj> TabOldPhotosClient::Parse(
154     std::shared_ptr<DataShare::DataShareResultSet> &resultSet)
155 {
156     std::vector<TabOldPhotosClient::TabOldPhotosClientObj> result;
157     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, result, "resultSet is null");
158     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
159         TabOldPhotosClient::TabOldPhotosClientObj obj;
160         obj.fileId = GetInt32Val(this->COLUMN_FILE_ID, resultSet);
161         obj.data = GetStringVal(this->COLUMN_DATA, resultSet);
162         obj.displayName = GetStringVal(this->COLUMN_DISPLAY_NAME, resultSet);
163         obj.oldFileId = GetInt32Val(this->COLUMN_OLD_FILE_ID, resultSet);
164         obj.oldData = GetStringVal(this->COLUMN_OLD_DATA, resultSet);
165         result.emplace_back(obj);
166     }
167     return result;
168 }
169 
StoiBoundCheck(std::string toCheck)170 static bool StoiBoundCheck(std::string toCheck)
171 {
172     const std::string intMax = std::to_string(std::numeric_limits<int>::max());
173 
174     return toCheck.length() < intMax.length();
175 }
176 
Parse(std::vector<std::string> & queryTabOldPhotosUris)177 std::vector<TabOldPhotosClient::RequestUriObj> TabOldPhotosClient::Parse(
178     std::vector<std::string> &queryTabOldPhotosUris)
179 {
180     const std::string GALLERY_URI_PREFIX = "//media";
181     const std::string GALLERY_PATH = "/storage/emulated";
182     std::vector<TabOldPhotosClient::RequestUriObj> result;
183     for (const auto &uri : queryTabOldPhotosUris) {
184         TabOldPhotosClient::RequestUriObj obj;
185         obj.type = URI_TYPE_DEFAULT;
186         obj.requestUri = uri;
187 
188         if (uri.find(GALLERY_URI_PREFIX) != std::string::npos) {
189             size_t lastSlashPos = uri.rfind('/');
190             if (lastSlashPos == std::string::npos || lastSlashPos + 1 >= uri.length()) {
191                 MEDIA_ERR_LOG("Error locating media id in media uri: %{public}s", uri.c_str());
192                 continue;
193             }
194             std::string idStr = uri.substr(lastSlashPos + 1);
195             if (!(!idStr.empty() && std::all_of(idStr.begin(), idStr.end(), ::isdigit)) || !StoiBoundCheck(idStr)) {
196                 MEDIA_ERR_LOG("Media id is invalid in uri: %{public}s", uri.c_str());
197                 continue;
198             }
199             obj.type = URI_TYPE_ID_LINK;
200             obj.oldFileId = std::stoi(idStr);
201         } else if (uri.find(GALLERY_PATH) != std::string::npos) {
202             obj.type = URI_TYPE_PATH;
203             obj.oldData = uri;
204         } else if (!uri.empty() && std::all_of(uri.begin(), uri.end(), ::isdigit) && StoiBoundCheck(uri)) {
205             int oldFileId = std::stoi(uri);
206             obj.type = URI_TYPE_ID;
207             obj.oldFileId = oldFileId;
208         }
209         if (obj.type == URI_TYPE_DEFAULT) {
210             continue;
211         }
212         result.emplace_back(obj);
213     }
214     return result;
215 }
216 
BuildRequestUri(const TabOldPhotosClient::TabOldPhotosClientObj & dataObj)217 std::string TabOldPhotosClient::BuildRequestUri(const TabOldPhotosClient::TabOldPhotosClientObj &dataObj)
218 {
219     std::string filePath = dataObj.data;
220     std::string displayName = dataObj.displayName;
221     int32_t fileId = dataObj.fileId;
222     std::string baseUri = "file://media";
223     size_t lastSlashInData = filePath.rfind('/');
224     std::string fileNameInData =
225         (lastSlashInData != std::string::npos) ? filePath.substr(lastSlashInData + 1) : filePath;
226     size_t dotPos = fileNameInData.rfind('.');
227     if (dotPos != std::string::npos) {
228         fileNameInData = fileNameInData.substr(0, dotPos);
229     }
230     return baseUri + "/Photo/" + std::to_string(fileId) + "/" + fileNameInData + "/" + displayName;
231 }
232 
Build(const TabOldPhotosClient::RequestUriObj & requestUriObj,const std::vector<TabOldPhotosClient::TabOldPhotosClientObj> & dataMapping)233 std::pair<std::string, std::string> TabOldPhotosClient::Build(const TabOldPhotosClient::RequestUriObj &requestUriObj,
234     const std::vector<TabOldPhotosClient::TabOldPhotosClientObj> &dataMapping)
235 {
236     if (requestUriObj.type == URI_TYPE_ID_LINK || requestUriObj.type == URI_TYPE_ID) {
237         int32_t oldFileId = requestUriObj.oldFileId;
238         auto it = std::find_if(dataMapping.begin(),
239             dataMapping.end(),
240             [oldFileId](const TabOldPhotosClient::TabOldPhotosClientObj &obj) {return obj.oldFileId == oldFileId;});
241         CHECK_AND_RETURN_RET(it == dataMapping.end(),
242             std::make_pair(requestUriObj.requestUri, this->BuildRequestUri(*it)));
243     }
244     if (requestUriObj.type == URI_TYPE_PATH) {
245         std::string oldData = requestUriObj.oldData;
246         auto it = std::find_if(dataMapping.begin(),
247             dataMapping.end(),
248             [oldData](const TabOldPhotosClient::TabOldPhotosClientObj &obj) {return obj.oldData == oldData;});
249         CHECK_AND_RETURN_RET(it == dataMapping.end(),
250             std::make_pair(requestUriObj.requestUri, this->BuildRequestUri(*it)));
251     }
252     return std::make_pair(requestUriObj.requestUri, "");
253 }
254 
Parse(const std::vector<TabOldPhotosClient::TabOldPhotosClientObj> & dataMapping,std::vector<RequestUriObj> & uriList)255 std::unordered_map<std::string, std::string> TabOldPhotosClient::Parse(
256     const std::vector<TabOldPhotosClient::TabOldPhotosClientObj> &dataMapping, std::vector<RequestUriObj> &uriList)
257 {
258     std::unordered_map<std::string, std::string> resultMap;
259     for (const auto &requestUriObj : uriList) {
260         std::pair<std::string, std::string> pair = this->Build(requestUriObj, dataMapping);
261         resultMap[pair.first] = pair.second;
262     }
263     return resultMap;
264 }
265 
GetResultMap(std::shared_ptr<DataShareResultSet> & resultSet,std::vector<std::string> & queryTabOldPhotosUris)266 std::unordered_map<std::string, std::string> TabOldPhotosClient::GetResultMap(
267     std::shared_ptr<DataShareResultSet> &resultSet, std::vector<std::string> &queryTabOldPhotosUris)
268 {
269     std::unordered_map<std::string, std::string> resultMap;
270     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, resultMap, "resultSet is null");
271     std::vector<TabOldPhotosClient::TabOldPhotosClientObj> dataMapping = this->Parse(resultSet);
272     std::vector<TabOldPhotosClient::RequestUriObj> uriList = this->Parse(queryTabOldPhotosUris);
273     return this->Parse(dataMapping, uriList);
274 }
275 } // namespace OHOS::Media
276