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