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