• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param)
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