• 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 #define LOG_TAG "KvStoreServiceDeathNotifier"
17 
18 #include "kvstore_service_death_notifier.h"
19 #include "if_system_ability_manager.h"
20 #include "ipc_skeleton.h"
21 #include "iservice_registry.h"
22 #include "kvstore_client_death_observer.h"
23 #include "datamgr_service_proxy.h"
24 #include "log_print.h"
25 #include "refbase.h"
26 #include "system_ability_definition.h"
27 #include "task_executor.h"
28 
29 namespace OHOS {
30 namespace DistributedKv {
31 
32 std::mutex KvStoreServiceDeathNotifier::instanceMutex_;
GetInstance()33 KvStoreServiceDeathNotifier& KvStoreServiceDeathNotifier::GetInstance()
34 {
35     static KvStoreServiceDeathNotifier instance;
36     return instance;
37 }
38 
SetAppId(const AppId & appId)39 void KvStoreServiceDeathNotifier::SetAppId(const AppId &appId)
40 {
41     auto &instance = GetInstance();
42     std::lock_guard<decltype(mutex_)> lg(instance.mutex_);
43     instance.appId_ = appId;
44 }
45 
GetAppId()46 AppId KvStoreServiceDeathNotifier::GetAppId()
47 {
48     auto &instance = GetInstance();
49     std::lock_guard<decltype(mutex_)> lg(instance.mutex_);
50     return instance.appId_;
51 }
52 
GetDistributedKvDataService()53 sptr<IKvStoreDataService> KvStoreServiceDeathNotifier::GetDistributedKvDataService()
54 {
55     ZLOGD("Begin.");
56     auto &instance = GetInstance();
57     std::lock_guard<std::mutex> lg(instance.watchMutex_);
58     if (instance.kvDataServiceProxy_ != nullptr) {
59         return instance.kvDataServiceProxy_;
60     }
61 
62     ZLOGI("Create remote proxy.");
63     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
64     if (samgr == nullptr) {
65         ZLOGE("Get samgr fail.");
66         return nullptr;
67     }
68 
69     auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
70     instance.kvDataServiceProxy_ = iface_cast<DataMgrServiceProxy>(remote);
71     if (instance.kvDataServiceProxy_ == nullptr) {
72         ZLOGE("Initialize proxy failed.");
73         return nullptr;
74     }
75 
76     if (instance.deathRecipientPtr_ == nullptr) {
77         instance.deathRecipientPtr_ = new (std::nothrow) ServiceDeathRecipient();
78         if (instance.deathRecipientPtr_ == nullptr) {
79             ZLOGW("New KvStoreDeathRecipient failed");
80             return nullptr;
81         }
82     }
83     if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(instance.deathRecipientPtr_))) {
84         ZLOGE("Failed to add death recipient.");
85     }
86 
87     instance.RegisterClientDeathObserver();
88 
89     return instance.kvDataServiceProxy_;
90 }
91 
RegisterClientDeathObserver()92 void KvStoreServiceDeathNotifier::RegisterClientDeathObserver()
93 {
94     if (kvDataServiceProxy_ == nullptr) {
95         return;
96     }
97     if (clientDeathObserverPtr_ == nullptr) {
98         clientDeathObserverPtr_ = new (std::nothrow) KvStoreClientDeathObserver();
99     }
100     if (clientDeathObserverPtr_ == nullptr) {
101         ZLOGW("New KvStoreClientDeathObserver failed");
102         return;
103     }
104     kvDataServiceProxy_->RegisterClientDeathObserver(GetAppId(), clientDeathObserverPtr_);
105 }
106 
AddServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)107 void KvStoreServiceDeathNotifier::AddServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)
108 {
109     auto &instance = GetInstance();
110     std::lock_guard<std::mutex> lg(instance.watchMutex_);
111     auto ret = instance.serviceDeathWatchers_.insert(std::move(watcher));
112     if (ret.second) {
113         ZLOGI("Success set size: %zu", instance.serviceDeathWatchers_.size());
114     } else {
115         ZLOGE("Failed set size: %zu", instance.serviceDeathWatchers_.size());
116     }
117 }
118 
RemoveServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)119 void KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)
120 {
121     auto &instance = GetInstance();
122     std::lock_guard<std::mutex> lg(instance.watchMutex_);
123     auto it = instance.serviceDeathWatchers_.find(std::move(watcher));
124     if (it != instance.serviceDeathWatchers_.end()) {
125         instance.serviceDeathWatchers_.erase(it);
126         ZLOGI("Find & erase set size: %zu", instance.serviceDeathWatchers_.size());
127     } else {
128         ZLOGE("No found set size: %zu", instance.serviceDeathWatchers_.size());
129     }
130 }
131 
OnRemoteDied(const wptr<IRemoteObject> & remote)132 void KvStoreServiceDeathNotifier::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
133 {
134     ZLOGW("DistributedDataMgrService died.");
135     auto &instance = GetInstance();
136     // Need to do this with the lock held
137     std::lock_guard<std::mutex> lg(instance.watchMutex_);
138     instance.kvDataServiceProxy_ = nullptr;
139     ZLOGI("Watcher set size: %zu", instance.serviceDeathWatchers_.size());
140     for (const auto &watcher : instance.serviceDeathWatchers_) {
141         if (watcher == nullptr) {
142             ZLOGI("This watcher is nullptr");
143             continue;
144         }
145         TaskExecutor::GetInstance().Execute([watcher] {
146             watcher->OnRemoteDied();
147         });
148     }
149 }
150 
ServiceDeathRecipient()151 KvStoreServiceDeathNotifier::ServiceDeathRecipient::ServiceDeathRecipient()
152 {
153     ZLOGI("Constructor.");
154 }
155 
~ServiceDeathRecipient()156 KvStoreServiceDeathNotifier::ServiceDeathRecipient::~ServiceDeathRecipient()
157 {
158     ZLOGI("Destructor.");
159 }
160 } // namespace DistributedKv
161 } // namespace OHOS
162