• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &notifier)
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