1 /*
2 * Copyright (C) 2022-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
16 #include "userfile_client.h"
17
18 #include "ability.h"
19
20 #include "media_asset_rdbstore.h"
21 #include "medialibrary_errno.h"
22 #include "medialibrary_napi_log.h"
23 #include "medialibrary_helper_container.h"
24 #include "media_file_utils.h"
25 #include "safe_map.h"
26
27 using namespace std;
28 using namespace OHOS::DataShare;
29 using namespace OHOS::AppExecFwk;
30 namespace OHOS {
31 namespace Media {
32
33 int32_t UserFileClient::userId_ = -1;
34 std::string MULTI_USER_URI_FLAG = "user=";
35 std::string USER_STR = "user";
36 SafeMap<int32_t, std::shared_ptr<DataShare::DataShareHelper>> UserFileClient::dataShareHelperMap_ = {};
37
GetMediaLibraryDataUri(const int32_t userId)38 static std::string GetMediaLibraryDataUri(const int32_t userId)
39 {
40 std::string mediaLibraryDataUri = MEDIALIBRARY_DATA_URI;
41 if (userId != -1) {
42 mediaLibraryDataUri = mediaLibraryDataUri + "?" + MULTI_USER_URI_FLAG + to_string(userId);
43 }
44 return mediaLibraryDataUri;
45 }
46
MultiUserUriRecognition(Uri & uri,const int32_t userId)47 static Uri MultiUserUriRecognition(Uri &uri, const int32_t userId)
48 {
49 if (userId == -1) {
50 return uri;
51 }
52 std::string uriString = uri.ToString();
53 MediaLibraryNapiUtils::UriAppendKeyValue(uriString, USER_STR, to_string(userId));
54 return Uri(uriString);
55 }
56
DataShareCreator(const sptr<IRemoteObject> & token,shared_ptr<DataShare::DataShareHelper> & dataShareHelper,const int32_t userId)57 static void DataShareCreator(const sptr<IRemoteObject> &token,
58 shared_ptr<DataShare::DataShareHelper> &dataShareHelper, const int32_t userId)
59 {
60 dataShareHelper = DataShare::DataShareHelper::Creator(token, GetMediaLibraryDataUri(userId));
61 if (dataShareHelper == nullptr) {
62 NAPI_ERR_LOG("dataShareHelper Creator failed");
63 dataShareHelper = DataShare::DataShareHelper::Creator(token, GetMediaLibraryDataUri(userId));
64 }
65 }
66
GetDataShareHelper(napi_env env,napi_callback_info info,const int32_t userId)67 shared_ptr<DataShare::DataShareHelper> UserFileClient::GetDataShareHelper(napi_env env,
68 napi_callback_info info, const int32_t userId)
69 {
70 size_t argc = ARGS_ONE;
71 napi_value argv[ARGS_ONE] = {0};
72 napi_value thisVar = nullptr;
73 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
74
75 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = nullptr;
76 bool isStageMode = false;
77 napi_status status = OHOS::AbilityRuntime::IsStageContext(env, argv[0], isStageMode);
78 if (status != napi_ok || !isStageMode) {
79 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
80 if (ability == nullptr) {
81 NAPI_ERR_LOG("Failed to get native ability instance");
82 return nullptr;
83 }
84 auto context = ability->GetContext();
85 if (context == nullptr) {
86 NAPI_ERR_LOG("Failed to get native context instance");
87 return nullptr;
88 }
89 DataShareCreator(context->GetToken(), dataShareHelper, userId);
90 } else {
91 auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
92 if (context == nullptr) {
93 NAPI_ERR_LOG("Failed to get native stage context instance");
94 return nullptr;
95 }
96 DataShareCreator(context->GetToken(), dataShareHelper, userId);
97 }
98 MediaLibraryHelperContainer::GetInstance()->SetDataShareHelper(dataShareHelper);
99 return dataShareHelper;
100 }
101
CheckIsStage(napi_env env,napi_callback_info info,bool & result)102 napi_status UserFileClient::CheckIsStage(napi_env env, napi_callback_info info, bool &result)
103 {
104 size_t argc = ARGS_ONE;
105 napi_value argv[ARGS_ONE] = {0};
106 napi_value thisVar = nullptr;
107 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
108 if (status != napi_ok) {
109 NAPI_ERR_LOG("Failed to get cb info, status=%{public}d", (int) status);
110 return status;
111 }
112
113 result = false;
114 status = OHOS::AbilityRuntime::IsStageContext(env, argv[0], result);
115 if (status != napi_ok) {
116 NAPI_ERR_LOG("Failed to get stage mode, status=%{public}d", (int) status);
117 return status;
118 }
119 return napi_ok;
120 }
121
ParseTokenInStageMode(napi_env env,napi_callback_info info)122 sptr<IRemoteObject> UserFileClient::ParseTokenInStageMode(napi_env env, napi_callback_info info)
123 {
124 size_t argc = ARGS_ONE;
125 napi_value argv[ARGS_ONE] = {0};
126 napi_value thisVar = nullptr;
127 if (napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok) {
128 NAPI_ERR_LOG("Failed to get cb info");
129 return nullptr;
130 }
131
132 auto context = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
133 if (context == nullptr) {
134 NAPI_ERR_LOG("Failed to get native stage context instance");
135 return nullptr;
136 }
137 return context->GetToken();
138 }
139
ParseTokenInAbility(napi_env env,napi_callback_info info)140 sptr<IRemoteObject> UserFileClient::ParseTokenInAbility(napi_env env, napi_callback_info info)
141 {
142 size_t argc = ARGS_ONE;
143 napi_value argv[ARGS_ONE] = {0};
144 napi_value thisVar = nullptr;
145 if (napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok) {
146 NAPI_ERR_LOG("Failed to get cb info");
147 return nullptr;
148 }
149
150 auto ability = OHOS::AbilityRuntime::GetCurrentAbility(env);
151 if (ability == nullptr) {
152 NAPI_ERR_LOG("Failed to get native ability instance");
153 return nullptr;
154 }
155 auto context = ability->GetContext();
156 if (context == nullptr) {
157 NAPI_ERR_LOG("Failed to get native context instance");
158 return nullptr;
159 }
160 return context->GetToken();
161 }
162
IsValid(const int32_t userId)163 bool UserFileClient::IsValid(const int32_t userId)
164 {
165 std::shared_ptr<DataShare::DataShareHelper> helper;
166 if (dataShareHelperMap_.Find(userId, helper)) {
167 return helper != nullptr;
168 }
169 return false;
170 }
171
GetDataShareHelperByUser(const int32_t userId)172 std::shared_ptr<DataShare::DataShareHelper> UserFileClient::GetDataShareHelperByUser(const int32_t userId)
173 {
174 return dataShareHelperMap_.ReadVal(userId);
175 }
176
Init(const sptr<IRemoteObject> & token,bool isSetHelper,const int32_t userId)177 void UserFileClient::Init(const sptr<IRemoteObject> &token, bool isSetHelper, const int32_t userId)
178 {
179 if (GetDataShareHelperByUser(userId) == nullptr) {
180 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper =
181 DataShare::DataShareHelper::Creator(token, GetMediaLibraryDataUri(userId));
182 if (isSetHelper) {
183 MediaLibraryHelperContainer::GetInstance()->SetDataShareHelper(dataShareHelper);
184 }
185 if (dataShareHelper != nullptr) {
186 if (!IsValid(userId)) {
187 dataShareHelperMap_.EnsureInsert(userId, dataShareHelper);
188 } else {
189 NAPI_ERR_LOG("dataShareHelperMap has userId and value");
190 }
191 } else {
192 NAPI_ERR_LOG("Failed to getDataShareHelper, dataShareHelper is null");
193 }
194 }
195 }
196
Init(napi_env env,napi_callback_info info,const int32_t userId)197 void UserFileClient::Init(napi_env env, napi_callback_info info, const int32_t userId)
198 {
199 if (GetDataShareHelperByUser(userId) == nullptr) {
200 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper = GetDataShareHelper(env, info, userId);
201 if (dataShareHelper != nullptr) {
202 if (!IsValid(userId)) {
203 dataShareHelperMap_.EnsureInsert(userId, dataShareHelper);
204 } else {
205 NAPI_ERR_LOG("dataShareHelperMap has userId and value");
206 }
207 } else {
208 NAPI_ERR_LOG("Failed to getDataShareHelper, dataShareHelper is null");
209 }
210 }
211 }
212
Query(Uri & uri,const DataSharePredicates & predicates,std::vector<std::string> & columns,int & errCode,const int32_t userId)213 shared_ptr<DataShareResultSet> UserFileClient::Query(Uri &uri, const DataSharePredicates &predicates,
214 std::vector<std::string> &columns, int &errCode, const int32_t userId)
215 {
216 if (!IsValid(userId)) {
217 NAPI_ERR_LOG("Query fail, helper null, userId is %{public}d", userId);
218 return nullptr;
219 }
220 uri = MultiUserUriRecognition(uri, userId);
221
222 shared_ptr<DataShareResultSet> resultSet = nullptr;
223 OperationObject object = OperationObject::UNKNOWN_OBJECT;
224 if (MediaAssetRdbStore::GetInstance()->IsQueryAccessibleViaSandBox(uri, object, predicates) &&
225 !uri.ToString().find(MULTI_USER_URI_FLAG)) {
226 resultSet = MediaAssetRdbStore::GetInstance()->Query(predicates, columns, object, errCode);
227 } else {
228 DatashareBusinessError businessError;
229 resultSet = GetDataShareHelperByUser(userId)->Query(uri, predicates, columns, &businessError);
230 errCode = businessError.GetCode();
231 }
232 return resultSet;
233 }
234
QueryRdb(Uri & uri,const DataShare::DataSharePredicates & predicates,std::vector<std::string> & columns)235 std::shared_ptr<NativeRdb::ResultSet> UserFileClient::QueryRdb(Uri &uri,
236 const DataShare::DataSharePredicates &predicates, std::vector<std::string> &columns)
237 {
238 shared_ptr<NativeRdb::ResultSet> resultSet = nullptr;
239 OperationObject object = OperationObject::UNKNOWN_OBJECT;
240 if (MediaAssetRdbStore::GetInstance()->IsSupportSharedAssetQuery(uri, object)) {
241 resultSet = MediaAssetRdbStore::GetInstance()->QueryRdb(predicates, columns, object);
242 }
243 return resultSet;
244 }
245
Insert(Uri & uri,const DataShareValuesBucket & value,const int32_t userId)246 int UserFileClient::Insert(Uri &uri, const DataShareValuesBucket &value, const int32_t userId)
247 {
248 if (!IsValid(userId)) {
249 NAPI_ERR_LOG("insert fail, helper null, userId is %{public}d", userId);
250 return E_FAIL;
251 }
252 int index = GetDataShareHelperByUser(userId)->Insert(uri, value);
253 return index;
254 }
255
InsertExt(Uri & uri,const DataShareValuesBucket & value,string & result,const int32_t userId)256 int UserFileClient::InsertExt(Uri &uri, const DataShareValuesBucket &value, string &result, const int32_t userId)
257 {
258 if (!IsValid(userId)) {
259 NAPI_ERR_LOG("insert fail, helper null, userId is %{public}d", userId);
260 return E_FAIL;
261 }
262 int index = GetDataShareHelperByUser(userId)->InsertExt(uri, value, result);
263 return index;
264 }
265
BatchInsert(Uri & uri,const std::vector<DataShare::DataShareValuesBucket> & values)266 int UserFileClient::BatchInsert(Uri &uri, const std::vector<DataShare::DataShareValuesBucket> &values)
267 {
268 if (!IsValid(GetUserId())) {
269 NAPI_ERR_LOG("Batch insert fail, helper null, userId is %{public}d", GetUserId());
270 return E_FAIL;
271 }
272 return GetDataShareHelperByUser(GetUserId())->BatchInsert(uri, values);
273 }
274
Delete(Uri & uri,const DataSharePredicates & predicates)275 int UserFileClient::Delete(Uri &uri, const DataSharePredicates &predicates)
276 {
277 if (!IsValid(GetUserId())) {
278 NAPI_ERR_LOG("delete fail, helper null, userId is %{public}d", GetUserId());
279 return E_FAIL;
280 }
281 return GetDataShareHelperByUser(GetUserId())->Delete(uri, predicates);
282 }
283
NotifyChange(const Uri & uri)284 void UserFileClient::NotifyChange(const Uri &uri)
285 {
286 if (!IsValid(GetUserId())) {
287 NAPI_ERR_LOG("notify change fail, helper null, userId is %{public}d", GetUserId());
288 return;
289 }
290 GetDataShareHelperByUser(GetUserId())->NotifyChange(uri);
291 }
292
RegisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)293 void UserFileClient::RegisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
294 {
295 if (!IsValid(GetUserId())) {
296 NAPI_ERR_LOG("register observer fail, helper null, userId is %{public}d", GetUserId());
297 return;
298 }
299 GetDataShareHelperByUser(GetUserId())->RegisterObserver(uri, dataObserver);
300 }
301
UnregisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)302 void UserFileClient::UnregisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
303 {
304 if (!IsValid(GetUserId())) {
305 NAPI_ERR_LOG("unregister observer fail, helper null, userId is %{public}d", GetUserId());
306 return;
307 }
308 GetDataShareHelperByUser(GetUserId())->UnregisterObserver(uri, dataObserver);
309 }
310
OpenFile(Uri & uri,const std::string & mode,const int32_t userId)311 int UserFileClient::OpenFile(Uri &uri, const std::string &mode, const int32_t userId)
312 {
313 if (!IsValid(userId)) {
314 NAPI_ERR_LOG("Open file fail, helper null, userId is %{public}d", userId);
315 return E_FAIL;
316 }
317 uri = MultiUserUriRecognition(uri, userId);
318 return GetDataShareHelperByUser(userId)->OpenFile(uri, mode);
319 }
320
Update(Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value,const int32_t userId)321 int UserFileClient::Update(Uri &uri, const DataSharePredicates &predicates,
322 const DataShareValuesBucket &value, const int32_t userId)
323 {
324 if (!IsValid(userId)) {
325 NAPI_ERR_LOG("update fail, helper null, userId is %{public}d", userId);
326 return E_FAIL;
327 }
328 return GetDataShareHelperByUser(userId)->Update(uri, predicates, value);
329 }
330
RegisterObserverExt(const Uri & uri,shared_ptr<DataShare::DataShareObserver> dataObserver,bool isDescendants)331 void UserFileClient::RegisterObserverExt(const Uri &uri,
332 shared_ptr<DataShare::DataShareObserver> dataObserver, bool isDescendants)
333 {
334 if (!IsValid(GetUserId())) {
335 NAPI_ERR_LOG("register observer fail, helper null, userId is %{public}d", GetUserId());
336 return;
337 }
338 GetDataShareHelperByUser(GetUserId())->RegisterObserverExt(uri, std::move(dataObserver), isDescendants);
339 }
340
UnregisterObserverExt(const Uri & uri,std::shared_ptr<DataShare::DataShareObserver> dataObserver)341 void UserFileClient::UnregisterObserverExt(const Uri &uri, std::shared_ptr<DataShare::DataShareObserver> dataObserver)
342 {
343 if (!IsValid(GetUserId())) {
344 NAPI_ERR_LOG("unregister observer fail, helper null, userId is %{public}d", GetUserId());
345 return;
346 }
347 GetDataShareHelperByUser(GetUserId())->UnregisterObserverExt(uri, std::move(dataObserver));
348 }
349
GetType(Uri & uri)350 std::string UserFileClient::GetType(Uri &uri)
351 {
352 if (!IsValid(GetUserId())) {
353 NAPI_ERR_LOG("get type fail, helper null, userId is %{public}d", GetUserId());
354 return "";
355 }
356 return GetDataShareHelperByUser(GetUserId())->GetType(uri);
357 }
358
Clear()359 void UserFileClient::Clear()
360 {
361 dataShareHelperMap_.Clear();
362 }
363
SetUserId(const int32_t userId)364 void UserFileClient::SetUserId(const int32_t userId)
365 {
366 userId_ = userId;
367 }
368
GetUserId()369 int32_t UserFileClient::GetUserId()
370 {
371 return userId_;
372 }
373 }
374 }
375