1 /*
2 * Copyright (c) 2021 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 "runtime_context_impl.h"
17 #include "db_errno.h"
18 #include "log_print.h"
19 #include "communicator_aggregator.h"
20 #include "network_adapter.h"
21
22 namespace DistributedDB {
RuntimeContextImpl()23 RuntimeContextImpl::RuntimeContextImpl()
24 : adapter_(nullptr),
25 communicatorAggregator_(nullptr),
26 mainLoop_(nullptr),
27 currentTimerId_(0),
28 taskPool_(nullptr),
29 taskPoolReportsTimerId_(0),
30 timeTickMonitor_(nullptr),
31 systemApiAdapter_(nullptr),
32 lockStatusObserver_(nullptr)
33 {
34 }
35
36 // Destruct the object.
~RuntimeContextImpl()37 RuntimeContextImpl::~RuntimeContextImpl()
38 {
39 if (taskPoolReportsTimerId_ > 0) {
40 RemoveTimer(taskPoolReportsTimerId_, true);
41 taskPoolReportsTimerId_ = 0;
42 }
43 if (taskPool_ != nullptr) {
44 taskPool_->Stop();
45 taskPool_->Release(taskPool_);
46 taskPool_ = nullptr;
47 }
48 if (mainLoop_ != nullptr) {
49 mainLoop_->KillAndDecObjRef(mainLoop_);
50 mainLoop_ = nullptr;
51 }
52 SetCommunicatorAggregator(nullptr);
53 (void)SetCommunicatorAdapter(nullptr);
54 systemApiAdapter_ = nullptr;
55 delete lockStatusObserver_;
56 lockStatusObserver_ = nullptr;
57 userChangeMonitor_ = nullptr;
58 }
59
60 // Set the label of this process.
SetProcessLabel(const std::string & label)61 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
62 {
63 std::lock_guard<std::mutex> labelLock(labelMutex_);
64 processLabel_ = label;
65 }
66
GetProcessLabel() const67 std::string RuntimeContextImpl::GetProcessLabel() const
68 {
69 std::lock_guard<std::mutex> labelLock(labelMutex_);
70 return processLabel_;
71 }
72
SetCommunicatorAdapter(IAdapter * adapter)73 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
74 {
75 {
76 std::lock_guard<std::mutex> autoLock(communicatorLock_);
77 if (adapter_ != nullptr) {
78 if (communicatorAggregator_ != nullptr) {
79 return -E_NOT_SUPPORT;
80 }
81 delete adapter_;
82 }
83 adapter_ = adapter;
84 }
85 ICommunicatorAggregator *communicatorAggregator = nullptr;
86 GetCommunicatorAggregator(communicatorAggregator);
87 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
88 return E_OK;
89 }
90
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)91 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
92 {
93 outAggregator = nullptr;
94 std::lock_guard<std::mutex> lock(communicatorLock_);
95 if (communicatorAggregator_ != nullptr) {
96 outAggregator = communicatorAggregator_;
97 return E_OK;
98 }
99
100 if (adapter_ == nullptr) {
101 LOGE("Adapter has not set!");
102 return -E_NOT_INIT;
103 }
104
105 communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
106 if (communicatorAggregator_ == nullptr) {
107 LOGE("CommunicatorAggregator create failed, may be no available memory!");
108 return -E_OUT_OF_MEMORY;
109 }
110
111 int errCode = communicatorAggregator_->Initialize(adapter_);
112 if (errCode != E_OK) {
113 LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
114 RefObject::KillAndDecObjRef(communicatorAggregator_);
115 communicatorAggregator_ = nullptr;
116 }
117 outAggregator = communicatorAggregator_;
118 return errCode;
119 }
120
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)121 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
122 {
123 std::lock_guard<std::mutex> autoLock(communicatorLock_);
124 if (communicatorAggregator_ != nullptr) {
125 autoLaunch_.SetCommunicatorAggregator(nullptr);
126 communicatorAggregator_->Finalize();
127 RefObject::KillAndDecObjRef(communicatorAggregator_);
128 }
129 communicatorAggregator_ = inAggregator;
130 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
131 }
132
GetLocalIdentity(std::string & outTarget)133 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
134 {
135 std::lock_guard<std::mutex> autoLock(communicatorLock_);
136 if (communicatorAggregator_ != nullptr) {
137 return communicatorAggregator_->GetLocalIdentity(outTarget);
138 }
139 return -E_NOT_INIT;
140 }
141
142 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)143 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
144 const TimerFinalizer &finalizer, TimerId &timerId)
145 {
146 timerId = 0;
147 if ((milliSeconds < 0) || !action) {
148 return -E_INVALID_ARGS;
149 }
150
151 IEventLoop *loop = nullptr;
152 int errCode = PrepareLoop(loop);
153 if (errCode != E_OK) {
154 LOGE("SetTimer(), prepare loop failed.");
155 return errCode;
156 }
157
158 IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
159 if (evTimer == nullptr) {
160 loop->DecObjRef(loop);
161 loop = nullptr;
162 return errCode;
163 }
164
165 errCode = AllocTimerId(evTimer, timerId);
166 if (errCode != E_OK) {
167 evTimer->DecObjRef(evTimer);
168 evTimer = nullptr;
169 loop->DecObjRef(loop);
170 loop = nullptr;
171 return errCode;
172 }
173
174 evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
175 int errCodeInner = action(timerId);
176 if (errCodeInner != E_OK) {
177 RemoveTimer(timerId, false);
178 }
179 return errCodeInner;
180 },
181 finalizer);
182
183 errCode = loop->Add(evTimer);
184 if (errCode != E_OK) {
185 evTimer->IgnoreFinalizer();
186 RemoveTimer(timerId, false);
187 timerId = 0;
188 }
189
190 loop->DecObjRef(loop);
191 loop = nullptr;
192 return errCode;
193 }
194
195 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)196 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
197 {
198 if (milliSeconds < 0) {
199 return -E_INVALID_ARGS;
200 }
201
202 std::lock_guard<std::mutex> autoLock(timersLock_);
203 auto iter = timers_.find(timerId);
204 if (iter == timers_.end()) {
205 return -E_NO_SUCH_ENTRY;
206 }
207
208 IEvent *evTimer = iter->second;
209 if (evTimer == nullptr) {
210 return -E_INTERNAL_ERROR;
211 }
212 return evTimer->SetTimeout(milliSeconds);
213 }
214
215 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)216 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
217 {
218 IEvent *evTimer = nullptr;
219 {
220 std::lock_guard<std::mutex> autoLock(timersLock_);
221 auto iter = timers_.find(timerId);
222 if (iter == timers_.end()) {
223 return;
224 }
225 evTimer = iter->second;
226 timers_.erase(iter);
227 }
228
229 if (evTimer != nullptr) {
230 evTimer->Detach(wait);
231 evTimer->DecObjRef(evTimer);
232 evTimer = nullptr;
233 }
234 }
235
236 // Task interfaces.
ScheduleTask(const TaskAction & task)237 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
238 {
239 std::lock_guard<std::mutex> autoLock(taskLock_);
240 int errCode = PrepareTaskPool();
241 if (errCode != E_OK) {
242 LOGE("Schedule task failed, fail to prepare task pool.");
243 return errCode;
244 }
245 return taskPool_->Schedule(task);
246 }
247
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)248 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
249 const TaskAction &task)
250 {
251 std::lock_guard<std::mutex> autoLock(taskLock_);
252 int errCode = PrepareTaskPool();
253 if (errCode != E_OK) {
254 LOGE("Schedule queued task failed, fail to prepare task pool.");
255 return errCode;
256 }
257 return taskPool_->Schedule(queueTag, task);
258 }
259
ShrinkMemory(const std::string & description)260 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
261 {
262 std::lock_guard<std::mutex> autoLock(taskLock_);
263 if (taskPool_ != nullptr) {
264 taskPool_->ShrinkMemory(description);
265 }
266 }
267
RegisterTimeChangedLister(const TimeChangedAction & action,int & errCode)268 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
269 int &errCode)
270 {
271 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
272 if (timeTickMonitor_ == nullptr) {
273 timeTickMonitor_ = std::make_unique<TimeTickMonitor>();
274 errCode = timeTickMonitor_->Start();
275 if (errCode != E_OK) {
276 LOGE("TimeTickMonitor start failed!");
277 timeTickMonitor_ = nullptr;
278 return nullptr;
279 }
280 }
281 return timeTickMonitor_->RegisterTimeChangedLister(action, errCode);
282 }
283
PrepareLoop(IEventLoop * & loop)284 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
285 {
286 std::lock_guard<std::mutex> autoLock(loopLock_);
287 if (mainLoop_ != nullptr) {
288 loop = mainLoop_;
289 loop->IncObjRef(loop); // ref 1 returned to caller.
290 return E_OK;
291 }
292
293 int errCode = E_OK;
294 loop = IEventLoop::CreateEventLoop(errCode);
295 if (loop == nullptr) {
296 return errCode;
297 }
298
299 loop->IncObjRef(loop); // ref 1 owned by thread.
300 std::thread loopThread([loop]() {
301 loop->Run();
302 loop->DecObjRef(loop); // ref 1 dropped by thread.
303 });
304 loopThread.detach();
305
306 mainLoop_ = loop;
307 loop->IncObjRef(loop); // ref 1 returned to caller.
308 return E_OK;
309 }
310
PrepareTaskPool()311 int RuntimeContextImpl::PrepareTaskPool()
312 {
313 if (taskPool_ != nullptr) {
314 return E_OK;
315 }
316
317 int errCode = E_OK;
318 TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
319 if (taskPool == nullptr) {
320 return errCode;
321 }
322
323 errCode = taskPool->Start();
324 if (errCode != E_OK) {
325 taskPool->Release(taskPool);
326 return errCode;
327 }
328
329 taskPool_ = taskPool;
330 return E_OK;
331 }
332
AllocTimerId(IEvent * evTimer,TimerId & timerId)333 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
334 {
335 if (evTimer == nullptr) {
336 return -E_INVALID_ARGS;
337 }
338
339 std::lock_guard<std::mutex> autoLock(timersLock_);
340 TimerId startId = currentTimerId_;
341 while (++currentTimerId_ != startId) {
342 if (currentTimerId_ == 0) {
343 continue;
344 }
345 if (timers_.find(currentTimerId_) == timers_.end()) {
346 timerId = currentTimerId_;
347 timers_[timerId] = evTimer;
348 return E_OK;
349 }
350 }
351 return -E_OUT_OF_IDS;
352 }
353
SetPermissionCheckCallback(const PermissionCheckCallback & callback)354 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
355 {
356 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
357 permissionCheckCallback_ = callback;
358 LOGI("SetPermissionCheckCallback ok");
359 return E_OK;
360 }
361
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)362 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
363 {
364 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
365 permissionCheckCallbackV2_ = callback;
366 LOGI("SetPermissionCheckCallback V2 ok");
367 return E_OK;
368 }
369
RunPermissionCheck(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,uint8_t flag) const370 int RuntimeContextImpl::RunPermissionCheck(const std::string &userId, const std::string &appId,
371 const std::string &storeId, const std::string &deviceId, uint8_t flag) const
372 {
373 bool checkResult = false;
374 std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
375 if (permissionCheckCallbackV2_) {
376 checkResult = permissionCheckCallbackV2_(userId, appId, storeId, deviceId, flag);
377 if (checkResult) {
378 return E_OK;
379 } else {
380 return -E_NOT_PERMIT;
381 }
382 } else if (permissionCheckCallback_) {
383 checkResult = permissionCheckCallback_(userId, appId, storeId, flag);
384 if (checkResult) {
385 return E_OK;
386 } else {
387 return -E_NOT_PERMIT;
388 }
389 } else {
390 return E_OK;
391 }
392 }
393
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)394 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
395 const AutoLaunchOption &option)
396 {
397 return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
398 }
399
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)400 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
401 const std::string &dualTupleIdentifier, const std::string &userId)
402 {
403 return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
404 }
405
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const406 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
407 std::vector<std::string> &devices) const
408 {
409 return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
410 }
411
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBType type)412 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBType type)
413 {
414 autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
415 }
416
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)417 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
418 int &errCode)
419 {
420 std::lock(lockStatusLock_, systemApiAdapterLock_);
421 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
422 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
423 if (lockStatusObserver_ == nullptr) {
424 lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
425 if (lockStatusObserver_ == nullptr) {
426 LOGE("lockStatusObserver_ is nullptr");
427 errCode = -E_OUT_OF_MEMORY;
428 return nullptr;
429 }
430 }
431
432 if (!lockStatusObserver_->IsStarted()) {
433 errCode = lockStatusObserver_->Start();
434 if (errCode != E_OK) {
435 LOGE("lockStatusObserver start failed, err = %d", errCode);
436 delete lockStatusObserver_;
437 lockStatusObserver_ = nullptr;
438 return nullptr;
439 }
440
441 if (systemApiAdapter_ != nullptr) {
442 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
443 lockStatusObserver_, std::placeholders::_1);
444 errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
445 if (errCode != OK) {
446 LOGE("Register access control event change failed, err = %d", errCode);
447 delete lockStatusObserver_;
448 lockStatusObserver_ = nullptr;
449 return nullptr;
450 }
451 }
452 }
453
454 NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
455 if ((listener == nullptr) || (errCode != E_OK)) {
456 LOGE("Register lock status changed listener failed, err = %d", errCode);
457 delete lockStatusObserver_;
458 lockStatusObserver_ = nullptr;
459 return nullptr;
460 }
461 return listener;
462 }
463
IsAccessControlled() const464 bool RuntimeContextImpl::IsAccessControlled() const
465 {
466 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
467 if (systemApiAdapter_ == nullptr) {
468 return false;
469 }
470 return systemApiAdapter_->IsAccessControlled();
471 }
472
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const473 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
474 {
475 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
476 if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
477 LOGI("Adapter is not set, or path not existed, not support set security option!");
478 return -E_NOT_SUPPORT;
479 }
480
481 if (option == SecurityOption()) {
482 LOGD("SecurityOption is NOT_SET,Not need to set security option!");
483 return E_OK;
484 }
485
486 std::string fileRealPath;
487 int errCode = OS::GetRealPath(filePath, fileRealPath);
488 if (errCode != E_OK) {
489 LOGE("Get real path failed when set security option!");
490 return errCode;
491 }
492
493 errCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
494 if (errCode != OK) {
495 if (errCode == NOT_SUPPORT) {
496 return -E_NOT_SUPPORT;
497 }
498 LOGE("SetSecurityOption failed, errCode = %d", errCode);
499 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
500 }
501 return E_OK;
502 }
503
GetSecurityOption(const std::string & filePath,SecurityOption & option) const504 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
505 {
506 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
507 if (systemApiAdapter_ == nullptr) {
508 LOGI("Get Security option, but not set system api adapter!");
509 return -E_NOT_SUPPORT;
510 }
511 int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
512 if (errCode != OK) {
513 if (errCode == NOT_SUPPORT) {
514 return -E_NOT_SUPPORT;
515 }
516 LOGE("GetSecurityOption failed, errCode = %d", errCode);
517 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
518 }
519
520 LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
521 // This interface may return success but failed to obtain the flag and modified it to -1
522 if (option.securityFlag == INVALID_SEC_FLAG) {
523 // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
524 if (option.securityLabel == S3) {
525 LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
526 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
527 }
528 option.securityFlag = 0; // 0 is default value
529 }
530 return E_OK;
531 }
532
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const533 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
534 {
535 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
536 if (systemApiAdapter_ == nullptr) {
537 return true;
538 }
539 return systemApiAdapter_->CheckDeviceSecurityAbility(devId, option);
540 }
541
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)542 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
543 {
544 std::lock(lockStatusLock_, systemApiAdapterLock_);
545 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
546 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
547 systemApiAdapter_ = adapter;
548 if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
549 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
550 lockStatusObserver_, std::placeholders::_1);
551 int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
552 if (errCode != OK) {
553 LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
554 delete lockStatusObserver_;
555 lockStatusObserver_ = nullptr;
556 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
557 }
558 }
559 return E_OK;
560 }
561
IsProcessSystemApiAdapterValid() const562 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
563 {
564 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
565 if (systemApiAdapter_ == nullptr) {
566 return false;
567 }
568 return true;
569 }
570
NotifyTimeStampChanged(TimeOffset offset) const571 void RuntimeContextImpl::NotifyTimeStampChanged(TimeOffset offset) const
572 {
573 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
574 if (timeTickMonitor_ == nullptr) {
575 LOGD("NotifyTimeStampChanged fail, timeTickMonitor_ is null.");
576 return;
577 }
578 timeTickMonitor_->NotifyTimeChange(offset);
579 }
580
IsCommunicatorAggregatorValid() const581 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
582 {
583 std::lock_guard<std::mutex> autoLock(communicatorLock_);
584 if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
585 return false;
586 }
587 return true;
588 }
589
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)590 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier)
591 {
592 std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
593 databaseStatusNotifyCallback_ = notifier;
594 LOGI("SetStoreStatusNotifier ok");
595 }
596
NotifyDatabaseStatusChange(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,bool onlineStatus)597 void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId,
598 const std::string &storeId, const std::string &deviceId, bool onlineStatus)
599 {
600 ScheduleTask([this, userId, appId, storeId, deviceId, onlineStatus] {
601 std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
602 if (databaseStatusNotifyCallback_) {
603 LOGI("start notify database status:%d", onlineStatus);
604 databaseStatusNotifyCallback_(userId, appId, storeId, deviceId, onlineStatus);
605 }
606 });
607 }
608
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)609 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
610 {
611 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
612 syncActivationCheckCallback_ = callback;
613 LOGI("SetSyncActivationCheckCallback ok");
614 return E_OK;
615 }
616
IsSyncerNeedActive(std::string & userId,std::string & appId,std::string & storeId) const617 bool RuntimeContextImpl::IsSyncerNeedActive(std::string &userId, std::string &appId, std::string &storeId) const
618 {
619 std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
620 if (syncActivationCheckCallback_) {
621 return syncActivationCheckCallback_(userId, appId, storeId);
622 }
623 return true;
624 }
625
RegisterUserChangedListerner(const UserChangedAction & action,EventType event)626 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListerner(const UserChangedAction &action,
627 EventType event)
628 {
629 int errCode;
630 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
631 if (userChangeMonitor_ == nullptr) {
632 userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
633 errCode = userChangeMonitor_->Start();
634 if (errCode != E_OK) {
635 LOGE("UserChangeMonitor start failed!");
636 userChangeMonitor_ = nullptr;
637 return nullptr;
638 }
639 }
640 NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListerner(action, event, errCode);
641 if ((listener == nullptr) || (errCode != E_OK)) {
642 LOGE("Register user status changed listener failed, err = %d", errCode);
643 return nullptr;
644 }
645 return listener;
646 }
647
NotifyUserChanged() const648 int RuntimeContextImpl::NotifyUserChanged() const
649 {
650 {
651 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
652 if (userChangeMonitor_ == nullptr) {
653 LOGD("userChangeMonitor is null, all db is in normal sync mode");
654 return E_OK;
655 }
656 }
657 userChangeMonitor_->NotifyUserChanged();
658 return E_OK;
659 }
660 } // namespace DistributedDB
661