• 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_distributedobjectstore.h"
17 
18 #include <cstring>
19 #include <random>
20 
21 #include "ability_context.h"
22 #include "accesstoken_kit.h"
23 #include "application_context.h"
24 #include "distributed_objectstore.h"
25 #include "js_ability.h"
26 #include "js_common.h"
27 #include "js_distributedobject.h"
28 #include "js_object_wrapper.h"
29 #include "js_util.h"
30 #include "logger.h"
31 #include "object_error.h"
32 #include "objectstore_errors.h"
33 
34 namespace OHOS::ObjectStore {
35 constexpr size_t TYPE_SIZE = 10;
36 const std::string DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
37 static ConcurrentMap<std::string, std::list<napi_ref>> g_statusCallBacks;
38 static ConcurrentMap<std::string, std::list<napi_ref>> g_changeCallBacks;
AddCallback(napi_env env,ConcurrentMap<std::string,std::list<napi_ref>> & callbacks,const std::string & objectId,napi_value callback)39 bool JSDistributedObjectStore::AddCallback(napi_env env, ConcurrentMap<std::string, std::list<napi_ref>> &callbacks,
40     const std::string &objectId, napi_value callback)
41 {
42     LOG_INFO("add callback %{public}s", objectId.c_str());
43     napi_ref ref = nullptr;
44     napi_status status = napi_create_reference(env, callback, 1, &ref);
45     if (status != napi_ok) {
46         return false;
47     }
48     return callbacks.Compute(objectId, [&ref](const std::string &key, std::list<napi_ref> &lists) {
49         lists.push_back(ref);
50         return true;
51     });
52 }
53 
DeleteAllCallback(napi_env env,std::list<napi_ref> & lists)54 bool DeleteAllCallback(napi_env env, std::list<napi_ref> &lists)
55 {
56     for (auto iter = lists.begin(); iter != lists.end();) {
57         if (*iter == nullptr) {
58             iter++;
59             continue;
60         }
61         napi_status status = napi_delete_reference(env, *iter);
62         CHECK_EQUAL_WITH_RETURN_FALSE(status, napi_ok);
63         iter = lists.erase(iter);
64     }
65     return false;
66 }
67 
DeleteSingleCallback(napi_env env,std::list<napi_ref> & lists,napi_value callback)68 bool DeleteSingleCallback(napi_env env, std::list<napi_ref> &lists, napi_value callback)
69 {
70     napi_value callbackTmp;
71     for (auto iter = lists.begin(); iter != lists.end();) {
72         if (*iter == nullptr) {
73             iter++;
74             continue;
75         }
76         napi_status status = napi_get_reference_value(env, *iter, &callbackTmp);
77         CHECK_EQUAL_WITH_RETURN_FALSE(status, napi_ok);
78         bool isEquals = false;
79         napi_strict_equals(env, callbackTmp, callback, &isEquals);
80         if (isEquals) {
81             napi_delete_reference(env, *iter);
82             iter = lists.erase(iter);
83         } else {
84             iter++;
85         }
86     }
87     return !lists.empty();
88 }
89 
DelCallback(napi_env env,ConcurrentMap<std::string,std::list<napi_ref>> & callbacks,const std::string & sessionId,napi_value callback)90 bool JSDistributedObjectStore::DelCallback(napi_env env, ConcurrentMap<std::string, std::list<napi_ref>> &callbacks,
91     const std::string &sessionId, napi_value callback)
92 {
93     LOG_INFO("del callback %{public}s", sessionId.c_str());
94     auto execute = [&env, callback](const std::string &key, std::list<napi_ref> &lists) {
95         if (callback == nullptr) {
96             return DeleteAllCallback(env, lists);
97         } else {
98             return DeleteSingleCallback(env, lists, callback);
99         }
100     };
101     return callbacks.ComputeIfPresent(sessionId, execute);
102 }
103 
NewDistributedObject(napi_env env,DistributedObjectStore * objectStore,DistributedObject * object,const std::string & objectId)104 napi_value JSDistributedObjectStore::NewDistributedObject(
105     napi_env env, DistributedObjectStore *objectStore, DistributedObject *object, const std::string &objectId)
106 {
107     napi_value result;
108     napi_status status = napi_new_instance(env, JSDistributedObject::GetCons(env), 0, nullptr, &result);
109     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
110     JSObjectWrapper *objectWrapper = new (std::nothrow) JSObjectWrapper(objectStore, object);
111     if (objectWrapper == nullptr) {
112         LOG_ERROR("JSDistributedObjectStore::NewDistributedObject no memory for objectWrapper malloc!");
113         return nullptr;
114     }
115     objectWrapper->SetObjectId(objectId);
116     status = napi_wrap(
117         env, result, objectWrapper,
118         [](napi_env env, void *data, void *hint) {
119             if (data == nullptr) {
120                 LOG_WARN("objectWrapper is nullptr.");
121                 return;
122             }
123             auto objectWrapper = static_cast<JSObjectWrapper *>(data);
124 
125             JSDistributedObjectStore::DelCallback(env, g_changeCallBacks, objectWrapper->GetObjectId());
126             JSDistributedObjectStore::DelCallback(env, g_statusCallBacks, objectWrapper->GetObjectId());
127 
128             if (objectWrapper->GetObject() == nullptr) {
129                 delete objectWrapper;
130                 return;
131             }
132             LOG_INFO("start delete object");
133             DistributedObjectStore::GetInstance(JSDistributedObjectStore::GetBundleName(env))
134                 ->DeleteObject(objectWrapper->GetObject()->GetSessionId());
135             delete objectWrapper;
136         },
137         nullptr, nullptr);
138     if (status != napi_ok) {
139         LOG_WARN("error! napi_wrap failed.");
140         delete objectWrapper;
141         return nullptr;
142     }
143 
144     RestoreWatchers(env, objectWrapper, objectId);
145     objectStore->NotifyCachedStatus(object->GetSessionId());
146     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
147     return result;
148 }
149 
150 // function createObjectSync(version: number, sessionId: string, objectId:string): DistributedObject;
151 // function createObjectSync(version: number, sessionId: string, objectId:string, context: Context): DistributedObject;
JSCreateObjectSync(napi_env env,napi_callback_info info)152 napi_value JSDistributedObjectStore::JSCreateObjectSync(napi_env env, napi_callback_info info)
153 {
154     size_t requireArgc = 3;
155     size_t argc = 4;
156     napi_value argv[4] = { 0 };
157     napi_value thisVar = nullptr;
158     void *data = nullptr;
159     double version = 8;
160     std::string sessionId;
161     std::string objectId;
162     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
163     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
164     auto innerError = std::make_shared<InnerError>();
165     NAPI_ASSERT_ERRCODE(env, argc >= 1, version, innerError);
166     napi_valuetype valueType = napi_undefined;
167     status = napi_typeof(env, argv[0], &valueType);
168     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
169     status = JSUtil::GetValue(env, argv[0], version);
170     NAPI_ASSERT_ERRCODE(env, argc >= requireArgc, version, std::make_shared<ParametersNum>("1 or 2"));
171     NAPI_ASSERT_ERRCODE(env, !IsSandBox(), version, innerError);
172     LOG_INFO("start JSCreateObjectSync");
173     NAPI_ASSERT_ERRCODE(env, JSDistributedObjectStore::CheckSyncPermission(), version,
174         std::make_shared<PermissionError>());
175     status = napi_typeof(env, argv[1], &valueType);
176     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
177     NAPI_ASSERT_ERRCODE(env, valueType == napi_string, version,
178         std::make_shared<ParametersType>("sessionId", "string"));
179     status = JSUtil::GetValue(env, argv[1], sessionId);
180     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
181     status = napi_typeof(env, argv[2], &valueType);
182     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
183     CHECK_EQUAL_WITH_RETURN_NULL(valueType, napi_string);
184     status = JSUtil::GetValue(env, argv[2], objectId);
185     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
186     std::string bundleName = "";
187     if (argc > requireArgc) {
188         bool executeResult = JSDistributedObjectStore::GetBundleNameWithContext(env, argv[3], bundleName);
189         NAPI_ASSERT_ERRCODE(env, executeResult, version, innerError);
190     } else {
191         bundleName = JSDistributedObjectStore::GetBundleName(env);
192     }
193     DistributedObjectStore *objectInfo = DistributedObjectStore::GetInstance(bundleName);
194     NAPI_ASSERT_ERRCODE(env, objectInfo != nullptr, version, innerError);
195     uint32_t result = 0;
196     DistributedObject *object = objectInfo->CreateObject(sessionId, result);
197     NAPI_ASSERT_ERRCODE(env, result != ERR_EXIST, version, std::make_shared<DatabaseError>());
198     NAPI_ASSERT_ERRCODE(env, result == SUCCESS, version, innerError);
199     NAPI_ASSERT_ERRCODE(env, object != nullptr, version, innerError);
200     return NewDistributedObject(env, objectInfo, object, objectId);
201 }
202 
203 // function destroyObjectSync(version: number, object: DistributedObject): number;
JSDestroyObjectSync(napi_env env,napi_callback_info info)204 napi_value JSDistributedObjectStore::JSDestroyObjectSync(napi_env env, napi_callback_info info)
205 {
206     double version = 8;
207     LOG_INFO("start");
208     size_t requireArgc = 2;
209     size_t argc = 2;
210     napi_value argv[2] = { 0 };
211     napi_value thisVar = nullptr;
212     void *data = nullptr;
213     std::string sessionId;
214     std::string bundleName;
215     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
216     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
217     status = JSUtil::GetValue(env, argv[0], version);
218     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
219     ASSERT_MATCH_ELSE_RETURN_NULL(argc >= requireArgc);
220     JSObjectWrapper *objectWrapper = nullptr;
221     status = napi_unwrap(env, argv[1], (void **)&objectWrapper);
222     auto innerError = std::make_shared<InnerError>();
223     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
224     NAPI_ASSERT_ERRCODE(env, objectWrapper != nullptr, version, innerError);
225     DistributedObjectStore *objectInfo =
226         DistributedObjectStore::GetInstance(JSDistributedObjectStore::GetBundleName(env));
227     NAPI_ASSERT_ERRCODE(env, objectInfo != nullptr && objectWrapper->GetObject() != nullptr, version, innerError);
228     objectWrapper->DeleteWatch(env, CHANGE);
229     objectWrapper->DeleteWatch(env, STATUS);
230     objectInfo->DeleteObject(objectWrapper->GetObject()->GetSessionId());
231     objectWrapper->DestroyObject();
232     return nullptr;
233 }
234 
235 // function on(version: number, type: 'change', object: DistributedObject,
236 //             callback: Callback<ChangedDataObserver>): void;
237 // function on(version: number, type: 'status', object: DistributedObject,
238 //             callback: Callback<ObjectStatusObserver>): void;
JSOn(napi_env env,napi_callback_info info)239 napi_value JSDistributedObjectStore::JSOn(napi_env env, napi_callback_info info)
240 {
241     double version = 8;
242     LOG_INFO("start");
243     size_t requireArgc = 4;
244     size_t argc = 4;
245     napi_value argv[4] = { 0 };
246     napi_value thisVar = nullptr;
247     void *data = nullptr;
248     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
249     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
250     auto innerError = std::make_shared<InnerError>();
251     NAPI_ASSERT_ERRCODE(env, argc >= 1, version, innerError);
252     status = JSUtil::GetValue(env, argv[0], version);
253     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
254     NAPI_ASSERT_ERRCODE(env, argc >= requireArgc, version, std::make_shared<ParametersNum>("2"));
255     char type[TYPE_SIZE] = { 0 };
256     size_t eventTypeLen = 0;
257     napi_valuetype valueType = napi_undefined;
258     status = napi_typeof(env, argv[1], &valueType);
259     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
260     NAPI_ASSERT_ERRCODE(env, valueType == napi_string, version, std::make_shared<ParametersType>("type", "string"));
261     status = napi_get_value_string_utf8(env, argv[1], type, TYPE_SIZE, &eventTypeLen);
262     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
263 
264     napi_valuetype objectType = napi_undefined;
265     status = napi_typeof(env, argv[2], &objectType);
266     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
267     ASSERT_MATCH_ELSE_RETURN_NULL(objectType == napi_object);
268 
269     JSObjectWrapper *wrapper = nullptr;
270     status = napi_unwrap(env, argv[2], (void **)&wrapper);
271     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
272     NAPI_ASSERT_ERRCODE(env, wrapper != nullptr, version, innerError);
273     napi_valuetype callbackType = napi_undefined;
274     status = napi_typeof(env, argv[3], &callbackType);
275     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
276     NAPI_ASSERT_ERRCODE(env, callbackType == napi_function, version,
277         std::make_shared<ParametersType>("callback", "function"));
278     bool addResult = wrapper->AddWatch(env, type, argv[3]);
279     NAPI_ASSERT_ERRCODE(env, addResult, version, innerError);
280     napi_value result = nullptr;
281     napi_get_undefined(env, &result);
282     return result;
283 }
284 
285 // function off(version: number, type: 'change', object: DistributedObject,
286 //              callback?: Callback<ChangedDataObserver>): void;
287 // function off(version: number, type: 'status', object: DistributedObject,
288 //              callback?: Callback<ObjectStatusObserver>): void;
JSOff(napi_env env,napi_callback_info info)289 napi_value JSDistributedObjectStore::JSOff(napi_env env, napi_callback_info info)
290 {
291     double version = 8;
292     LOG_INFO("start");
293     size_t requireArgc = 3;
294     size_t argc = 4;
295     napi_value argv[4] = { 0 };
296     napi_value thisVar = nullptr;
297     void *data = nullptr;
298     char type[TYPE_SIZE] = { 0 };
299     size_t typeLen = 0;
300     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
301     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
302     auto innerError = std::make_shared<InnerError>();
303     NAPI_ASSERT_ERRCODE(env, argc >= 1, version, innerError);
304     status = JSUtil::GetValue(env, argv[0], version);
305     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
306     NAPI_ASSERT_ERRCODE(env, argc >= requireArgc, version, std::make_shared<ParametersNum>("1"));
307     napi_valuetype valueType = napi_undefined;
308     status = napi_typeof(env, argv[1], &valueType);
309     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
310     NAPI_ASSERT_ERRCODE(env, valueType == napi_string, version, std::make_shared<ParametersType>("type", "string"));
311     status = napi_get_value_string_utf8(env, argv[1], type, TYPE_SIZE, &typeLen);
312     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
313 
314     status = napi_typeof(env, argv[2], &valueType);
315     ASSERT_MATCH_ELSE_RETURN_NULL(valueType == napi_object);
316     JSObjectWrapper *wrapper = nullptr;
317     status = napi_unwrap(env, argv[2], (void **)&wrapper);
318     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
319     NAPI_ASSERT_ERRCODE(env, wrapper != nullptr, version, innerError);
320     if (argc == requireArgc) {
321         LOG_INFO("delete all");
322         wrapper->DeleteWatch(env, type);
323     } else {
324         LOG_INFO("delete");
325         status = napi_typeof(env, argv[3], &valueType);
326         NAPI_ASSERT_ERRCODE(env, valueType == napi_function, version,
327             std::make_shared<ParametersType>("callback", "function"));
328         wrapper->DeleteWatch(env, type, argv[3]);
329     }
330     napi_value result = nullptr;
331     status = napi_get_undefined(env, &result);
332     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
333     return result;
334 }
335 
GetBundleNameWithContext(napi_env env,napi_value argv,std::string & bundleName)336 bool JSDistributedObjectStore::GetBundleNameWithContext(napi_env env, napi_value argv, std::string &bundleName)
337 {
338     napi_valuetype objectType = napi_undefined;
339     napi_status status = napi_typeof(env, argv, &objectType);
340     if (status == napi_ok && objectType == napi_object) {
341         std::shared_ptr<Context> context = JSAbility::GetContext(env, argv);
342         if (context != nullptr) {
343             bundleName = context->GetBundleName();
344             return true;
345         }
346     }
347     LOG_ERROR("arguments error, context.");
348     return false;
349 }
350 
GetBundleName(napi_env env)351 std::string JSDistributedObjectStore::GetBundleName(napi_env env)
352 {
353     static std::string bundleName;
354     if (bundleName.empty()) {
355         bundleName = AbilityRuntime::Context::GetApplicationContext()->GetBundleName();
356     }
357     return bundleName;
358 }
359 
RestoreWatchers(napi_env env,JSObjectWrapper * wrapper,const std::string & objectId)360 void JSDistributedObjectStore::RestoreWatchers(napi_env env, JSObjectWrapper *wrapper, const std::string &objectId)
361 {
362     napi_status status;
363     napi_value callbackValue;
364     bool watchResult = true;
365     LOG_DEBUG("start restore %{public}s", objectId.c_str());
366     watchResult = g_changeCallBacks.ComputeIfPresent(objectId, [&](const std::string &key, std::list<napi_ref> &lists) {
367         for (auto callback : lists) {
368             status = napi_get_reference_value(env, callback, &callbackValue);
369             if (status != napi_ok) {
370                 LOG_ERROR("error! %{public}d", status);
371                 continue;
372             }
373             wrapper->AddWatch(env, CHANGE, callbackValue);
374         }
375         return true;
376     });
377     if (!watchResult) {
378         LOG_INFO("no callback %{public}s", objectId.c_str());
379     }
380     watchResult = g_statusCallBacks.ComputeIfPresent(objectId, [&](const std::string &key, std::list<napi_ref> &lists) {
381         for (auto callback : lists) {
382             status = napi_get_reference_value(env, callback, &callbackValue);
383             if (status != napi_ok) {
384                 LOG_ERROR("error! %{public}d", status);
385                 continue;
386             }
387             wrapper->AddWatch(env, STATUS, callbackValue);
388         }
389         return true;
390     });
391     if (!watchResult) {
392         LOG_INFO("no status %{public}s", objectId.c_str());
393     }
394 }
395 
396 // function recordCallback(version: number, type: 'change', objectId: string,
397 //                         callback: Callback<ChangedDataObserver>): void;
398 // function recordCallback(version: number, type: 'status', objectId: string,
399 //                         callback: Callback<ObjectStatusObserver>): void;
JSRecordCallback(napi_env env,napi_callback_info info)400 napi_value JSDistributedObjectStore::JSRecordCallback(napi_env env, napi_callback_info info)
401 {
402     double version = 8;
403     LOG_INFO("start");
404     size_t requireArgc = 4;
405     size_t argc = 4;
406     napi_value argv[4] = { 0 };
407     napi_value thisVar = nullptr;
408     void *data = nullptr;
409     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
410     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
411     auto innerError = std::make_shared<InnerError>();
412     NAPI_ASSERT_ERRCODE(env, argc >= 1, version, innerError);
413     status = JSUtil::GetValue(env, argv[0], version);
414     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
415     NAPI_ASSERT_ERRCODE(env, argc >= requireArgc, version, std::make_shared<ParametersNum>("2"));
416     char type[TYPE_SIZE] = { 0 };
417     size_t eventTypeLen = 0;
418     napi_valuetype valueType = napi_undefined;
419     status = napi_typeof(env, argv[1], &valueType);
420     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
421     NAPI_ASSERT_ERRCODE(env, valueType == napi_string, version, std::make_shared<ParametersType>("type", "string"));
422     status = napi_get_value_string_utf8(env, argv[1], type, TYPE_SIZE, &eventTypeLen);
423     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
424     std::string objectId;
425     status = napi_typeof(env, argv[2], &valueType);
426     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
427     CHECK_EQUAL_WITH_RETURN_NULL(valueType, napi_string);
428     status = JSUtil::GetValue(env, argv[2], objectId);
429     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
430     napi_valuetype callbackType = napi_undefined;
431     status = napi_typeof(env, argv[3], &callbackType);
432     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
433     NAPI_ASSERT_ERRCODE(env, callbackType == napi_function, version,
434         std::make_shared<ParametersType>("callback", "function"));
435     bool addResult = true;
436     if (!strcmp(CHANGE, type)) {
437         addResult = AddCallback(env, g_changeCallBacks, objectId, argv[3]);
438     } else if (!strcmp(STATUS, type)) {
439         addResult = AddCallback(env, g_statusCallBacks, objectId, argv[3]);
440     }
441     NAPI_ASSERT_ERRCODE(env, addResult, version, innerError);
442     napi_value result = nullptr;
443     napi_get_undefined(env, &result);
444     return result;
445 }
446 
447 // function deleteCallback(version: number, type: 'change', objectId: string,
448 //                         callback?: Callback<ChangedDataObserver>): void;
449 // function deleteCallback(version: number, type: 'status', objectId: string,
450 //                         callback?: Callback<ObjectStatusObserver>): void;
JSDeleteCallback(napi_env env,napi_callback_info info)451 napi_value JSDistributedObjectStore::JSDeleteCallback(napi_env env, napi_callback_info info)
452 {
453     double version = 8;
454     LOG_INFO("start");
455     size_t requireArgc = 3;
456     size_t argc = 4;
457     napi_value argv[4] = { 0 };
458     napi_value thisVar = nullptr;
459     void *data = nullptr;
460     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
461     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
462     auto innerError = std::make_shared<InnerError>();
463     NAPI_ASSERT_ERRCODE(env, argc >= 1, version, innerError);
464     status = JSUtil::GetValue(env, argv[0], version);
465     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
466     NAPI_ASSERT_ERRCODE(env, argc >= requireArgc, version, std::make_shared<ParametersNum>("1 or 2"));
467     char type[TYPE_SIZE] = { 0 };
468     size_t eventTypeLen = 0;
469     napi_valuetype valueType = napi_undefined;
470     status = napi_typeof(env, argv[1], &valueType);
471     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
472     NAPI_ASSERT_ERRCODE(env, valueType == napi_string, version, std::make_shared<ParametersType>("type", "string"));
473     status = napi_get_value_string_utf8(env, argv[1], type, TYPE_SIZE, &eventTypeLen);
474     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
475 
476     std::string objectId;
477     status = napi_typeof(env, argv[2], &valueType);
478     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
479     CHECK_EQUAL_WITH_RETURN_NULL(valueType, napi_string);
480     status = JSUtil::GetValue(env, argv[2], objectId);
481     NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
482     bool delResult = true;
483     if (argc == 3) {
484         if (!strcmp(CHANGE, type)) {
485             delResult = DelCallback(env, g_changeCallBacks, objectId);
486         } else if (!strcmp(STATUS, type)) {
487             delResult = DelCallback(env, g_statusCallBacks, objectId);
488         }
489     } else {
490         napi_valuetype callbackType = napi_undefined;
491         status = napi_typeof(env, argv[3], &callbackType);
492         NAPI_ASSERT_ERRCODE(env, status == napi_ok, version, innerError);
493         NAPI_ASSERT_ERRCODE(env, callbackType == napi_function, version,
494             std::make_shared<ParametersType>("callback", "function"));
495         if (!strcmp(CHANGE, type)) {
496             delResult = DelCallback(env, g_changeCallBacks, objectId, argv[3]);
497         } else if (!strcmp(STATUS, type)) {
498             delResult = DelCallback(env, g_statusCallBacks, objectId, argv[3]);
499         }
500     }
501     NAPI_ASSERT_ERRCODE(env, delResult, version, innerError);
502     napi_value result = nullptr;
503     napi_get_undefined(env, &result);
504     return result;
505 }
506 
JSEquenceNum(napi_env env,napi_callback_info info)507 napi_value JSDistributedObjectStore::JSEquenceNum(napi_env env, napi_callback_info info)
508 {
509     std::random_device randomDevice;
510     std::uniform_int_distribution<uint32_t> distribution(0, std::numeric_limits<uint32_t>::max());
511     std::string str = std::to_string(distribution(randomDevice));
512     napi_value result = nullptr;
513     napi_status status = napi_create_string_utf8(env, str.c_str(), str.size(), &result);
514     CHECK_EQUAL_WITH_RETURN_NULL(status, napi_ok);
515     return result;
516 }
517 
CheckSyncPermission()518 bool JSDistributedObjectStore::CheckSyncPermission()
519 {
520     int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(
521         AbilityRuntime::Context::GetApplicationContext()->GetApplicationInfo()->accessTokenId, DISTRIBUTED_DATASYNC);
522     if (ret == Security::AccessToken::PermissionState::PERMISSION_DENIED) {
523         LOG_ERROR("VerifyPermission %{public}d: PERMISSION_DENIED",
524             AbilityRuntime::Context::GetApplicationContext()->GetApplicationInfo()->accessTokenId);
525         return false;
526     }
527     return true;
528 }
529 
530 // don't create distributed data object while this application is sandbox
IsSandBox()531 bool JSDistributedObjectStore::IsSandBox()
532 {
533     int32_t dlpFlag = Security::AccessToken::AccessTokenKit::GetHapDlpFlag(
534         AbilityRuntime::Context::GetApplicationContext()->GetApplicationInfo()->accessTokenId);
535     if (dlpFlag != 0) {
536         return true;
537     }
538     return false;
539 }
540 } // namespace OHOS::ObjectStore
541