1 /*
2 * Copyright (C) 2022 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 "medialibrary_command.h"
17
18 #include "media_file_uri.h"
19 #include "media_file_utils.h"
20 #include "media_log.h"
21 #include "medialibrary_data_manager_utils.h"
22 #include "medialibrary_db_const.h"
23 #include "medialibrary_unistore_manager.h"
24 #include "medialibrary_errno.h"
25 #include "userfilemgr_uri.h"
26
27 using namespace std;
28 using namespace OHOS::NativeRdb;
29 using namespace OHOS::DataShare;
30
31 namespace OHOS {
32 namespace Media {
33
MediaLibraryCommand(const Uri & uri)34 MediaLibraryCommand::MediaLibraryCommand(const Uri &uri) : uri_(uri)
35 {
36 ParseOprnObjectFromUri();
37 ParseOprnTypeFromUri();
38 ParseQuerySetMapFromUri();
39 SetApiFromQuerySetMap();
40 ParseOprnObjectFromFileUri();
41 ParseTableName();
42 }
43
MediaLibraryCommand(const Uri & uri,const ValuesBucket & value)44 MediaLibraryCommand::MediaLibraryCommand(const Uri &uri, const ValuesBucket &value) : uri_(uri), insertValue_(value)
45 {
46 ParseOprnObjectFromUri();
47 ParseOprnTypeFromUri();
48 ParseQuerySetMapFromUri();
49 SetApiFromQuerySetMap();
50 ParseOprnObjectFromFileUri();
51 ParseTableName();
52 }
53
MediaLibraryCommand(const Uri & uri,const OperationType & oprnType)54 MediaLibraryCommand::MediaLibraryCommand(const Uri &uri, const OperationType &oprnType) : uri_(uri), oprnType_(oprnType)
55 {
56 ParseOprnObjectFromUri();
57 ParseQuerySetMapFromUri();
58 SetApiFromQuerySetMap();
59 ParseOprnObjectFromFileUri();
60 ParseTableName();
61 }
62
MediaLibraryCommand(const OperationObject & oprnObject,const OperationType & oprnType,MediaLibraryApi api)63 MediaLibraryCommand::MediaLibraryCommand(const OperationObject &oprnObject, const OperationType &oprnType,
64 MediaLibraryApi api) : oprnObject_(oprnObject), oprnType_(oprnType), api_(api)
65 {
66 ParseTableName();
67 }
68
MediaLibraryCommand(const OperationObject & oprnObject,const OperationType & oprnType,const ValuesBucket & value,MediaLibraryApi api)69 MediaLibraryCommand::MediaLibraryCommand(const OperationObject &oprnObject, const OperationType &oprnType,
70 const ValuesBucket &value, MediaLibraryApi api) :insertValue_(value), oprnObject_(oprnObject),
71 oprnType_(oprnType), api_(api)
72 {
73 ParseTableName();
74 }
75
MediaLibraryCommand(const OperationObject & oprnObject,const OperationType & oprnType,const string & networkId,MediaLibraryApi api)76 MediaLibraryCommand::MediaLibraryCommand(const OperationObject &oprnObject, const OperationType &oprnType,
77 const string &networkId, MediaLibraryApi api) : oprnObject_(oprnObject), oprnType_(oprnType),
78 oprnDevice_(networkId), api_(api)
79 {
80 ParseTableName();
81 }
82
~MediaLibraryCommand()83 MediaLibraryCommand::~MediaLibraryCommand() {}
84
85 // set functions
SetOprnObject(OperationObject object)86 void MediaLibraryCommand::SetOprnObject(OperationObject object)
87 {
88 oprnObject_ = object;
89 }
90
SetOprnAssetId(const std::string & oprnId)91 void MediaLibraryCommand::SetOprnAssetId(const std::string &oprnId)
92 {
93 oprnFileId_ = oprnId;
94 }
95
SetValueBucket(const NativeRdb::ValuesBucket & value)96 void MediaLibraryCommand::SetValueBucket(const NativeRdb::ValuesBucket &value)
97 {
98 insertValue_ = value;
99 }
100
SetTableName(const std::string & tableName)101 void MediaLibraryCommand::SetTableName(const std::string &tableName)
102 {
103 tableName_ = tableName;
104 }
105
SetBundleName(const std::string & bundleName)106 void MediaLibraryCommand::SetBundleName(const std::string &bundleName)
107 {
108 bundleName_ = bundleName;
109 }
110
SetDeviceName(const std::string & deviceName)111 void MediaLibraryCommand::SetDeviceName(const std::string &deviceName)
112 {
113 deviceName_ = deviceName;
114 }
115
SetResult(const std::string & result)116 void MediaLibraryCommand::SetResult(const std::string &result)
117 {
118 result_ = result;
119 }
120
IsDataSharePredNull() const121 bool MediaLibraryCommand::IsDataSharePredNull() const
122 {
123 return datasharePred_ == nullptr;
124 }
125
126 // get functions
GetOprnObject() const127 OperationObject MediaLibraryCommand::GetOprnObject() const
128 {
129 return oprnObject_;
130 }
131
GetOprnType() const132 OperationType MediaLibraryCommand::GetOprnType() const
133 {
134 return oprnType_;
135 }
136
GetValueBucket()137 ValuesBucket &MediaLibraryCommand::GetValueBucket()
138 {
139 return insertValue_;
140 }
141
GetAbsRdbPredicates()142 AbsRdbPredicates *MediaLibraryCommand::GetAbsRdbPredicates()
143 {
144 if (absRdbPredicates_ == nullptr) {
145 InitAbsRdbPredicates();
146 }
147 return absRdbPredicates_.get();
148 }
149
GetTableName()150 const string &MediaLibraryCommand::GetTableName()
151 {
152 if (tableName_.empty()) {
153 ParseTableName();
154 }
155
156 return tableName_;
157 }
158
GetOprnFileId()159 const string &MediaLibraryCommand::GetOprnFileId()
160 {
161 if (oprnFileId_.empty()) {
162 ParseFileId();
163 }
164
165 return oprnFileId_;
166 }
167
GetOprnDevice()168 const string &MediaLibraryCommand::GetOprnDevice()
169 {
170 if (oprnDevice_.empty()) {
171 oprnDevice_ = MediaFileUtils::GetNetworkIdFromUri(uri_.ToString());
172 }
173 return oprnDevice_;
174 }
175
GetUri() const176 const Uri &MediaLibraryCommand::GetUri() const
177 {
178 return uri_;
179 }
180
GetBundleName()181 const string &MediaLibraryCommand::GetBundleName()
182 {
183 return bundleName_;
184 }
185
GetDeviceName()186 const string &MediaLibraryCommand::GetDeviceName()
187 {
188 return deviceName_;
189 }
190
GetResult()191 const string &MediaLibraryCommand::GetResult()
192 {
193 return result_;
194 }
195
GetUriStringWithoutSegment() const196 string MediaLibraryCommand::GetUriStringWithoutSegment() const
197 {
198 string uriString = uri_.ToString();
199 size_t questionMaskPoint = uriString.rfind('?');
200 size_t hashKeyPoint = uriString.rfind('#');
201 if (questionMaskPoint != string::npos) {
202 return uriString.substr(0, questionMaskPoint);
203 }
204 if (hashKeyPoint != string::npos) {
205 return uriString.substr(0, hashKeyPoint);
206 }
207 return uriString;
208 }
209
GetApi()210 MediaLibraryApi MediaLibraryCommand::GetApi()
211 {
212 return api_;
213 }
214
GetQuerySetParam(const std::string & key)215 string MediaLibraryCommand::GetQuerySetParam(const std::string &key)
216 {
217 if (key.empty() || querySetMap_.find(key) == querySetMap_.end()) {
218 return "";
219 }
220 return querySetMap_[key];
221 }
222
ParseOprnObjectFromUri()223 void MediaLibraryCommand::ParseOprnObjectFromUri()
224 {
225 const string opObject = MediaFileUri::GetPathFirstDentry(uri_);
226 if (OPRN_OBJ_MAP.find(opObject) != OPRN_OBJ_MAP.end()) {
227 oprnObject_ = OPRN_OBJ_MAP.at(opObject);
228 }
229 MEDIA_DEBUG_LOG("Command operation object is %{public}d", oprnObject_);
230 }
231
ParseOprnTypeFromUri()232 void MediaLibraryCommand::ParseOprnTypeFromUri()
233 {
234 const string opType = MediaFileUri::GetPathSecondDentry(uri_);
235 if (OPRN_TYPE_MAP.find(opType) != OPRN_TYPE_MAP.end()) {
236 oprnType_ = OPRN_TYPE_MAP.at(opType);
237 } else {
238 oprnType_ = OperationType::QUERY;
239 }
240 MEDIA_DEBUG_LOG("Command operation type is %{public}d", oprnType_);
241 }
242
GetDistTable(const string & table,const string & networkId)243 static string GetDistTable(const string &table, const string &networkId)
244 {
245 string ret = MEDIALIBRARY_TABLE;
246 auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
247 if (rdbStore == nullptr) {
248 return ret;
249 }
250
251 int errCode = E_ERR;
252 if (table == PhotoColumn::PHOTOS_TABLE || table == AudioColumn::AUDIOS_TABLE) {
253 ret = rdbStore->ObtainDistributedTableName(networkId, table, errCode);
254 } else {
255 ret = rdbStore->ObtainDistributedTableName(networkId, MEDIALIBRARY_TABLE, errCode);
256 }
257 return ret;
258 }
259
ParseTableName()260 void MediaLibraryCommand::ParseTableName()
261 {
262 if (TABLE_NAME_MAP.find(oprnObject_) != TABLE_NAME_MAP.end()) {
263 auto cmdObj = TABLE_NAME_MAP.at(oprnObject_);
264 if (cmdObj.find(oprnType_) != cmdObj.end()) {
265 tableName_ = cmdObj.at(oprnType_);
266 } else if (cmdObj.find(OperationType::UNKNOWN_TYPE) != cmdObj.end()) {
267 tableName_ = cmdObj.at(OperationType::UNKNOWN_TYPE);
268 } else {
269 tableName_ = MEDIALIBRARY_TABLE;
270 }
271 } else {
272 tableName_ = MEDIALIBRARY_TABLE;
273 }
274 // distributed tablename, smartalbum and smartalbumMap can not distributed
275 if ((oprnObject_ == OperationObject::SMART_ALBUM) || (oprnObject_ == OperationObject::SMART_ALBUM_MAP)) {
276 MEDIA_DEBUG_LOG("smart table name is %{public}s", tableName_.c_str());
277 return;
278 }
279 // distributed tablename
280 auto networkId = GetOprnDevice();
281 if (networkId.empty()) {
282 return;
283 }
284 tableName_ = GetDistTable(tableName_, networkId);
285 MEDIA_INFO_LOG("Table name is %{public}s", tableName_.c_str());
286 }
287
InitAbsRdbPredicates()288 void MediaLibraryCommand::InitAbsRdbPredicates()
289 {
290 if (tableName_.empty()) {
291 ParseTableName();
292 }
293 absRdbPredicates_ = make_unique<AbsRdbPredicates>(tableName_);
294 }
295
ParseFileId()296 void MediaLibraryCommand::ParseFileId()
297 {
298 int32_t fileIdInValue = -1;
299 ValueObject valueObject;
300 if (insertValue_.GetObject(MEDIA_DATA_DB_ID, valueObject)) {
301 valueObject.GetInt(fileIdInValue);
302 }
303 if (fileIdInValue != -1) {
304 oprnFileId_ = to_string(fileIdInValue);
305 return;
306 }
307 string uriInValue;
308 if (insertValue_.GetObject(MEDIA_DATA_DB_URI, valueObject)) {
309 valueObject.GetString(uriInValue);
310 }
311 if (uriInValue.empty()) {
312 uriInValue = GetUriStringWithoutSegment();
313 }
314
315 string idFromUri = MediaFileUtils::GetIdFromUri(uriInValue);
316 if (!MediaLibraryDataManagerUtils::IsNumber(idFromUri)) {
317 return;
318 }
319 oprnFileId_ = idFromUri;
320 }
321
ParseQuerySetMapFromUri()322 void MediaLibraryCommand::ParseQuerySetMapFromUri()
323 {
324 // uri format: datashare:///media/photo_operation/create_asset?op1=xxx&op2=yyy&api_version=10#abc
325 // QuerySetMap: {"op1": "xxx", "op2": "yyy", "api_version": "10"}
326 string uriStr = uri_.ToString();
327 size_t cutPoint = uriStr.find('#');
328 if (cutPoint != string::npos) {
329 uriStr = uriStr.substr(0, cutPoint);
330 }
331 MediaFileUri mediaUri(uriStr);
332 querySetMap_ = mediaUri.GetQueryKeys();
333 }
334
SetApiFromQuerySetMap()335 void MediaLibraryCommand::SetApiFromQuerySetMap()
336 {
337 if (querySetMap_.find(URI_PARAM_API_VERSION) == querySetMap_.end()) {
338 api_ = MediaLibraryApi::API_OLD;
339 } else {
340 string apiString = querySetMap_[URI_PARAM_API_VERSION];
341 if (!MediaLibraryDataManagerUtils::IsNumber(apiString)) {
342 api_ = MediaLibraryApi::API_OLD;
343 return;
344 }
345 int32_t apiNum = stoi(apiString);
346 if (apiNum <= static_cast<int32_t>(MediaLibraryApi::API_START) ||
347 apiNum >= static_cast<int32_t>(MediaLibraryApi::API_END)) {
348 MEDIA_ERR_LOG("this api num is wrong: %{public}d", apiNum);
349 api_ = MediaLibraryApi::API_OLD;
350 } else {
351 api_ = static_cast<MediaLibraryApi>(apiNum);
352 }
353 }
354 }
355
ParseOprnObjectFromFileUri()356 void MediaLibraryCommand::ParseOprnObjectFromFileUri()
357 {
358 if (oprnObject_ != OperationObject::UNKNOWN_OBJECT) {
359 return;
360 }
361
362 string uri = uri_.ToString();
363 // parse cache file uri
364 if (MediaFileUtils::StartsWith(uri, PhotoColumn::PHOTO_CACHE_URI_PREFIX)) {
365 oprnObject_ = OperationObject::PAH_PHOTO;
366 return;
367 }
368
369 for (const auto &item : OPRN_MAP) {
370 if (MediaFileUtils::StartsWith(uri, item.first)) {
371 oprnObject_ = item.second;
372 break;
373 }
374 }
375 }
376
SetDataSharePred(const DataSharePredicates & pred)377 void MediaLibraryCommand::SetDataSharePred(const DataSharePredicates &pred)
378 {
379 datasharePred_ = make_unique<const DataSharePredicates>(pred);
380 }
381
382 // Caller is responsible for calling SetDataSharePred() firstly, before calling GetDataSharePred()
GetDataSharePred() const383 const DataSharePredicates &MediaLibraryCommand::GetDataSharePred() const
384 {
385 return *datasharePred_;
386 }
387 } // namespace Media
388 } // namespace OHOS
389