• 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 "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