• 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_common.h"
18 #include "db_errno.h"
19 #include "db_dfx_adapter.h"
20 #include "log_print.h"
21 #include "communicator_aggregator.h"
22 #include "network_adapter.h"
23 
24 namespace DistributedDB {
RuntimeContextImpl()25 RuntimeContextImpl::RuntimeContextImpl()
26     : adapter_(nullptr),
27       communicatorAggregator_(nullptr),
28       mainLoop_(nullptr),
29       currentTimerId_(0),
30       taskPool_(nullptr),
31       taskPoolReportsTimerId_(0),
32       timeTickMonitor_(nullptr),
33       systemApiAdapter_(nullptr),
34       lockStatusObserver_(nullptr),
35       currentSessionId_(1)
36 {
37 }
38 
39 // Destruct the object.
~RuntimeContextImpl()40 RuntimeContextImpl::~RuntimeContextImpl()
41 {
42     if (taskPoolReportsTimerId_ > 0) {
43         RemoveTimer(taskPoolReportsTimerId_, true);
44         taskPoolReportsTimerId_ = 0;
45     }
46     if (taskPool_ != nullptr) {
47         taskPool_->Stop();
48         taskPool_->Release(taskPool_);
49         taskPool_ = nullptr;
50     }
51     if (mainLoop_ != nullptr) {
52         mainLoop_->Stop();
53         mainLoop_->KillAndDecObjRef(mainLoop_);
54         mainLoop_ = nullptr;
55     }
56     SetCommunicatorAggregator(nullptr);
57     (void)SetCommunicatorAdapter(nullptr);
58     systemApiAdapter_ = nullptr;
59     delete lockStatusObserver_;
60     lockStatusObserver_ = nullptr;
61     userChangeMonitor_ = nullptr;
62     SetThreadPool(nullptr);
63 }
64 
65 // Set the label of this process.
SetProcessLabel(const std::string & label)66 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
67 {
68     std::lock_guard<std::mutex> labelLock(labelMutex_);
69     processLabel_ = label;
70 }
71 
GetProcessLabel() const72 std::string RuntimeContextImpl::GetProcessLabel() const
73 {
74     std::lock_guard<std::mutex> labelLock(labelMutex_);
75     return processLabel_;
76 }
77 
SetCommunicatorAdapter(IAdapter * adapter)78 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
79 {
80     {
81         std::lock_guard<std::mutex> autoLock(communicatorLock_);
82         if (adapter_ != nullptr) {
83             if (communicatorAggregator_ != nullptr) {
84                 return -E_NOT_SUPPORT;
85             }
86             delete adapter_;
87         }
88         adapter_ = adapter;
89     }
90     ICommunicatorAggregator *communicatorAggregator = nullptr;
91     GetCommunicatorAggregator(communicatorAggregator);
92     autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
93     return E_OK;
94 }
95 
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)96 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
97 {
98     outAggregator = nullptr;
99     std::lock_guard<std::mutex> lock(communicatorLock_);
100     if (communicatorAggregator_ != nullptr) {
101         outAggregator = communicatorAggregator_;
102         return E_OK;
103     }
104 
105     if (adapter_ == nullptr) {
106         LOGE("Adapter has not set!");
107         return -E_NOT_INIT;
108     }
109 
110     communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
111     if (communicatorAggregator_ == nullptr) {
112         LOGE("CommunicatorAggregator create failed, may be no available memory!");
113         return -E_OUT_OF_MEMORY;
114     }
115 
116     int errCode = communicatorAggregator_->Initialize(adapter_);
117     if (errCode != E_OK) {
118         LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
119         RefObject::KillAndDecObjRef(communicatorAggregator_);
120         communicatorAggregator_ = nullptr;
121     }
122     outAggregator = communicatorAggregator_;
123     return errCode;
124 }
125 
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)126 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
127 {
128     std::lock_guard<std::mutex> autoLock(communicatorLock_);
129     if (communicatorAggregator_ != nullptr) {
130         autoLaunch_.SetCommunicatorAggregator(nullptr);
131         communicatorAggregator_->Finalize();
132         RefObject::KillAndDecObjRef(communicatorAggregator_);
133     }
134     communicatorAggregator_ = inAggregator;
135     autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
136 }
137 
GetLocalIdentity(std::string & outTarget)138 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
139 {
140     std::lock_guard<std::mutex> autoLock(communicatorLock_);
141     if (communicatorAggregator_ != nullptr) {
142         return communicatorAggregator_->GetLocalIdentity(outTarget);
143     }
144     return -E_NOT_INIT;
145 }
146 
147 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)148 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
149     const TimerFinalizer &finalizer, TimerId &timerId)
150 {
151     timerId = 0;
152     if ((milliSeconds < 0) || !action) {
153         return -E_INVALID_ARGS;
154     }
155     int errCode = SetTimerByThreadPool(milliSeconds, action, finalizer, true, timerId);
156     if (errCode != -E_NOT_SUPPORT) {
157         return errCode;
158     }
159     IEventLoop *loop = nullptr;
160     errCode = PrepareLoop(loop);
161     if (errCode != E_OK) {
162         LOGE("SetTimer(), prepare loop failed.");
163         return errCode;
164     }
165 
166     IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
167     if (evTimer == nullptr) {
168         loop->DecObjRef(loop);
169         loop = nullptr;
170         return errCode;
171     }
172 
173     errCode = AllocTimerId(evTimer, timerId);
174     if (errCode != E_OK) {
175         evTimer->DecObjRef(evTimer);
176         evTimer = nullptr;
177         loop->DecObjRef(loop);
178         loop = nullptr;
179         return errCode;
180     }
181 
182     evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
183             int errCodeInner = action(timerId);
184             if (errCodeInner != E_OK) {
185                 RemoveTimer(timerId, false);
186             }
187             return errCodeInner;
188         },
189         finalizer);
190 
191     errCode = loop->Add(evTimer);
192     if (errCode != E_OK) {
193         evTimer->IgnoreFinalizer();
194         RemoveTimer(timerId, false);
195         timerId = 0;
196     }
197 
198     loop->DecObjRef(loop);
199     loop = nullptr;
200     return errCode;
201 }
202 
203 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)204 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
205 {
206     if (milliSeconds < 0) {
207         return -E_INVALID_ARGS;
208     }
209     int errCode = ModifyTimerByThreadPool(timerId, milliSeconds);
210     if (errCode != -E_NOT_SUPPORT) {
211         return errCode;
212     }
213     std::lock_guard<std::mutex> autoLock(timersLock_);
214     auto iter = timers_.find(timerId);
215     if (iter == timers_.end()) {
216         return -E_NO_SUCH_ENTRY;
217     }
218 
219     IEvent *evTimer = iter->second;
220     if (evTimer == nullptr) {
221         return -E_INTERNAL_ERROR;
222     }
223     return evTimer->SetTimeout(milliSeconds);
224 }
225 
226 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)227 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
228 {
229     RemoveTimerByThreadPool(timerId, wait);
230     IEvent *evTimer = nullptr;
231     {
232         std::lock_guard<std::mutex> autoLock(timersLock_);
233         auto iter = timers_.find(timerId);
234         if (iter == timers_.end()) {
235             return;
236         }
237         evTimer = iter->second;
238         timers_.erase(iter);
239     }
240 
241     if (evTimer != nullptr) {
242         evTimer->Detach(wait);
243         evTimer->DecObjRef(evTimer);
244         evTimer = nullptr;
245     }
246 }
247 
248 // Task interfaces.
ScheduleTask(const TaskAction & task)249 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
250 {
251     if (ScheduleTaskByThreadPool(task) == E_OK) {
252         return E_OK;
253     }
254     std::lock_guard<std::mutex> autoLock(taskLock_);
255     int errCode = PrepareTaskPool();
256     if (errCode != E_OK) {
257         LOGE("Schedule task failed, fail to prepare task pool.");
258         return errCode;
259     }
260     return taskPool_->Schedule(task);
261 }
262 
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)263 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
264     const TaskAction &task)
265 {
266     if (ScheduleTaskByThreadPool(task) == E_OK) {
267         return E_OK;
268     }
269     std::lock_guard<std::mutex> autoLock(taskLock_);
270     int errCode = PrepareTaskPool();
271     if (errCode != E_OK) {
272         LOGE("Schedule queued task failed, fail to prepare task pool.");
273         return errCode;
274     }
275     return taskPool_->Schedule(queueTag, task);
276 }
277 
ShrinkMemory(const std::string & description)278 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
279 {
280     std::lock_guard<std::mutex> autoLock(taskLock_);
281     if (taskPool_ != nullptr) {
282         taskPool_->ShrinkMemory(description);
283     }
284 }
285 
RegisterTimeChangedLister(const TimeChangedAction & action,const TimeFinalizeAction & finalize,int & errCode)286 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
287     const TimeFinalizeAction &finalize, int &errCode)
288 {
289     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
290     if (timeTickMonitor_ == nullptr) {
291         timeTickMonitor_ = std::make_unique<TimeTickMonitor>();
292         errCode = timeTickMonitor_->StartTimeTickMonitor();
293         if (errCode != E_OK) {
294             LOGE("TimeTickMonitor start failed!");
295             timeTickMonitor_ = nullptr;
296             return nullptr;
297         }
298         LOGD("[RuntimeContext] TimeTickMonitor start success");
299     }
300     LOGD("[RuntimeContext] call RegisterTimeChangedLister");
301     return timeTickMonitor_->RegisterTimeChangedLister(action, finalize, errCode);
302 }
303 
PrepareLoop(IEventLoop * & loop)304 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
305 {
306     std::lock_guard<std::mutex> autoLock(loopLock_);
307     if (mainLoop_ != nullptr) {
308         loop = mainLoop_;
309         loop->IncObjRef(loop); // ref 1 returned to caller.
310         return E_OK;
311     }
312 
313     int errCode = E_OK;
314     loop = IEventLoop::CreateEventLoop(errCode);
315     if (loop == nullptr) {
316         return errCode;
317     }
318 
319     loop->IncObjRef(loop); // ref 1 owned by thread.
320     std::thread loopThread([loop]() {
321             loop->Run();
322             loop->DecObjRef(loop); // ref 1 dropped by thread.
323         });
324     loopThread.detach();
325 
326     mainLoop_ = loop;
327     loop->IncObjRef(loop); // ref 1 returned to caller.
328     return E_OK;
329 }
330 
PrepareTaskPool()331 int RuntimeContextImpl::PrepareTaskPool()
332 {
333     if (taskPool_ != nullptr) {
334         return E_OK;
335     }
336 
337     int errCode = E_OK;
338     TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
339     if (taskPool == nullptr) {
340         return errCode;
341     }
342 
343     errCode = taskPool->Start();
344     if (errCode != E_OK) {
345         taskPool->Release(taskPool);
346         return errCode;
347     }
348 
349     taskPool_ = taskPool;
350     return E_OK;
351 }
352 
AllocTimerId(IEvent * evTimer,TimerId & timerId)353 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
354 {
355     std::lock_guard<std::mutex> autoLock(timersLock_);
356     TimerId startId = currentTimerId_;
357     while (++currentTimerId_ != startId) {
358         if (currentTimerId_ == 0) {
359             continue;
360         }
361         if (timers_.find(currentTimerId_) == timers_.end()) {
362             timerId = currentTimerId_;
363             timers_[timerId] = evTimer;
364             return E_OK;
365         }
366     }
367     return -E_OUT_OF_IDS;
368 }
369 
SetPermissionCheckCallback(const PermissionCheckCallback & callback)370 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
371 {
372     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
373     permissionCheckCallback_ = callback;
374     LOGI("SetPermissionCheckCallback ok");
375     return E_OK;
376 }
377 
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)378 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
379 {
380     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
381     permissionCheckCallbackV2_ = callback;
382     LOGI("SetPermissionCheckCallback V2 ok");
383     return E_OK;
384 }
385 
SetPermissionCheckCallback(const PermissionCheckCallbackV3 & callback)386 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV3 &callback)
387 {
388     std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
389     permissionCheckCallbackV3_ = callback;
390     LOGI("SetPermissionCheckCallback V3 ok");
391     return E_OK;
392 }
393 
RunPermissionCheck(const PermissionCheckParam & param,uint8_t flag) const394 int RuntimeContextImpl::RunPermissionCheck(const PermissionCheckParam &param, uint8_t flag) const
395 {
396     bool checkResult = false;
397     std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
398     if (permissionCheckCallbackV3_) {
399         checkResult = permissionCheckCallbackV3_(param, flag);
400     } else if (permissionCheckCallbackV2_) {
401         checkResult = permissionCheckCallbackV2_(param.userId, param.appId, param.storeId, param.deviceId, flag);
402     } else if (permissionCheckCallback_) {
403         checkResult = permissionCheckCallback_(param.userId, param.appId, param.storeId, flag);
404     } else {
405         return E_OK;
406     }
407     if (checkResult) {
408         return E_OK;
409     }
410     return -E_NOT_PERMIT;
411 }
412 
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)413 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
414     const AutoLaunchOption &option)
415 {
416     return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
417 }
418 
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)419 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
420     const std::string &dualTupleIdentifier, const std::string &userId)
421 {
422     return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
423 }
424 
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const425 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
426     std::vector<std::string> &devices) const
427 {
428     return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
429 }
430 
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBTypeInner type)431 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBTypeInner type)
432 {
433     autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
434 }
435 
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)436 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
437     int &errCode)
438 {
439     std::lock(lockStatusLock_, systemApiAdapterLock_);
440     std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
441     std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
442     if (lockStatusObserver_ == nullptr) {
443         lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
444         if (lockStatusObserver_ == nullptr) {
445             LOGE("lockStatusObserver_ is nullptr");
446             errCode = -E_OUT_OF_MEMORY;
447             return nullptr;
448         }
449     }
450 
451     if (!lockStatusObserver_->IsStarted()) {
452         errCode = lockStatusObserver_->Start();
453         if (errCode != E_OK) {
454             LOGE("lockStatusObserver start failed, err = %d", errCode);
455             delete lockStatusObserver_;
456             lockStatusObserver_ = nullptr;
457             return nullptr;
458         }
459 
460         if (systemApiAdapter_ != nullptr) {
461             auto callback = std::bind(&LockStatusObserver::OnStatusChange,
462                 lockStatusObserver_, std::placeholders::_1);
463             errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
464             if (errCode != OK) {
465                 LOGE("Register access control event change failed, err = %d", errCode);
466                 delete lockStatusObserver_;
467                 lockStatusObserver_ = nullptr;
468                 return nullptr;
469             }
470         }
471     }
472 
473     NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
474     if ((listener == nullptr) || (errCode != E_OK)) {
475         LOGE("Register lock status changed listener failed, err = %d", errCode);
476         delete lockStatusObserver_;
477         lockStatusObserver_ = nullptr;
478         return nullptr;
479     }
480     return listener;
481 }
482 
IsAccessControlled() const483 bool RuntimeContextImpl::IsAccessControlled() const
484 {
485     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
486     if (systemApiAdapter_ == nullptr) {
487         return false;
488     }
489     return systemApiAdapter_->IsAccessControlled();
490 }
491 
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const492 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
493 {
494     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
495     if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
496         LOGI("Adapter is not set, or path not existed, not support set security option!");
497         return -E_NOT_SUPPORT;
498     }
499 
500     if (option == SecurityOption()) {
501         LOGD("SecurityOption is NOT_SET,Not need to set security option!");
502         return E_OK;
503     }
504 
505     std::string fileRealPath;
506     int errCode = OS::GetRealPath(filePath, fileRealPath);
507     if (errCode != E_OK) {
508         LOGE("Get real path failed when set security option!");
509         return errCode;
510     }
511 
512     errCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
513     if (errCode != OK) {
514         if (errCode == NOT_SUPPORT) {
515             return -E_NOT_SUPPORT;
516         }
517         LOGE("SetSecurityOption failed, errCode = %d", errCode);
518         return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
519     }
520     return E_OK;
521 }
522 
GetSecurityOption(const std::string & filePath,SecurityOption & option) const523 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
524 {
525     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
526     if (systemApiAdapter_ == nullptr) {
527         LOGI("Get Security option, but not set system api adapter!");
528         return -E_NOT_SUPPORT;
529     }
530     int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
531     if (errCode != OK) {
532         if (errCode == NOT_SUPPORT) {
533             return -E_NOT_SUPPORT;
534         }
535         LOGE("GetSecurityOption failed, errCode = %d", errCode);
536         return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
537     }
538 
539     LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
540     // This interface may return success but failed to obtain the flag and modified it to -1
541     if (option.securityFlag == INVALID_SEC_FLAG) {
542         // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
543         if (option.securityLabel == S3) {
544             LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
545             return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
546         }
547         option.securityFlag = 0; // 0 is default value
548     }
549     return E_OK;
550 }
551 
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const552 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
553 {
554     std::shared_ptr<IProcessSystemApiAdapter> tempSystemApiAdapter = nullptr;
555     {
556         std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
557         if (systemApiAdapter_ == nullptr) {
558             LOGI("[CheckDeviceSecurityAbility] security not set");
559             return true;
560         }
561         tempSystemApiAdapter = systemApiAdapter_;
562     }
563 
564     return tempSystemApiAdapter->CheckDeviceSecurityAbility(devId, option);
565 }
566 
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)567 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
568 {
569     std::lock(lockStatusLock_, systemApiAdapterLock_);
570     std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
571     std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
572     systemApiAdapter_ = adapter;
573     if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
574         auto callback = std::bind(&LockStatusObserver::OnStatusChange,
575             lockStatusObserver_, std::placeholders::_1);
576         int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
577         if (errCode != OK) {
578             LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
579             delete lockStatusObserver_;
580             lockStatusObserver_ = nullptr;
581             return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
582         }
583     }
584     return E_OK;
585 }
586 
IsProcessSystemApiAdapterValid() const587 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
588 {
589     std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
590     return (systemApiAdapter_ != nullptr);
591 }
592 
NotifyTimestampChanged(TimeOffset offset) const593 void RuntimeContextImpl::NotifyTimestampChanged(TimeOffset offset) const
594 {
595     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
596     if (timeTickMonitor_ == nullptr) {
597         LOGD("NotifyTimestampChanged fail, timeTickMonitor_ is null.");
598         return;
599     }
600     timeTickMonitor_->NotifyTimeChange(offset);
601 }
602 
IsCommunicatorAggregatorValid() const603 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
604 {
605     std::lock_guard<std::mutex> autoLock(communicatorLock_);
606     if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
607         return false;
608     }
609     return true;
610 }
611 
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)612 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier &notifier)
613 {
614     std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
615     databaseStatusNotifyCallback_ = notifier;
616     LOGI("SetStoreStatusNotifier ok");
617 }
618 
NotifyDatabaseStatusChange(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,bool onlineStatus)619 void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId,
620     const std::string &storeId, const std::string &deviceId, bool onlineStatus)
621 {
622     ScheduleTask([this, userId, appId, storeId, deviceId, onlineStatus] {
623         std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
624         if (databaseStatusNotifyCallback_) {
625             LOGI("start notify database status:%d", onlineStatus);
626             databaseStatusNotifyCallback_(userId, appId, storeId, deviceId, onlineStatus);
627         }
628     });
629 }
630 
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)631 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
632 {
633     std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
634     syncActivationCheckCallback_ = callback;
635     LOGI("SetSyncActivationCheckCallback ok");
636     return E_OK;
637 }
638 
SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 & callback)639 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 &callback)
640 {
641     std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
642     syncActivationCheckCallbackV2_ = callback;
643     LOGI("SetSyncActivationCheckCallbackV2 ok");
644     return E_OK;
645 }
646 
IsSyncerNeedActive(const DBProperties & properties) const647 bool RuntimeContextImpl::IsSyncerNeedActive(const DBProperties &properties) const
648 {
649     ActivationCheckParam param = {
650         properties.GetStringProp(DBProperties::USER_ID, ""),
651         properties.GetStringProp(DBProperties::APP_ID, ""),
652         properties.GetStringProp(DBProperties::STORE_ID, ""),
653         properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
654     };
655     std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
656     if (syncActivationCheckCallbackV2_) {
657         return syncActivationCheckCallbackV2_(param);
658     } else if (syncActivationCheckCallback_) {
659         return syncActivationCheckCallback_(param.userId, param.appId, param.storeId);
660     }
661     return true;
662 }
663 
RegisterUserChangedListener(const UserChangedAction & action,EventType event)664 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListener(const UserChangedAction &action,
665     EventType event)
666 {
667     int errCode;
668     std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
669     if (userChangeMonitor_ == nullptr) {
670         userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
671         errCode = userChangeMonitor_->Start();
672         if (errCode != E_OK) {
673             LOGE("UserChangeMonitor start failed!");
674             userChangeMonitor_ = nullptr;
675             return nullptr;
676         }
677     }
678     NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListener(action, event, errCode);
679     if ((listener == nullptr) || (errCode != E_OK)) {
680         LOGE("Register user status changed listener failed, err = %d", errCode);
681         return nullptr;
682     }
683     return listener;
684 }
685 
NotifyUserChanged() const686 int RuntimeContextImpl::NotifyUserChanged() const
687 {
688     {
689         std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
690         if (userChangeMonitor_ == nullptr) {
691             LOGD("userChangeMonitor is null, all db is in normal sync mode");
692             return E_OK;
693         }
694     }
695     userChangeMonitor_->NotifyUserChanged();
696     return E_OK;
697 }
698 
GenerateSessionId()699 uint32_t RuntimeContextImpl::GenerateSessionId()
700 {
701     uint32_t sessionId = currentSessionId_++;
702     if (sessionId == 0) {
703         sessionId = currentSessionId_++;
704     }
705     return sessionId;
706 }
707 
DumpCommonInfo(int fd)708 void RuntimeContextImpl::DumpCommonInfo(int fd)
709 {
710     autoLaunch_.Dump(fd);
711 }
712 
CloseAutoLaunchConnection(DBTypeInner type,const DBProperties & properties)713 void RuntimeContextImpl::CloseAutoLaunchConnection(DBTypeInner type, const DBProperties &properties)
714 {
715     autoLaunch_.CloseConnection(type, properties);
716 }
717 
SetPermissionConditionCallback(const PermissionConditionCallback & callback)718 int RuntimeContextImpl::SetPermissionConditionCallback(const PermissionConditionCallback &callback)
719 {
720     std::unique_lock<std::shared_mutex> autoLock(permissionConditionLock_);
721     permissionConditionCallback_ = callback;
722     return E_OK;
723 }
724 
GetPermissionCheckParam(const DBProperties & properties)725 std::map<std::string, std::string> RuntimeContextImpl::GetPermissionCheckParam(const DBProperties &properties)
726 {
727     PermissionConditionParam param = {
728         properties.GetStringProp(DBProperties::USER_ID, ""),
729         properties.GetStringProp(DBProperties::APP_ID, ""),
730         properties.GetStringProp(DBProperties::STORE_ID, ""),
731         properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
732     };
733     std::shared_lock<std::shared_mutex> autoLock(permissionConditionLock_);
734     if (permissionConditionCallback_ == nullptr) {
735         return {};
736     }
737     return permissionConditionCallback_(param);
738 }
739 
StopTaskPool()740 void RuntimeContextImpl::StopTaskPool()
741 {
742     std::lock_guard<std::mutex> autoLock(taskLock_);
743     if (taskPool_ != nullptr) {
744         taskPool_->Stop();
745         TaskPool::Release(taskPool_);
746         taskPool_ = nullptr;
747     }
748 }
749 
StopTimeTickMonitorIfNeed()750 void RuntimeContextImpl::StopTimeTickMonitorIfNeed()
751 {
752     std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
753     if (timeTickMonitor_ == nullptr) {
754         return;
755     }
756     if (timeTickMonitor_->EmptyListener()) {
757         LOGD("[RuntimeContext] TimeTickMonitor exist because no listener");
758         timeTickMonitor_ = nullptr;
759     }
760     LOGD("[RuntimeContext] TimeTickMonitor can not stop because listener is not empty");
761 }
762 
SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback & callback)763 void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback)
764 {
765     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
766     translateToDeviceIdCallback_ = callback;
767     deviceIdCache_.clear();
768 }
769 
TranslateDeviceId(const std::string & deviceId,const StoreInfo & info,std::string & newDeviceId)770 int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId,
771     const StoreInfo &info, std::string &newDeviceId)
772 {
773     const std::string id = DBCommon::GenerateIdentifierId(info.storeId, info.appId, info.userId);
774     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
775     if (translateToDeviceIdCallback_ == nullptr) {
776         return -E_NOT_SUPPORT;
777     }
778     if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() ||
779         deviceIdCache_[deviceId].find(id) == deviceIdCache_[deviceId].end()) {
780         deviceIdCache_[deviceId][id] = translateToDeviceIdCallback_(deviceId, info);
781     }
782     newDeviceId = deviceIdCache_[deviceId][id];
783     return E_OK;
784 }
785 
ExistTranslateDevIdCallback() const786 bool RuntimeContextImpl::ExistTranslateDevIdCallback() const
787 {
788     std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
789     return translateToDeviceIdCallback_ != nullptr;
790 }
791 
SetThreadPool(const std::shared_ptr<IThreadPool> & threadPool)792 void RuntimeContextImpl::SetThreadPool(const std::shared_ptr<IThreadPool> &threadPool)
793 {
794     std::unique_lock<std::shared_mutex> writeLock(threadPoolLock_);
795     threadPool_ = threadPool;
796     LOGD("[RuntimeContext] Set thread pool finished");
797 }
798 
GetThreadPool() const799 std::shared_ptr<IThreadPool> RuntimeContextImpl::GetThreadPool() const
800 {
801     std::shared_lock<std::shared_mutex> readLock(threadPoolLock_);
802     return threadPool_;
803 }
804 
ScheduleTaskByThreadPool(const DistributedDB::TaskAction & task) const805 int RuntimeContextImpl::ScheduleTaskByThreadPool(const DistributedDB::TaskAction &task) const
806 {
807     std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
808     if (threadPool == nullptr) {
809         return -E_NOT_SUPPORT;
810     }
811     (void)threadPool->Execute(task);
812     return E_OK;
813 }
814 
SetTimerByThreadPool(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,bool allocTimerId,TimerId & timerId)815 int RuntimeContextImpl::SetTimerByThreadPool(int milliSeconds, const TimerAction &action,
816     const TimerFinalizer &finalizer, bool allocTimerId, TimerId &timerId)
817 {
818     std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
819     if (threadPool == nullptr) {
820         return -E_NOT_SUPPORT;
821     }
822     int errCode = E_OK;
823     if (allocTimerId) {
824         errCode = AllocTimerId(nullptr, timerId);
825     } else {
826         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
827         if (taskIds_.find(timerId) == taskIds_.end()) {
828             LOGD("[SetTimerByThreadPool] Timer has been remove");
829             return -E_NO_SUCH_ENTRY;
830         }
831     }
832     if (errCode != E_OK) {
833         return errCode;
834     }
835     std::lock_guard<std::mutex> autoLock(timerTaskLock_);
836     if (!allocTimerId && taskIds_.find(timerId) == taskIds_.end()) {
837         LOGD("[SetTimerByThreadPool] Timer has been remove");
838         return -E_NO_SUCH_ENTRY;
839     }
840     timerFinalizers_[timerId] = finalizer;
841     Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
842         std::chrono::milliseconds(milliSeconds));
843     TaskId taskId = threadPool->Execute([milliSeconds, action, timerId, this]() {
844         ThreadPoolTimerAction(milliSeconds, action, timerId);
845     }, duration);
846     taskIds_[timerId] = taskId;
847     return E_OK;
848 }
849 
ModifyTimerByThreadPool(TimerId timerId,int milliSeconds)850 int RuntimeContextImpl::ModifyTimerByThreadPool(TimerId timerId, int milliSeconds)
851 {
852     std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
853     if (threadPool == nullptr) {
854         return -E_NOT_SUPPORT;
855     }
856     TaskId taskId;
857     {
858         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
859         if (taskIds_.find(timerId) == taskIds_.end()) {
860             return -E_NO_SUCH_ENTRY;
861         }
862         taskId = taskIds_[timerId];
863     }
864     Duration duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(
865         std::chrono::milliseconds(milliSeconds));
866     TaskId ret = threadPool->Reset(taskId, duration);
867     if (ret != taskId) {
868         return -E_NO_SUCH_ENTRY;
869     }
870     return E_OK;
871 }
872 
RemoveTimerByThreadPool(TimerId timerId,bool wait)873 void RuntimeContextImpl::RemoveTimerByThreadPool(TimerId timerId, bool wait)
874 {
875     std::shared_ptr<IThreadPool> threadPool = GetThreadPool();
876     if (threadPool == nullptr) {
877         return;
878     }
879     TaskId taskId;
880     {
881         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
882         if (taskIds_.find(timerId) == taskIds_.end()) {
883             return;
884         }
885         taskId = taskIds_[timerId];
886         taskIds_.erase(timerId);
887     }
888     bool removeBeforeExecute = threadPool->Remove(taskId, wait);
889     TimerFinalizer timerFinalizer = nullptr;
890     if (removeBeforeExecute) {
891         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
892         timerFinalizer = timerFinalizers_[timerId];
893         timerFinalizers_.erase(timerId);
894     }
895     if (timerFinalizer) {
896         timerFinalizer();
897     }
898 }
899 
ThreadPoolTimerAction(int milliSeconds,const TimerAction & action,TimerId timerId)900 void RuntimeContextImpl::ThreadPoolTimerAction(int milliSeconds, const TimerAction &action, TimerId timerId)
901 {
902     TimerFinalizer timerFinalizer = nullptr;
903     bool timerExist = true;
904     {
905         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
906         if (timerFinalizers_.find(timerId) == timerFinalizers_.end()) {
907             LOGD("[ThreadPoolTimerAction] Timer has been finalize");
908             return;
909         }
910         timerFinalizer = timerFinalizers_[timerId];
911         timerFinalizers_.erase(timerId);
912         if (taskIds_.find(timerId) == taskIds_.end()) {
913             LOGD("[ThreadPoolTimerAction] Timer has been removed");
914             timerExist = false;
915         }
916     }
917     if (timerExist && action(timerId) == E_OK) {
918         // schedule task again
919         int errCode = SetTimerByThreadPool(milliSeconds, action, timerFinalizer, false, timerId);
920         if (errCode == E_OK) {
921             return;
922         }
923         LOGW("[RuntimeContext] create timer failed %d", errCode);
924     }
925     if (timerFinalizer) {
926         timerFinalizer();
927     }
928     {
929         std::lock_guard<std::mutex> autoLock(timerTaskLock_);
930         taskIds_.erase(timerId);
931     }
932     std::lock_guard<std::mutex> autoLock(timersLock_);
933     timers_.erase(timerId);
934 }
935 
SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> & dataTranslate)936 void RuntimeContextImpl::SetCloudTranslate(const std::shared_ptr<ICloudDataTranslate> &dataTranslate)
937 {
938     std::unique_lock<std::shared_mutex> autoLock(dataTranslateLock_);
939     dataTranslate_ = dataTranslate;
940 }
941 
AssetToBlob(const Asset & asset,std::vector<uint8_t> & blob)942 int RuntimeContextImpl::AssetToBlob(const Asset &asset, std::vector<uint8_t> &blob)
943 {
944     std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
945     if (dataTranslate_ == nullptr) {
946         return -E_NOT_INIT;
947     }
948     blob = dataTranslate_->AssetToBlob(asset);
949     return E_OK;
950 }
951 
AssetsToBlob(const Assets & assets,std::vector<uint8_t> & blob)952 int RuntimeContextImpl::AssetsToBlob(const Assets &assets, std::vector<uint8_t> &blob)
953 {
954     std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
955     if (dataTranslate_ == nullptr) {
956         return -E_NOT_INIT;
957     }
958     blob = dataTranslate_->AssetsToBlob(assets);
959     return E_OK;
960 }
961 
BlobToAsset(const std::vector<uint8_t> & blob,Asset & asset)962 int RuntimeContextImpl::BlobToAsset(const std::vector<uint8_t> &blob, Asset &asset)
963 {
964     std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
965     if (dataTranslate_ == nullptr) {
966         return -E_NOT_INIT;
967     }
968     asset = dataTranslate_->BlobToAsset(blob);
969     return E_OK;
970 }
971 
BlobToAssets(std::vector<uint8_t> & blob,Assets & assets)972 int RuntimeContextImpl::BlobToAssets(std::vector<uint8_t> &blob, Assets &assets)
973 {
974     std::shared_lock<std::shared_mutex> autoLock(dataTranslateLock_);
975     if (dataTranslate_ == nullptr) {
976         return -E_NOT_INIT;
977     }
978     assets = dataTranslate_->BlobToAssets(blob);
979     return E_OK;
980 }
981 } // namespace DistributedDB
982