• 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 "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