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