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