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 "log_print.h"
24 #include "refbase.h"
25 #include "system_ability_definition.h"
26 #include "task_executor.h"
27
28 namespace OHOS {
29 namespace DistributedKv {
30
31 std::mutex KvStoreServiceDeathNotifier::instanceMutex_;
32 KvStoreServiceDeathNotifier* KvStoreServiceDeathNotifier::instance_ = nullptr;
33
GetInstance()34 KvStoreServiceDeathNotifier* KvStoreServiceDeathNotifier::GetInstance()
35 {
36 if (instance_ == nullptr) {
37 std::lock_guard<std::mutex> lock(instanceMutex_);
38 if (instance_ == nullptr) {
39 instance_ = new (std::nothrow) KvStoreServiceDeathNotifier();
40 if (instance_ == nullptr) {
41 ZLOGE("KvStoreServiceDeathNotifier nullptr");
42 }
43 return instance_;
44 }
45 }
46 return instance_;
47 }
48
SetAppId(const AppId & appId)49 void KvStoreServiceDeathNotifier::SetAppId(const AppId &appId)
50 {
51 auto *instance = GetInstance();
52 if (instance == nullptr) {
53 return;
54 }
55 std::lock_guard<decltype(mutex_)> lg(instance->mutex_);
56 instance->appId_ = appId;
57 }
58
GetAppId()59 AppId KvStoreServiceDeathNotifier::GetAppId()
60 {
61 auto *instance = GetInstance();
62 if (instance == nullptr) {
63 return {};
64 }
65 std::lock_guard<decltype(mutex_)> lg(instance->mutex_);
66 return instance->appId_;
67 }
68
GetDistributedKvDataService()69 sptr<IKvStoreDataService> KvStoreServiceDeathNotifier::GetDistributedKvDataService()
70 {
71 ZLOGD("begin.");
72 auto *instance = GetInstance();
73 if (instance == nullptr) {
74 return nullptr;
75 }
76 std::lock_guard<std::mutex> lg(instance->watchMutex_);
77 if (instance->kvDataServiceProxy_ != nullptr) {
78 return instance->kvDataServiceProxy_;
79 }
80
81 ZLOGI("create remote proxy.");
82 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
83 if (samgr == nullptr) {
84 ZLOGE("get samgr fail.");
85 return nullptr;
86 }
87
88 auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
89 instance->kvDataServiceProxy_ = iface_cast<IKvStoreDataService>(remote);
90 if (instance->kvDataServiceProxy_ == nullptr) {
91 ZLOGE("initialize proxy failed.");
92 return nullptr;
93 }
94
95 if (instance->deathRecipientPtr_ == nullptr) {
96 instance->deathRecipientPtr_ = new (std::nothrow) ServiceDeathRecipient();
97 if (instance->deathRecipientPtr_ == nullptr) {
98 ZLOGW("new KvStoreDeathRecipient failed");
99 return nullptr;
100 }
101 }
102 if ((remote->IsProxyObject()) && (!remote->AddDeathRecipient(instance->deathRecipientPtr_))) {
103 ZLOGE("failed to add death recipient.");
104 }
105
106 instance->RegisterClientDeathObserver();
107
108 return instance->kvDataServiceProxy_;
109 }
110
RegisterClientDeathObserver()111 void KvStoreServiceDeathNotifier::RegisterClientDeathObserver()
112 {
113 if (kvDataServiceProxy_ == nullptr) {
114 return;
115 }
116 if (clientDeathObserverPtr_ == nullptr) {
117 clientDeathObserverPtr_ = new (std::nothrow) KvStoreClientDeathObserver();
118 }
119 if (clientDeathObserverPtr_ == nullptr) {
120 ZLOGW("new KvStoreClientDeathObserver failed");
121 return;
122 }
123 kvDataServiceProxy_->RegisterClientDeathObserver(GetAppId(), clientDeathObserverPtr_);
124 }
125
AddServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)126 void KvStoreServiceDeathNotifier::AddServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)
127 {
128 auto *instance = GetInstance();
129 if (instance == nullptr) {
130 return;
131 }
132 std::lock_guard<std::mutex> lg(instance->watchMutex_);
133 auto ret = instance->serviceDeathWatchers_.insert(std::move(watcher));
134 if (ret.second) {
135 ZLOGI("success set size: %zu", instance->serviceDeathWatchers_.size());
136 } else {
137 ZLOGE("failed set size: %zu", instance->serviceDeathWatchers_.size());
138 }
139 }
140
RemoveServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)141 void KvStoreServiceDeathNotifier::RemoveServiceDeathWatcher(std::shared_ptr<KvStoreDeathRecipient> watcher)
142 {
143 auto *instance = GetInstance();
144 if (instance == nullptr) {
145 return;
146 }
147 std::lock_guard<std::mutex> lg(instance->watchMutex_);
148 auto it = instance->serviceDeathWatchers_.find(std::move(watcher));
149 if (it != instance->serviceDeathWatchers_.end()) {
150 instance->serviceDeathWatchers_.erase(it);
151 ZLOGI("find & erase set size: %zu", instance->serviceDeathWatchers_.size());
152 } else {
153 ZLOGE("no found set size: %zu", instance->serviceDeathWatchers_.size());
154 }
155 }
156
OnRemoteDied(const wptr<IRemoteObject> & remote)157 void KvStoreServiceDeathNotifier::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
158 {
159 ZLOGW("DistributedDataMgrService died.");
160 auto *instance = GetInstance();
161 if (instance == nullptr) {
162 return;
163 }
164 // Need to do this with the lock held
165 std::lock_guard<std::mutex> lg(instance->watchMutex_);
166 instance->kvDataServiceProxy_ = nullptr;
167 ZLOGI("watcher set size: %zu", instance->serviceDeathWatchers_.size());
168 for (const auto &watcher : instance->serviceDeathWatchers_) {
169 if (watcher == nullptr) {
170 ZLOGI("watcher is nullptr");
171 continue;
172 }
173 TaskExecutor::GetInstance().Execute([watcher] {
174 watcher->OnRemoteDied();
175 });
176 }
177 }
178
ServiceDeathRecipient()179 KvStoreServiceDeathNotifier::ServiceDeathRecipient::ServiceDeathRecipient()
180 {
181 ZLOGI("constructor.");
182 }
183
~ServiceDeathRecipient()184 KvStoreServiceDeathNotifier::ServiceDeathRecipient::~ServiceDeathRecipient()
185 {
186 ZLOGI("destructor.");
187 }
188 } // namespace DistributedKv
189 } // namespace OHOS
190