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