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_->KillAndDecObjRef(mainLoop_);
53 mainLoop_ = nullptr;
54 }
55 SetCommunicatorAggregator(nullptr);
56 (void)SetCommunicatorAdapter(nullptr);
57 systemApiAdapter_ = nullptr;
58 delete lockStatusObserver_;
59 lockStatusObserver_ = nullptr;
60 userChangeMonitor_ = nullptr;
61 }
62
63 // Set the label of this process.
SetProcessLabel(const std::string & label)64 void RuntimeContextImpl::SetProcessLabel(const std::string &label)
65 {
66 std::lock_guard<std::mutex> labelLock(labelMutex_);
67 processLabel_ = label;
68 }
69
GetProcessLabel() const70 std::string RuntimeContextImpl::GetProcessLabel() const
71 {
72 std::lock_guard<std::mutex> labelLock(labelMutex_);
73 return processLabel_;
74 }
75
SetCommunicatorAdapter(IAdapter * adapter)76 int RuntimeContextImpl::SetCommunicatorAdapter(IAdapter *adapter)
77 {
78 {
79 std::lock_guard<std::mutex> autoLock(communicatorLock_);
80 if (adapter_ != nullptr) {
81 if (communicatorAggregator_ != nullptr) {
82 return -E_NOT_SUPPORT;
83 }
84 delete adapter_;
85 }
86 adapter_ = adapter;
87 }
88 ICommunicatorAggregator *communicatorAggregator = nullptr;
89 GetCommunicatorAggregator(communicatorAggregator);
90 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator);
91 return E_OK;
92 }
93
GetCommunicatorAggregator(ICommunicatorAggregator * & outAggregator)94 int RuntimeContextImpl::GetCommunicatorAggregator(ICommunicatorAggregator *&outAggregator)
95 {
96 outAggregator = nullptr;
97 std::lock_guard<std::mutex> lock(communicatorLock_);
98 if (communicatorAggregator_ != nullptr) {
99 outAggregator = communicatorAggregator_;
100 return E_OK;
101 }
102
103 if (adapter_ == nullptr) {
104 LOGE("Adapter has not set!");
105 return -E_NOT_INIT;
106 }
107
108 communicatorAggregator_ = new (std::nothrow) CommunicatorAggregator;
109 if (communicatorAggregator_ == nullptr) {
110 LOGE("CommunicatorAggregator create failed, may be no available memory!");
111 return -E_OUT_OF_MEMORY;
112 }
113
114 int errCode = communicatorAggregator_->Initialize(adapter_);
115 if (errCode != E_OK) {
116 LOGE("CommunicatorAggregator init failed, err = %d!", errCode);
117 RefObject::KillAndDecObjRef(communicatorAggregator_);
118 communicatorAggregator_ = nullptr;
119 }
120 outAggregator = communicatorAggregator_;
121 return errCode;
122 }
123
SetCommunicatorAggregator(ICommunicatorAggregator * inAggregator)124 void RuntimeContextImpl::SetCommunicatorAggregator(ICommunicatorAggregator *inAggregator)
125 {
126 std::lock_guard<std::mutex> autoLock(communicatorLock_);
127 if (communicatorAggregator_ != nullptr) {
128 autoLaunch_.SetCommunicatorAggregator(nullptr);
129 communicatorAggregator_->Finalize();
130 RefObject::KillAndDecObjRef(communicatorAggregator_);
131 }
132 communicatorAggregator_ = inAggregator;
133 autoLaunch_.SetCommunicatorAggregator(communicatorAggregator_);
134 }
135
GetLocalIdentity(std::string & outTarget)136 int RuntimeContextImpl::GetLocalIdentity(std::string &outTarget)
137 {
138 std::lock_guard<std::mutex> autoLock(communicatorLock_);
139 if (communicatorAggregator_ != nullptr) {
140 return communicatorAggregator_->GetLocalIdentity(outTarget);
141 }
142 return -E_NOT_INIT;
143 }
144
145 // Add and start a timer.
SetTimer(int milliSeconds,const TimerAction & action,const TimerFinalizer & finalizer,TimerId & timerId)146 int RuntimeContextImpl::SetTimer(int milliSeconds, const TimerAction &action,
147 const TimerFinalizer &finalizer, TimerId &timerId)
148 {
149 timerId = 0;
150 if ((milliSeconds < 0) || !action) {
151 return -E_INVALID_ARGS;
152 }
153
154 IEventLoop *loop = nullptr;
155 int errCode = PrepareLoop(loop);
156 if (errCode != E_OK) {
157 LOGE("SetTimer(), prepare loop failed.");
158 return errCode;
159 }
160
161 IEvent *evTimer = IEvent::CreateEvent(milliSeconds, errCode);
162 if (evTimer == nullptr) {
163 loop->DecObjRef(loop);
164 loop = nullptr;
165 return errCode;
166 }
167
168 errCode = AllocTimerId(evTimer, timerId);
169 if (errCode != E_OK) {
170 evTimer->DecObjRef(evTimer);
171 evTimer = nullptr;
172 loop->DecObjRef(loop);
173 loop = nullptr;
174 return errCode;
175 }
176
177 evTimer->SetAction([this, timerId, action](EventsMask revents) -> int {
178 int errCodeInner = action(timerId);
179 if (errCodeInner != E_OK) {
180 RemoveTimer(timerId, false);
181 }
182 return errCodeInner;
183 },
184 finalizer);
185
186 errCode = loop->Add(evTimer);
187 if (errCode != E_OK) {
188 evTimer->IgnoreFinalizer();
189 RemoveTimer(timerId, false);
190 timerId = 0;
191 }
192
193 loop->DecObjRef(loop);
194 loop = nullptr;
195 return errCode;
196 }
197
198 // Modify the interval of the timer.
ModifyTimer(TimerId timerId,int milliSeconds)199 int RuntimeContextImpl::ModifyTimer(TimerId timerId, int milliSeconds)
200 {
201 if (milliSeconds < 0) {
202 return -E_INVALID_ARGS;
203 }
204
205 std::lock_guard<std::mutex> autoLock(timersLock_);
206 auto iter = timers_.find(timerId);
207 if (iter == timers_.end()) {
208 return -E_NO_SUCH_ENTRY;
209 }
210
211 IEvent *evTimer = iter->second;
212 if (evTimer == nullptr) {
213 return -E_INTERNAL_ERROR;
214 }
215 return evTimer->SetTimeout(milliSeconds);
216 }
217
218 // Remove the timer.
RemoveTimer(TimerId timerId,bool wait)219 void RuntimeContextImpl::RemoveTimer(TimerId timerId, bool wait)
220 {
221 IEvent *evTimer = nullptr;
222 {
223 std::lock_guard<std::mutex> autoLock(timersLock_);
224 auto iter = timers_.find(timerId);
225 if (iter == timers_.end()) {
226 return;
227 }
228 evTimer = iter->second;
229 timers_.erase(iter);
230 }
231
232 if (evTimer != nullptr) {
233 evTimer->Detach(wait);
234 evTimer->DecObjRef(evTimer);
235 evTimer = nullptr;
236 }
237 }
238
239 // Task interfaces.
ScheduleTask(const TaskAction & task)240 int RuntimeContextImpl::ScheduleTask(const TaskAction &task)
241 {
242 std::lock_guard<std::mutex> autoLock(taskLock_);
243 int errCode = PrepareTaskPool();
244 if (errCode != E_OK) {
245 LOGE("Schedule task failed, fail to prepare task pool.");
246 return errCode;
247 }
248 return taskPool_->Schedule(task);
249 }
250
ScheduleQueuedTask(const std::string & queueTag,const TaskAction & task)251 int RuntimeContextImpl::ScheduleQueuedTask(const std::string &queueTag,
252 const TaskAction &task)
253 {
254 std::lock_guard<std::mutex> autoLock(taskLock_);
255 int errCode = PrepareTaskPool();
256 if (errCode != E_OK) {
257 LOGE("Schedule queued task failed, fail to prepare task pool.");
258 return errCode;
259 }
260 return taskPool_->Schedule(queueTag, task);
261 }
262
ShrinkMemory(const std::string & description)263 void RuntimeContextImpl::ShrinkMemory(const std::string &description)
264 {
265 std::lock_guard<std::mutex> autoLock(taskLock_);
266 if (taskPool_ != nullptr) {
267 taskPool_->ShrinkMemory(description);
268 }
269 }
270
RegisterTimeChangedLister(const TimeChangedAction & action,int & errCode)271 NotificationChain::Listener *RuntimeContextImpl::RegisterTimeChangedLister(const TimeChangedAction &action,
272 int &errCode)
273 {
274 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
275 if (timeTickMonitor_ == nullptr) {
276 timeTickMonitor_ = std::make_unique<TimeTickMonitor>();
277 errCode = timeTickMonitor_->StartTimeTickMonitor();
278 if (errCode != E_OK) {
279 LOGE("TimeTickMonitor start failed!");
280 timeTickMonitor_ = nullptr;
281 return nullptr;
282 }
283 LOGD("[RuntimeContext] TimeTickMonitor start success");
284 }
285 return timeTickMonitor_->RegisterTimeChangedLister(action, errCode);
286 }
287
PrepareLoop(IEventLoop * & loop)288 int RuntimeContextImpl::PrepareLoop(IEventLoop *&loop)
289 {
290 std::lock_guard<std::mutex> autoLock(loopLock_);
291 if (mainLoop_ != nullptr) {
292 loop = mainLoop_;
293 loop->IncObjRef(loop); // ref 1 returned to caller.
294 return E_OK;
295 }
296
297 int errCode = E_OK;
298 loop = IEventLoop::CreateEventLoop(errCode);
299 if (loop == nullptr) {
300 return errCode;
301 }
302
303 loop->IncObjRef(loop); // ref 1 owned by thread.
304 std::thread loopThread([loop]() {
305 loop->Run();
306 loop->DecObjRef(loop); // ref 1 dropped by thread.
307 });
308 loopThread.detach();
309
310 mainLoop_ = loop;
311 loop->IncObjRef(loop); // ref 1 returned to caller.
312 return E_OK;
313 }
314
PrepareTaskPool()315 int RuntimeContextImpl::PrepareTaskPool()
316 {
317 if (taskPool_ != nullptr) {
318 return E_OK;
319 }
320
321 int errCode = E_OK;
322 TaskPool *taskPool = TaskPool::Create(MAX_TP_THREADS, MIN_TP_THREADS, errCode);
323 if (taskPool == nullptr) {
324 return errCode;
325 }
326
327 errCode = taskPool->Start();
328 if (errCode != E_OK) {
329 taskPool->Release(taskPool);
330 return errCode;
331 }
332
333 taskPool_ = taskPool;
334 return E_OK;
335 }
336
AllocTimerId(IEvent * evTimer,TimerId & timerId)337 int RuntimeContextImpl::AllocTimerId(IEvent *evTimer, TimerId &timerId)
338 {
339 if (evTimer == nullptr) {
340 return -E_INVALID_ARGS;
341 }
342
343 std::lock_guard<std::mutex> autoLock(timersLock_);
344 TimerId startId = currentTimerId_;
345 while (++currentTimerId_ != startId) {
346 if (currentTimerId_ == 0) {
347 continue;
348 }
349 if (timers_.find(currentTimerId_) == timers_.end()) {
350 timerId = currentTimerId_;
351 timers_[timerId] = evTimer;
352 return E_OK;
353 }
354 }
355 return -E_OUT_OF_IDS;
356 }
357
SetPermissionCheckCallback(const PermissionCheckCallback & callback)358 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
359 {
360 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
361 permissionCheckCallback_ = callback;
362 LOGI("SetPermissionCheckCallback ok");
363 return E_OK;
364 }
365
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)366 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
367 {
368 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
369 permissionCheckCallbackV2_ = callback;
370 LOGI("SetPermissionCheckCallback V2 ok");
371 return E_OK;
372 }
373
SetPermissionCheckCallback(const PermissionCheckCallbackV3 & callback)374 int RuntimeContextImpl::SetPermissionCheckCallback(const PermissionCheckCallbackV3 &callback)
375 {
376 std::unique_lock<std::shared_mutex> writeLock(permissionCheckCallbackMutex_);
377 permissionCheckCallbackV3_ = callback;
378 LOGI("SetPermissionCheckCallback V3 ok");
379 return E_OK;
380 }
381
RunPermissionCheck(const PermissionCheckParam & param,uint8_t flag) const382 int RuntimeContextImpl::RunPermissionCheck(const PermissionCheckParam ¶m, uint8_t flag) const
383 {
384 bool checkResult = false;
385 std::shared_lock<std::shared_mutex> autoLock(permissionCheckCallbackMutex_);
386 if (permissionCheckCallbackV3_) {
387 checkResult = permissionCheckCallbackV3_(param, flag);
388 } else if (permissionCheckCallbackV2_) {
389 checkResult = permissionCheckCallbackV2_(param.userId, param.appId, param.storeId, param.deviceId, flag);
390 } else if (permissionCheckCallback_) {
391 checkResult = permissionCheckCallback_(param.userId, param.appId, param.storeId, flag);
392 } else {
393 return E_OK;
394 }
395 if (checkResult) {
396 return E_OK;
397 } else {
398 return -E_NOT_PERMIT;
399 }
400 }
401
EnableKvStoreAutoLaunch(const KvDBProperties & properties,AutoLaunchNotifier notifier,const AutoLaunchOption & option)402 int RuntimeContextImpl::EnableKvStoreAutoLaunch(const KvDBProperties &properties, AutoLaunchNotifier notifier,
403 const AutoLaunchOption &option)
404 {
405 return autoLaunch_.EnableKvStoreAutoLaunch(properties, notifier, option);
406 }
407
DisableKvStoreAutoLaunch(const std::string & normalIdentifier,const std::string & dualTupleIdentifier,const std::string & userId)408 int RuntimeContextImpl::DisableKvStoreAutoLaunch(const std::string &normalIdentifier,
409 const std::string &dualTupleIdentifier, const std::string &userId)
410 {
411 return autoLaunch_.DisableKvStoreAutoLaunch(normalIdentifier, dualTupleIdentifier, userId);
412 }
413
GetAutoLaunchSyncDevices(const std::string & identifier,std::vector<std::string> & devices) const414 void RuntimeContextImpl::GetAutoLaunchSyncDevices(const std::string &identifier,
415 std::vector<std::string> &devices) const
416 {
417 return autoLaunch_.GetAutoLaunchSyncDevices(identifier, devices);
418 }
419
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback,DBType type)420 void RuntimeContextImpl::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback, DBType type)
421 {
422 autoLaunch_.SetAutoLaunchRequestCallback(callback, type);
423 }
424
RegisterLockStatusLister(const LockStatusNotifier & action,int & errCode)425 NotificationChain::Listener *RuntimeContextImpl::RegisterLockStatusLister(const LockStatusNotifier &action,
426 int &errCode)
427 {
428 std::lock(lockStatusLock_, systemApiAdapterLock_);
429 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
430 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
431 if (lockStatusObserver_ == nullptr) {
432 lockStatusObserver_ = new (std::nothrow) LockStatusObserver();
433 if (lockStatusObserver_ == nullptr) {
434 LOGE("lockStatusObserver_ is nullptr");
435 errCode = -E_OUT_OF_MEMORY;
436 return nullptr;
437 }
438 }
439
440 if (!lockStatusObserver_->IsStarted()) {
441 errCode = lockStatusObserver_->Start();
442 if (errCode != E_OK) {
443 LOGE("lockStatusObserver start failed, err = %d", errCode);
444 delete lockStatusObserver_;
445 lockStatusObserver_ = nullptr;
446 return nullptr;
447 }
448
449 if (systemApiAdapter_ != nullptr) {
450 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
451 lockStatusObserver_, std::placeholders::_1);
452 errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
453 if (errCode != OK) {
454 LOGE("Register access control event change failed, err = %d", errCode);
455 delete lockStatusObserver_;
456 lockStatusObserver_ = nullptr;
457 return nullptr;
458 }
459 }
460 }
461
462 NotificationChain::Listener *listener = lockStatusObserver_->RegisterLockStatusChangedLister(action, errCode);
463 if ((listener == nullptr) || (errCode != E_OK)) {
464 LOGE("Register lock status changed listener failed, err = %d", errCode);
465 delete lockStatusObserver_;
466 lockStatusObserver_ = nullptr;
467 return nullptr;
468 }
469 return listener;
470 }
471
IsAccessControlled() const472 bool RuntimeContextImpl::IsAccessControlled() const
473 {
474 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
475 if (systemApiAdapter_ == nullptr) {
476 return false;
477 }
478 return systemApiAdapter_->IsAccessControlled();
479 }
480
SetSecurityOption(const std::string & filePath,const SecurityOption & option) const481 int RuntimeContextImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option) const
482 {
483 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
484 if (systemApiAdapter_ == nullptr || !OS::CheckPathExistence(filePath)) {
485 LOGI("Adapter is not set, or path not existed, not support set security option!");
486 return -E_NOT_SUPPORT;
487 }
488
489 if (option == SecurityOption()) {
490 LOGD("SecurityOption is NOT_SET,Not need to set security option!");
491 return E_OK;
492 }
493
494 std::string fileRealPath;
495 int errCode = OS::GetRealPath(filePath, fileRealPath);
496 if (errCode != E_OK) {
497 LOGE("Get real path failed when set security option!");
498 return errCode;
499 }
500
501 errCode = systemApiAdapter_->SetSecurityOption(fileRealPath, option);
502 if (errCode != OK) {
503 if (errCode == NOT_SUPPORT) {
504 return -E_NOT_SUPPORT;
505 }
506 LOGE("SetSecurityOption failed, errCode = %d", errCode);
507 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
508 }
509 return E_OK;
510 }
511
GetSecurityOption(const std::string & filePath,SecurityOption & option) const512 int RuntimeContextImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
513 {
514 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
515 if (systemApiAdapter_ == nullptr) {
516 LOGI("Get Security option, but not set system api adapter!");
517 return -E_NOT_SUPPORT;
518 }
519 int errCode = systemApiAdapter_->GetSecurityOption(filePath, option);
520 if (errCode != OK) {
521 if (errCode == NOT_SUPPORT) {
522 return -E_NOT_SUPPORT;
523 }
524 LOGE("GetSecurityOption failed, errCode = %d", errCode);
525 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
526 }
527
528 LOGD("Get security option from system adapter [%d, %d]", option.securityLabel, option.securityFlag);
529 // This interface may return success but failed to obtain the flag and modified it to -1
530 if (option.securityFlag == INVALID_SEC_FLAG) {
531 // Currently ignoring the failure to obtain flags -1 other than S3, modify the flag to the default value
532 if (option.securityLabel == S3) {
533 LOGE("GetSecurityOption failed, SecurityOption is invalid [3, -1]!");
534 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
535 }
536 option.securityFlag = 0; // 0 is default value
537 }
538 return E_OK;
539 }
540
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const541 bool RuntimeContextImpl::CheckDeviceSecurityAbility(const std::string &devId, const SecurityOption &option) const
542 {
543 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
544 if (systemApiAdapter_ == nullptr) {
545 return true;
546 }
547 return systemApiAdapter_->CheckDeviceSecurityAbility(devId, option);
548 }
549
SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)550 int RuntimeContextImpl::SetProcessSystemApiAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
551 {
552 std::lock(lockStatusLock_, systemApiAdapterLock_);
553 std::lock_guard<std::mutex> lockStatusLock(lockStatusLock_, std::adopt_lock);
554 std::lock_guard<std::recursive_mutex> systemApiAdapterLock(systemApiAdapterLock_, std::adopt_lock);
555 systemApiAdapter_ = adapter;
556 if (systemApiAdapter_ != nullptr && lockStatusObserver_ != nullptr && lockStatusObserver_->IsStarted()) {
557 auto callback = std::bind(&LockStatusObserver::OnStatusChange,
558 lockStatusObserver_, std::placeholders::_1);
559 int errCode = systemApiAdapter_->RegOnAccessControlledEvent(callback);
560 if (errCode != OK) {
561 LOGE("Register access controlled event failed while setting adapter, err = %d", errCode);
562 delete lockStatusObserver_;
563 lockStatusObserver_ = nullptr;
564 return -E_SYSTEM_API_ADAPTER_CALL_FAILED;
565 }
566 }
567 return E_OK;
568 }
569
IsProcessSystemApiAdapterValid() const570 bool RuntimeContextImpl::IsProcessSystemApiAdapterValid() const
571 {
572 std::lock_guard<std::recursive_mutex> autoLock(systemApiAdapterLock_);
573 return (systemApiAdapter_ != nullptr);
574 }
575
NotifyTimestampChanged(TimeOffset offset) const576 void RuntimeContextImpl::NotifyTimestampChanged(TimeOffset offset) const
577 {
578 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
579 if (timeTickMonitor_ == nullptr) {
580 LOGD("NotifyTimestampChanged fail, timeTickMonitor_ is null.");
581 return;
582 }
583 timeTickMonitor_->NotifyTimeChange(offset);
584 }
585
IsCommunicatorAggregatorValid() const586 bool RuntimeContextImpl::IsCommunicatorAggregatorValid() const
587 {
588 std::lock_guard<std::mutex> autoLock(communicatorLock_);
589 if (communicatorAggregator_ == nullptr && adapter_ == nullptr) {
590 return false;
591 }
592 return true;
593 }
594
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)595 void RuntimeContextImpl::SetStoreStatusNotifier(const StoreStatusNotifier ¬ifier)
596 {
597 std::unique_lock<std::shared_mutex> writeLock(databaseStatusCallbackMutex_);
598 databaseStatusNotifyCallback_ = notifier;
599 LOGI("SetStoreStatusNotifier ok");
600 }
601
NotifyDatabaseStatusChange(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,bool onlineStatus)602 void RuntimeContextImpl::NotifyDatabaseStatusChange(const std::string &userId, const std::string &appId,
603 const std::string &storeId, const std::string &deviceId, bool onlineStatus)
604 {
605 ScheduleTask([this, userId, appId, storeId, deviceId, onlineStatus] {
606 std::shared_lock<std::shared_mutex> autoLock(databaseStatusCallbackMutex_);
607 if (databaseStatusNotifyCallback_) {
608 LOGI("start notify database status:%d", onlineStatus);
609 databaseStatusNotifyCallback_(userId, appId, storeId, deviceId, onlineStatus);
610 }
611 });
612 }
613
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)614 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
615 {
616 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
617 syncActivationCheckCallback_ = callback;
618 LOGI("SetSyncActivationCheckCallback ok");
619 return E_OK;
620 }
621
SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 & callback)622 int RuntimeContextImpl::SetSyncActivationCheckCallback(const SyncActivationCheckCallbackV2 &callback)
623 {
624 std::unique_lock<std::shared_mutex> writeLock(syncActivationCheckCallbackMutex_);
625 syncActivationCheckCallbackV2_ = callback;
626 LOGI("SetSyncActivationCheckCallbackV2 ok");
627 return E_OK;
628 }
629
IsSyncerNeedActive(const DBProperties & properties) const630 bool RuntimeContextImpl::IsSyncerNeedActive(const DBProperties &properties) const
631 {
632 ActivationCheckParam param = {
633 properties.GetStringProp(DBProperties::USER_ID, ""),
634 properties.GetStringProp(DBProperties::APP_ID, ""),
635 properties.GetStringProp(DBProperties::STORE_ID, ""),
636 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
637 };
638 std::shared_lock<std::shared_mutex> autoLock(syncActivationCheckCallbackMutex_);
639 if (syncActivationCheckCallbackV2_) {
640 return syncActivationCheckCallbackV2_(param);
641 } else if (syncActivationCheckCallback_) {
642 return syncActivationCheckCallback_(param.userId, param.appId, param.storeId);
643 }
644 return true;
645 }
646
RegisterUserChangedListener(const UserChangedAction & action,EventType event)647 NotificationChain::Listener *RuntimeContextImpl::RegisterUserChangedListener(const UserChangedAction &action,
648 EventType event)
649 {
650 int errCode;
651 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
652 if (userChangeMonitor_ == nullptr) {
653 userChangeMonitor_ = std::make_unique<UserChangeMonitor>();
654 errCode = userChangeMonitor_->Start();
655 if (errCode != E_OK) {
656 LOGE("UserChangeMonitor start failed!");
657 userChangeMonitor_ = nullptr;
658 return nullptr;
659 }
660 }
661 NotificationChain::Listener *listener = userChangeMonitor_->RegisterUserChangedListener(action, event, errCode);
662 if ((listener == nullptr) || (errCode != E_OK)) {
663 LOGE("Register user status changed listener failed, err = %d", errCode);
664 return nullptr;
665 }
666 return listener;
667 }
668
NotifyUserChanged() const669 int RuntimeContextImpl::NotifyUserChanged() const
670 {
671 {
672 std::lock_guard<std::mutex> autoLock(userChangeMonitorLock_);
673 if (userChangeMonitor_ == nullptr) {
674 LOGD("userChangeMonitor is null, all db is in normal sync mode");
675 return E_OK;
676 }
677 }
678 userChangeMonitor_->NotifyUserChanged();
679 return E_OK;
680 }
681
GenerateSessionId()682 uint32_t RuntimeContextImpl::GenerateSessionId()
683 {
684 uint32_t sessionId = currentSessionId_++;
685 if (sessionId == 0) {
686 sessionId = currentSessionId_++;
687 }
688 return sessionId;
689 }
690
DumpCommonInfo(int fd)691 void RuntimeContextImpl::DumpCommonInfo(int fd)
692 {
693 autoLaunch_.Dump(fd);
694 }
695
CloseAutoLaunchConnection(DBType type,const DBProperties & properties)696 void RuntimeContextImpl::CloseAutoLaunchConnection(DBType type, const DBProperties &properties)
697 {
698 autoLaunch_.CloseConnection(type, properties);
699 }
700
SetPermissionConditionCallback(const PermissionConditionCallback & callback)701 int RuntimeContextImpl::SetPermissionConditionCallback(const PermissionConditionCallback &callback)
702 {
703 std::unique_lock<std::shared_mutex> autoLock(permissionConditionLock_);
704 permissionConditionCallback_ = callback;
705 return E_OK;
706 }
707
GetPermissionCheckParam(const DBProperties & properties)708 std::map<std::string, std::string> RuntimeContextImpl::GetPermissionCheckParam(const DBProperties &properties)
709 {
710 PermissionConditionParam param = {
711 properties.GetStringProp(DBProperties::USER_ID, ""),
712 properties.GetStringProp(DBProperties::APP_ID, ""),
713 properties.GetStringProp(DBProperties::STORE_ID, ""),
714 properties.GetIntProp(DBProperties::INSTANCE_ID, 0)
715 };
716 std::shared_lock<std::shared_mutex> autoLock(permissionConditionLock_);
717 if (permissionConditionCallback_ == nullptr) {
718 return {};
719 }
720 return permissionConditionCallback_(param);
721 }
722
StopTaskPool()723 void RuntimeContextImpl::StopTaskPool()
724 {
725 std::lock_guard<std::mutex> autoLock(taskLock_);
726 if (taskPool_ != nullptr) {
727 taskPool_->Stop();
728 TaskPool::Release(taskPool_);
729 taskPool_ = nullptr;
730 }
731 }
732
StopTimeTickMonitorIfNeed()733 void RuntimeContextImpl::StopTimeTickMonitorIfNeed()
734 {
735 std::lock_guard<std::mutex> autoLock(timeTickMonitorLock_);
736 if (timeTickMonitor_ == nullptr) {
737 return;
738 }
739 if (timeTickMonitor_->EmptyListener()) {
740 LOGD("[RuntimeContext] TimeTickMonitor exist because no listener");
741 timeTickMonitor_ = nullptr;
742 }
743 }
744
SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback & callback)745 void RuntimeContextImpl::SetTranslateToDeviceIdCallback(const TranslateToDeviceIdCallback &callback)
746 {
747 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
748 translateToDeviceIdCallback_ = callback;
749 deviceIdCache_.clear();
750 }
751
TranslateDeviceId(const std::string & deviceId,const StoreInfo & info,std::string & newDeviceId)752 int RuntimeContextImpl::TranslateDeviceId(const std::string &deviceId,
753 const StoreInfo &info, std::string &newDeviceId)
754 {
755 const std::string id = DBCommon::GenerateIdentifierId(info.storeId, info.appId, info.userId);
756 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
757 if (translateToDeviceIdCallback_ == nullptr) {
758 return -E_NOT_SUPPORT;
759 }
760 if (deviceIdCache_.find(deviceId) == deviceIdCache_.end() ||
761 deviceIdCache_[deviceId].find(id) == deviceIdCache_[deviceId].end()) {
762 deviceIdCache_[deviceId][id] = translateToDeviceIdCallback_(deviceId, info);
763 }
764 newDeviceId = deviceIdCache_[deviceId][id];
765 return E_OK;
766 }
767
ExistTranslateDevIdCallback() const768 bool RuntimeContextImpl::ExistTranslateDevIdCallback() const
769 {
770 std::lock_guard<std::mutex> autoLock(translateToDeviceIdLock_);
771 return translateToDeviceIdCallback_ != nullptr;
772 }
773 } // namespace DistributedDB
774