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 "js_datashare_ext_ability.h"
17
18 #include "ability_info.h"
19 #include "dataobs_mgr_client.h"
20 #include "datashare_stub_impl.h"
21 #include "datashare_log.h"
22 #include "js_datashare_ext_ability_context.h"
23 #include "js_runtime.h"
24 #include "js_runtime_utils.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27 #include "napi_common_util.h"
28 #include "napi_common_want.h"
29 #include "napi_remote_object.h"
30
31 #include "napi_datashare_values_bucket.h"
32 #include "datashare_predicates_proxy.h"
33
34 namespace OHOS {
35 namespace DataShare {
36 using namespace AbilityRuntime;
37 namespace {
38 constexpr size_t ARGC_ONE = 1;
39 constexpr size_t ARGC_TWO = 2;
40 constexpr size_t ARGC_THREE = 3;
41 constexpr int INVALID_VALUE = -1;
42 const std::string ASYNC_CALLBACK_NAME = "AsyncCallback";
43 }
44
45 bool MakeNapiColumn(napi_env env, napi_value &napiColumns, const std::vector<std::string> &columns);
46
47 using namespace OHOS::AppExecFwk;
48 using DataObsMgrClient = OHOS::AAFwk::DataObsMgrClient;
49
Create(const std::unique_ptr<Runtime> & runtime)50 JsDataShareExtAbility* JsDataShareExtAbility::Create(const std::unique_ptr<Runtime>& runtime)
51 {
52 return new JsDataShareExtAbility(static_cast<JsRuntime&>(*runtime));
53 }
54
JsDataShareExtAbility(JsRuntime & jsRuntime)55 JsDataShareExtAbility::JsDataShareExtAbility(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
56
~JsDataShareExtAbility()57 JsDataShareExtAbility::~JsDataShareExtAbility()
58 {
59 LOG_DEBUG("Js datashare extension destructor.");
60 jsRuntime_.FreeNativeReference(std::move(jsObj_));
61 }
62
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)63 void JsDataShareExtAbility::Init(const std::shared_ptr<AbilityLocalRecord> &record,
64 const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
65 const sptr<IRemoteObject> &token)
66 {
67 DataShareExtAbility::Init(record, application, handler, token);
68 std::string srcPath = "";
69 GetSrcPath(srcPath);
70 if (srcPath.empty()) {
71 LOG_ERROR("Failed to get srcPath");
72 return;
73 }
74
75 std::string moduleName(Extension::abilityInfo_->moduleName);
76 moduleName.append("::").append(abilityInfo_->name);
77 LOG_INFO("module:%{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str());
78 HandleScope handleScope(jsRuntime_);
79 auto& engine = jsRuntime_.GetNativeEngine();
80
81 jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
82 abilityInfo_->compileMode == CompileMode::ES_MODULE);
83 if (jsObj_ == nullptr) {
84 LOG_ERROR("Failed to get jsObj_");
85 return;
86 }
87 LOG_INFO("ConvertNativeValueTo.");
88 NativeObject* obj = ConvertNativeValueTo<NativeObject>(jsObj_->Get());
89 if (obj == nullptr) {
90 LOG_ERROR("Failed to get JsDataShareExtAbility object");
91 return;
92 }
93
94 auto context = GetContext();
95 if (context == nullptr) {
96 LOG_ERROR("Failed to get context");
97 return;
98 }
99 LOG_INFO("CreateJsDataShareExtAbilityContext.");
100 NativeValue* contextObj = CreateJsDataShareExtAbilityContext(engine, context);
101 auto contextRef = jsRuntime_.LoadSystemModule("application.DataShareExtensionAbilityContext",
102 &contextObj, ARGC_ONE);
103 contextObj = contextRef->Get();
104 LOG_INFO("Bind.");
105 context->Bind(jsRuntime_, contextRef.release());
106 LOG_INFO("SetProperty.");
107 obj->SetProperty("context", contextObj);
108
109 auto nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
110 if (nativeObj == nullptr) {
111 LOG_ERROR("Failed to get datashare extension ability native object");
112 return;
113 }
114
115 LOG_INFO("Set datashare extension ability context pointer is nullptr: %{public}d", context.get() == nullptr);
116
117 nativeObj->SetNativePointer(new std::weak_ptr<AbilityRuntime::Context>(context),
118 [](NativeEngine*, void* data, void*) {
119 LOG_INFO("Finalizer for weak_ptr datashare extension ability context is called");
120 delete static_cast<std::weak_ptr<AbilityRuntime::Context>*>(data);
121 }, nullptr);
122 }
123
OnStart(const AAFwk::Want & want)124 void JsDataShareExtAbility::OnStart(const AAFwk::Want &want)
125 {
126 Extension::OnStart(want);
127 HandleScope handleScope(jsRuntime_);
128 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
129 napi_handle_scope scope = nullptr;
130 napi_open_handle_scope(env, &scope);
131 if (scope == nullptr) {
132 return;
133 }
134 napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want);
135 NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
136 NativeValue* argv[] = {nativeWant};
137 CallObjectMethod("onCreate", argv, ARGC_ONE);
138 napi_close_handle_scope(env, scope);
139 }
140
OnConnect(const AAFwk::Want & want)141 sptr<IRemoteObject> JsDataShareExtAbility::OnConnect(const AAFwk::Want &want)
142 {
143 Extension::OnConnect(want);
144 sptr<DataShareStubImpl> remoteObject = new (std::nothrow) DataShareStubImpl(
145 std::static_pointer_cast<JsDataShareExtAbility>(shared_from_this()),
146 reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine()));
147 if (remoteObject == nullptr) {
148 LOG_ERROR("No memory allocated for DataShareStubImpl");
149 return nullptr;
150 }
151 return remoteObject->AsObject();
152 }
153
CheckAndSetAsyncResult(NativeEngine * engine)154 void JsDataShareExtAbility::CheckAndSetAsyncResult(NativeEngine* engine)
155 {
156 auto result = GetAsyncResult();
157 auto type = result->TypeOf();
158 if (type == NATIVE_NUMBER) {
159 int32_t value = OHOS::AppExecFwk::UnwrapInt32FromJS(reinterpret_cast<napi_env>(engine),
160 reinterpret_cast<napi_value>(result));
161 SetResult(value);
162 } else if (type == NATIVE_STRING) {
163 std::string value = OHOS::AppExecFwk::UnwrapStringFromJS(reinterpret_cast<napi_env>(engine),
164 reinterpret_cast<napi_value>(result));
165 SetResult(value);
166 } else if (type == NATIVE_OBJECT) {
167 ResultSetBridge::Creator *proxy = nullptr;
168 napi_unwrap(reinterpret_cast<napi_env>(engine), reinterpret_cast<napi_value>(result),
169 reinterpret_cast<void **>(&proxy));
170 if (proxy == nullptr) {
171 std::vector<std::string> value;
172 OHOS::AppExecFwk::UnwrapArrayStringFromJS(reinterpret_cast<napi_env>(engine),
173 reinterpret_cast<napi_value>(result), value);
174 SetResult(value);
175 } else {
176 std::shared_ptr<ResultSetBridge> value = proxy->Create();
177 std::shared_ptr<DataShareResultSet> resultSet = std::make_shared<DataShareResultSet>(value);
178 SetResult(resultSet);
179 }
180 } else {
181 callbackResultNumber_ = -1;
182 callbackResultString_ = "";
183 callbackResultStringArr_ = {};
184 callbackResultObject_ = nullptr;
185 }
186 }
187
AsyncCallback(NativeEngine * engine,NativeCallbackInfo * info)188 NativeValue* JsDataShareExtAbility::AsyncCallback(NativeEngine* engine, NativeCallbackInfo* info)
189 {
190 LOG_INFO("engine == nullptr : %{public}d, info == nullptr : %{public}d.", engine == nullptr, info == nullptr);
191 if (engine == nullptr || info == nullptr) {
192 LOG_ERROR("invalid param.");
193 return nullptr;
194 }
195 if (info->argc < ARGC_TWO || info->argv[0] == nullptr || info->argv[1] == nullptr) {
196 LOG_ERROR("invalid args.");
197 return engine->CreateUndefined();
198 }
199
200 int32_t value = -1;
201 if ((info->argv[0])->TypeOf() == NATIVE_NUMBER) {
202 value = OHOS::AppExecFwk::UnwrapInt32FromJS(reinterpret_cast<napi_env>(engine),
203 reinterpret_cast<napi_value>(info->argv[0]));
204 LOG_INFO("value_number : %{public}d.", value);
205 }
206
207 if (info->functionInfo == nullptr || info->functionInfo->data == nullptr) {
208 LOG_ERROR("invalid object.");
209 return engine->CreateUndefined();
210 }
211
212 JsDataShareExtAbility* instance = static_cast<JsDataShareExtAbility*>(info->functionInfo->data);
213 if (instance != nullptr) {
214 instance->SetBlockWaiting(true);
215 instance->SetAsyncResult(info->argv[1]);
216 instance->CheckAndSetAsyncResult(engine);
217 }
218
219 return engine->CreateUndefined();
220 }
221
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc,bool isAsync)222 NativeValue* JsDataShareExtAbility::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc,
223 bool isAsync)
224 {
225 LOG_INFO("JsDataShareExtAbility::CallObjectMethod(%{public}s), begin", name);
226
227 if (!jsObj_) {
228 LOG_WARN("Not found DataShareExtAbility.js");
229 return nullptr;
230 }
231
232 HandleEscape handleEscape(jsRuntime_);
233 auto& nativeEngine = jsRuntime_.GetNativeEngine();
234
235 NativeValue* value = jsObj_->Get();
236 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
237 if (obj == nullptr) {
238 LOG_ERROR("Failed to get DataShareExtAbility object");
239 return nullptr;
240 }
241
242 NativeValue* method = obj->GetProperty(name);
243 if (method == nullptr) {
244 LOG_ERROR("Failed to get '%{public}s' from DataShareExtAbility object", name);
245 return nullptr;
246 }
247
248 size_t count = argc + 1;
249 NativeValue **args = new (std::nothrow) NativeValue *[count];
250 if (args == nullptr) {
251 LOG_ERROR("JsDataShareExtAbility::CallObjectMethod new NativeValue error.");
252 return nullptr;
253 }
254 for (size_t i = 0; i < argc; i++) {
255 args[i] = argv[i];
256 }
257
258 if (isAsync) {
259 callbackResultNumber_ = -1;
260 callbackResultString_ = "";
261 callbackResultStringArr_ = {};
262 callbackResultObject_ = nullptr;
263 args[argc] = nativeEngine.CreateFunction(ASYNC_CALLBACK_NAME.c_str(),
264 ASYNC_CALLBACK_NAME.length(), JsDataShareExtAbility::AsyncCallback, this);
265 LOG_INFO("AsyncType::ASYNC_COMMON.");
266 } else {
267 args[argc] = nullptr;
268 }
269
270 SetBlockWaiting(false);
271 return handleEscape.Escape(nativeEngine.CallFunction(value, method, args, count));
272 }
273
GetSrcPath(std::string & srcPath)274 void JsDataShareExtAbility::GetSrcPath(std::string &srcPath)
275 {
276 if (!Extension::abilityInfo_->isStageBasedModel) {
277 /* temporary compatibility api8 + config.json */
278 srcPath.append(Extension::abilityInfo_->package);
279 srcPath.append("/assets/js/");
280 if (!Extension::abilityInfo_->srcPath.empty()) {
281 srcPath.append(Extension::abilityInfo_->srcPath);
282 }
283 srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
284 return;
285 }
286
287 if (!Extension::abilityInfo_->srcEntrance.empty()) {
288 srcPath.append(Extension::abilityInfo_->moduleName + "/");
289 srcPath.append(Extension::abilityInfo_->srcEntrance);
290 srcPath.erase(srcPath.rfind('.'));
291 srcPath.append(".abc");
292 }
293 }
294
GetFileTypes(const Uri & uri,const std::string & mimeTypeFilter)295 std::vector<std::string> JsDataShareExtAbility::GetFileTypes(const Uri &uri, const std::string &mimeTypeFilter)
296 {
297 auto ret = DataShareExtAbility::GetFileTypes(uri, mimeTypeFilter);
298 HandleScope handleScope(jsRuntime_);
299 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
300 napi_handle_scope scope = nullptr;
301 napi_open_handle_scope(env, &scope);
302 if (scope == nullptr) {
303 return ret;
304 }
305 napi_value napiUri = nullptr;
306 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
307 if (status != napi_ok) {
308 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
309 napi_close_handle_scope(env, scope);
310 return ret;
311 }
312 napi_value napiMimeTypeFilter = nullptr;
313 status = napi_create_string_utf8(env, mimeTypeFilter.c_str(), NAPI_AUTO_LENGTH, &napiMimeTypeFilter);
314 if (status != napi_ok) {
315 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
316 napi_close_handle_scope(env, scope);
317 return ret;
318 }
319
320 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
321 NativeValue* nativeMimeTypeFilter = reinterpret_cast<NativeValue*>(napiMimeTypeFilter);
322 NativeValue* argv[] = {nativeUri, nativeMimeTypeFilter};
323 CallObjectMethod("getFileTypes", argv, ARGC_TWO);
324 napi_close_handle_scope(env, scope);
325 return ret;
326 }
327
OpenFile(const Uri & uri,const std::string & mode)328 int JsDataShareExtAbility::OpenFile(const Uri &uri, const std::string &mode)
329 {
330 auto ret = DataShareExtAbility::OpenFile(uri, mode);
331 HandleScope handleScope(jsRuntime_);
332 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
333 napi_handle_scope scope = nullptr;
334 napi_open_handle_scope(env, &scope);
335 if (scope == nullptr) {
336 return ret;
337 }
338 napi_value napiUri = nullptr;
339 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
340 if (status != napi_ok) {
341 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
342 napi_close_handle_scope(env, scope);
343 return ret;
344 }
345 napi_value napiMode = nullptr;
346 status = napi_create_string_utf8(env, mode.c_str(), NAPI_AUTO_LENGTH, &napiMode);
347 if (status != napi_ok) {
348 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
349 napi_close_handle_scope(env, scope);
350 return ret;
351 }
352
353 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
354 NativeValue* nativeMode = reinterpret_cast<NativeValue*>(napiMode);
355 NativeValue* argv[] = {nativeUri, nativeMode};
356 CallObjectMethod("openFile", argv, ARGC_TWO);
357 napi_close_handle_scope(env, scope);
358 return ret;
359 }
360
OpenRawFile(const Uri & uri,const std::string & mode)361 int JsDataShareExtAbility::OpenRawFile(const Uri &uri, const std::string &mode)
362 {
363 auto ret = DataShareExtAbility::OpenRawFile(uri, mode);
364 HandleScope handleScope(jsRuntime_);
365 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
366 napi_handle_scope scope = nullptr;
367 napi_open_handle_scope(env, &scope);
368 if (scope == nullptr) {
369 return ret;
370 }
371 napi_value napiUri = nullptr;
372 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
373 if (status != napi_ok) {
374 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
375 napi_close_handle_scope(env, scope);
376 return ret;
377 }
378 napi_value napiMode = nullptr;
379 status = napi_create_string_utf8(env, mode.c_str(), NAPI_AUTO_LENGTH, &napiMode);
380 if (status != napi_ok) {
381 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
382 napi_close_handle_scope(env, scope);
383 return ret;
384 }
385
386 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
387 NativeValue* nativeMode = reinterpret_cast<NativeValue*>(napiMode);
388 NativeValue* argv[] = {nativeUri, nativeMode};
389 CallObjectMethod("openRawFile", argv, ARGC_TWO, false);
390 napi_close_handle_scope(env, scope);
391 return ret;
392 }
393
Insert(const Uri & uri,const DataShareValuesBucket & value)394 int JsDataShareExtAbility::Insert(const Uri &uri, const DataShareValuesBucket &value)
395 {
396 int ret = INVALID_VALUE;
397 ret = DataShareExtAbility::Insert(uri, value);
398 HandleScope handleScope(jsRuntime_);
399 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
400 napi_handle_scope scope = nullptr;
401 napi_open_handle_scope(env, &scope);
402 if (scope == nullptr) {
403 return ret;
404 }
405 napi_value napiUri = nullptr;
406 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
407 if (status != napi_ok) {
408 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
409 napi_close_handle_scope(env, scope);
410 return ret;
411 }
412 napi_value napiValue = DataShareValueBucketNewInstance(env, const_cast<DataShareValuesBucket&>(value));
413 if (napiValue == nullptr) {
414 LOG_ERROR("failed to make new instance of rdbValueBucket.");
415 napi_close_handle_scope(env, scope);
416 return ret;
417 }
418
419 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
420 NativeValue* nativeValue = reinterpret_cast<NativeValue*>(napiValue);
421 NativeValue* argv[] = {nativeUri, nativeValue};
422 CallObjectMethod("insert", argv, ARGC_TWO);
423 napi_close_handle_scope(env, scope);
424 return ret;
425 }
426
Update(const Uri & uri,const DataSharePredicates & predicates,const DataShareValuesBucket & value)427 int JsDataShareExtAbility::Update(const Uri &uri, const DataSharePredicates &predicates,
428 const DataShareValuesBucket &value)
429 {
430 int ret = INVALID_VALUE;
431 ret = DataShareExtAbility::Update(uri, predicates, value);
432 HandleScope handleScope(jsRuntime_);
433 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
434 napi_handle_scope scope = nullptr;
435 napi_open_handle_scope(env, &scope);
436 if (scope == nullptr) {
437 return ret;
438 }
439 napi_value napiUri = nullptr;
440 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
441 if (status != napi_ok) {
442 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
443 napi_close_handle_scope(env, scope);
444 return ret;
445 }
446
447 napi_value napiPredicates = MakePredicates(env, predicates);
448 if (napiPredicates == nullptr) {
449 napi_close_handle_scope(env, scope);
450 return ret;
451 }
452
453 napi_value napiValue = DataShareValueBucketNewInstance(env, const_cast<DataShareValuesBucket&>(value));
454 if (napiValue == nullptr) {
455 LOG_ERROR("failed to make new instance of rdbValueBucket.");
456 napi_close_handle_scope(env, scope);
457 return ret;
458 }
459
460 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
461 NativeValue* nativePredicates = reinterpret_cast<NativeValue*>(napiPredicates);
462 NativeValue* nativeValue = reinterpret_cast<NativeValue*>(napiValue);
463 NativeValue* argv[] = {nativeUri, nativePredicates, nativeValue};
464 CallObjectMethod("update", argv, ARGC_THREE);
465 napi_close_handle_scope(env, scope);
466 return ret;
467 }
468
Delete(const Uri & uri,const DataSharePredicates & predicates)469 int JsDataShareExtAbility::Delete(const Uri &uri, const DataSharePredicates &predicates)
470 {
471 int ret = INVALID_VALUE;
472 ret = DataShareExtAbility::Delete(uri, predicates);
473 HandleScope handleScope(jsRuntime_);
474 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
475 napi_handle_scope scope = nullptr;
476 napi_open_handle_scope(env, &scope);
477 if (scope == nullptr) {
478 return ret;
479 }
480 napi_value napiUri = nullptr;
481 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
482 if (status != napi_ok) {
483 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
484 napi_close_handle_scope(env, scope);
485 return ret;
486 }
487
488 napi_value napiPredicates = MakePredicates(env, predicates);
489 if (napiPredicates == nullptr) {
490 napi_close_handle_scope(env, scope);
491 return ret;
492 }
493
494 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
495 NativeValue* nativePredicates = reinterpret_cast<NativeValue*>(napiPredicates);
496 NativeValue* argv[] = {nativeUri, nativePredicates};
497 CallObjectMethod("delete", argv, ARGC_TWO);
498 napi_close_handle_scope(env, scope);
499 return ret;
500 }
501
Query(const Uri & uri,const DataSharePredicates & predicates,std::vector<std::string> & columns)502 std::shared_ptr<DataShareResultSet> JsDataShareExtAbility::Query(const Uri &uri,
503 const DataSharePredicates &predicates, std::vector<std::string> &columns)
504 {
505 std::shared_ptr<DataShareResultSet> ret;
506 ret = DataShareExtAbility::Query(uri, predicates, columns);
507
508 HandleScope handleScope(jsRuntime_);
509 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
510 napi_handle_scope scope = nullptr;
511 napi_open_handle_scope(env, &scope);
512 if (scope == nullptr) {
513 return ret;
514 }
515 napi_value napiUri = nullptr;
516 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
517 if (status != napi_ok) {
518 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
519 napi_close_handle_scope(env, scope);
520 return ret;
521 }
522
523 napi_value napiPredicates = MakePredicates(env, predicates);
524 if (napiPredicates == nullptr) {
525 napi_close_handle_scope(env, scope);
526 return ret;
527 }
528
529 napi_value napiColumns = nullptr;
530 if (!MakeNapiColumn(env, napiColumns, columns)) {
531 LOG_ERROR("MakeNapiColumn failed");
532 napi_close_handle_scope(env, scope);
533 return ret;
534 }
535
536 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
537 NativeValue* nativePredicates = reinterpret_cast<NativeValue*>(napiPredicates);
538 NativeValue* nativeColumns = reinterpret_cast<NativeValue*>(napiColumns);
539 NativeValue* argv[] = {nativeUri, nativePredicates, nativeColumns};
540 CallObjectMethod("query", argv, ARGC_THREE);
541 napi_close_handle_scope(env, scope);
542 return std::make_shared<DataShareResultSet>();
543 }
544
GetType(const Uri & uri)545 std::string JsDataShareExtAbility::GetType(const Uri &uri)
546 {
547 auto ret = DataShareExtAbility::GetType(uri);
548 HandleScope handleScope(jsRuntime_);
549 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
550 napi_handle_scope scope = nullptr;
551 napi_open_handle_scope(env, &scope);
552 if (scope == nullptr) {
553 return ret;
554 }
555 napi_value napiUri = nullptr;
556 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
557 if (status != napi_ok) {
558 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
559 napi_close_handle_scope(env, scope);
560 return ret;
561 }
562 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
563 NativeValue* argv[] = {nativeUri};
564 CallObjectMethod("getType", argv, ARGC_ONE);
565 napi_close_handle_scope(env, scope);
566 return ret;
567 }
568
BatchInsert(const Uri & uri,const std::vector<DataShareValuesBucket> & values)569 int JsDataShareExtAbility::BatchInsert(const Uri &uri, const std::vector<DataShareValuesBucket> &values)
570 {
571 int ret = INVALID_VALUE;
572 ret = DataShareExtAbility::BatchInsert(uri, values);
573
574 HandleScope handleScope(jsRuntime_);
575 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
576 napi_handle_scope scope = nullptr;
577 napi_open_handle_scope(env, &scope);
578 if (scope == nullptr) {
579 return ret;
580 }
581 napi_value napiUri = nullptr;
582 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
583 if (status != napi_ok) {
584 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
585 napi_close_handle_scope(env, scope);
586 return ret;
587 }
588
589 napi_value napiValues = nullptr;
590 status = napi_create_array(env, &napiValues);
591 if (status != napi_ok) {
592 LOG_ERROR("napi_create_array status : %{public}d", status);
593 napi_close_handle_scope(env, scope);
594 return ret;
595 }
596 bool isArray = false;
597 if (napi_is_array(env, napiValues, &isArray) != napi_ok || !isArray) {
598 LOG_ERROR("JsDataShareExtAbility create array failed");
599 napi_close_handle_scope(env, scope);
600 return ret;
601 }
602 int32_t index = 0;
603 for (const auto &value : values) {
604 napi_value result = DataShareValueBucketNewInstance(env, const_cast<DataShareValuesBucket&>(value));
605 if (result == nullptr) {
606 LOG_ERROR("failed to make new instance of rdbValueBucket.");
607 napi_close_handle_scope(env, scope);
608 return ret;
609 }
610 napi_set_element(env, napiValues, index++, result);
611 }
612
613 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
614 NativeValue* nativeValues = reinterpret_cast<NativeValue*>(napiValues);
615 NativeValue* argv[] = {nativeUri, nativeValues};
616 CallObjectMethod("batchInsert", argv, ARGC_TWO);
617 napi_close_handle_scope(env, scope);
618 return ret;
619 }
620
RegisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)621 bool JsDataShareExtAbility::RegisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
622 {
623 DataShareExtAbility::RegisterObserver(uri, dataObserver);
624 auto obsMgrClient = DataObsMgrClient::GetInstance();
625 if (obsMgrClient == nullptr) {
626 LOG_ERROR("obsMgrClient is nullptr");
627 return false;
628 }
629
630 ErrCode ret = obsMgrClient->RegisterObserver(uri, dataObserver);
631 if (ret != ERR_OK) {
632 LOG_ERROR("obsMgrClient->RegisterObserver error return %{public}d", ret);
633 return false;
634 }
635 return true;
636 }
637
UnregisterObserver(const Uri & uri,const sptr<AAFwk::IDataAbilityObserver> & dataObserver)638 bool JsDataShareExtAbility::UnregisterObserver(const Uri &uri, const sptr<AAFwk::IDataAbilityObserver> &dataObserver)
639 {
640 DataShareExtAbility::UnregisterObserver(uri, dataObserver);
641 auto obsMgrClient = DataObsMgrClient::GetInstance();
642 if (obsMgrClient == nullptr) {
643 LOG_ERROR("obsMgrClient is nullptr");
644 return false;
645 }
646
647 ErrCode ret = obsMgrClient->UnregisterObserver(uri, dataObserver);
648 if (ret != ERR_OK) {
649 LOG_ERROR("obsMgrClient->UnregisterObserver error return %{public}d", ret);
650 return false;
651 }
652 return true;
653 }
654
NotifyChange(const Uri & uri)655 bool JsDataShareExtAbility::NotifyChange(const Uri &uri)
656 {
657 DataShareExtAbility::NotifyChange(uri);
658 auto obsMgrClient = DataObsMgrClient::GetInstance();
659 if (obsMgrClient == nullptr) {
660 LOG_ERROR("obsMgrClient is nullptr");
661 return false;
662 }
663
664 ErrCode ret = obsMgrClient->NotifyChange(uri);
665 if (ret != ERR_OK) {
666 LOG_ERROR("obsMgrClient->NotifyChange error return %{public}d", ret);
667 return false;
668 }
669 return true;
670 }
671
NormalizeUri(const Uri & uri)672 Uri JsDataShareExtAbility::NormalizeUri(const Uri &uri)
673 {
674 auto ret = DataShareExtAbility::NormalizeUri(uri);
675 HandleScope handleScope(jsRuntime_);
676 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
677 napi_handle_scope scope = nullptr;
678 napi_open_handle_scope(env, &scope);
679 if (scope == nullptr) {
680 return ret;
681 }
682 napi_value napiUri = nullptr;
683 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
684 if (status != napi_ok) {
685 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
686 napi_close_handle_scope(env, scope);
687 return ret;
688 }
689 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
690 NativeValue* argv[] = {nativeUri};
691 CallObjectMethod("normalizeUri", argv, ARGC_ONE);
692 napi_close_handle_scope(env, scope);
693 return ret;
694 }
695
DenormalizeUri(const Uri & uri)696 Uri JsDataShareExtAbility::DenormalizeUri(const Uri &uri)
697 {
698 auto ret = DataShareExtAbility::DenormalizeUri(uri);
699 HandleScope handleScope(jsRuntime_);
700 napi_env env = reinterpret_cast<napi_env>(&jsRuntime_.GetNativeEngine());
701 napi_handle_scope scope = nullptr;
702 napi_open_handle_scope(env, &scope);
703 if (scope == nullptr) {
704 return ret;
705 }
706 napi_value napiUri = nullptr;
707 napi_status status = napi_create_string_utf8(env, uri.ToString().c_str(), NAPI_AUTO_LENGTH, &napiUri);
708 if (status != napi_ok) {
709 LOG_ERROR("napi_create_string_utf8 status : %{public}d", status);
710 napi_close_handle_scope(env, scope);
711 return ret;
712 }
713 NativeValue* nativeUri = reinterpret_cast<NativeValue*>(napiUri);
714 NativeValue* argv[] = {nativeUri};
715 CallObjectMethod("denormalizeUri", argv, ARGC_ONE);
716 napi_close_handle_scope(env, scope);
717 return ret;
718 }
719
MakePredicates(napi_env env,const DataSharePredicates & predicates)720 napi_value JsDataShareExtAbility::MakePredicates(napi_env env, const DataSharePredicates &predicates)
721 {
722 std::shared_ptr<DataSharePredicates> predicatesPtr = std::make_shared<DataSharePredicates>(predicates);
723 if (predicatesPtr == nullptr) {
724 LOG_ERROR("No memory allocated for predicates");
725 return nullptr;
726 }
727 napi_value napiPredicates = DataSharePredicatesProxy::NewInstance(env, predicatesPtr);
728 if (napiPredicates == nullptr) {
729 LOG_ERROR("failed to make new instance of DataSharePredicates.");
730 }
731 return napiPredicates;
732 }
733
MakeNapiColumn(napi_env env,napi_value & napiColumns,const std::vector<std::string> & columns)734 bool MakeNapiColumn(napi_env env, napi_value &napiColumns, const std::vector<std::string> &columns)
735 {
736 napi_status status = napi_create_array(env, &napiColumns);
737 if (status != napi_ok) {
738 LOG_ERROR("napi_create_array status : %{public}d", status);
739 return false;
740 }
741
742 bool isArray = false;
743 if (napi_is_array(env, napiColumns, &isArray) != napi_ok || !isArray) {
744 LOG_ERROR("JsDataShareExtAbility create array failed");
745 return false;
746 }
747
748 int32_t index = 0;
749 for (const auto &column : columns) {
750 napi_value result = nullptr;
751 napi_create_string_utf8(env, column.c_str(), column.length(), &result);
752 napi_set_element(env, napiColumns, index++, result);
753 }
754
755 return true;
756 }
757 } // namespace DataShare
758 } // namespace OHOS