1 /*
2  * Copyright (c) 2022-2024 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 "connection_observer_client_impl.h"
17 
18 #include "connection_observer_errors.h"
19 #include "connection_observer_stub_impl.h"
20 #include "hilog_tag_wrapper.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23 
24 namespace OHOS {
25 namespace AbilityRuntime {
RegisterObserver(const std::shared_ptr<ConnectionObserver> & observer)26 int32_t ConnectionObserverClientImpl::RegisterObserver(const std::shared_ptr<ConnectionObserver> &observer)
27 {
28     if (!observer) {
29         TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
30         return ERR_INVALID_OBSERVER;
31     }
32 
33     auto proxy = GetServiceProxy();
34 
35     std::lock_guard<std::mutex> guard(observerLock_);
36     if (!RegisterObserverToServiceLocked(proxy)) {
37         TAG_LOGE(AAFwkTag::CONNECTION, "register failed");
38         return ERR_REGISTER_FAILED;
39     }
40 
41     return AddObserversLocked(observer);
42 }
43 
UnregisterObserver(const std::shared_ptr<ConnectionObserver> & observer)44 int32_t ConnectionObserverClientImpl::UnregisterObserver(const std::shared_ptr<ConnectionObserver> &observer)
45 {
46     if (!observer) {
47         TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
48         return ERR_INVALID_OBSERVER;
49     }
50 
51     auto proxy = GetServiceProxy();
52 
53     std::lock_guard<std::mutex> guard(observerLock_);
54     auto ret = RemoveObserversLocked(observer);
55     if (userObservers_.empty()) {
56         UnregisterFromServiceLocked(proxy);
57     }
58 
59     return ret;
60 }
61 
62 #ifdef WITH_DLP
GetDlpConnectionInfos(std::vector<DlpConnectionInfo> & infos)63 int32_t ConnectionObserverClientImpl::GetDlpConnectionInfos(std::vector<DlpConnectionInfo> &infos)
64 {
65     auto proxy = GetServiceProxy();
66     if (!proxy) {
67         TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
68         return ERR_NO_PROXY;
69     }
70 
71     return proxy->GetDlpConnectionInfos(infos);
72 }
73 #endif // WITH_DLP
74 
GetConnectionData(std::vector<ConnectionData> & connectionData)75 int32_t ConnectionObserverClientImpl::GetConnectionData(std::vector<ConnectionData> &connectionData)
76 {
77     auto proxy = GetServiceProxy();
78     if (!proxy) {
79         TAG_LOGE(AAFwkTag::CONNECTION, "invalid observer");
80         return ERR_NO_PROXY;
81     }
82 
83     return proxy->GetConnectionData(connectionData);
84 }
85 
HandleExtensionConnected(const ConnectionData & data)86 void ConnectionObserverClientImpl::HandleExtensionConnected(const ConnectionData &data)
87 {
88     auto observers = GetObservers();
89     for (auto it = observers.begin(); it != observers.end(); ++it) {
90         auto observer = *it;
91         if (observer) {
92             observer->OnExtensionConnected(data);
93         }
94     }
95 }
96 
HandleExtensionDisconnected(const ConnectionData & data)97 void ConnectionObserverClientImpl::HandleExtensionDisconnected(const ConnectionData &data)
98 {
99     auto observers = GetObservers();
100     for (auto it = observers.begin(); it != observers.end(); ++it) {
101         auto observer = *it;
102         if (observer) {
103             observer->OnExtensionDisconnected(data);
104         }
105     }
106 }
107 
108 #ifdef WITH_DLP
HandleDlpAbilityOpened(const DlpStateData & data)109 void ConnectionObserverClientImpl::HandleDlpAbilityOpened(const DlpStateData &data)
110 {
111     auto observers = GetObservers();
112     for (auto it = observers.begin(); it != observers.end(); ++it) {
113         auto observer = *it;
114         if (observer) {
115             observer->OnDlpAbilityOpened(data);
116         }
117     }
118 }
119 
HandleDlpAbilityClosed(const DlpStateData & data)120 void ConnectionObserverClientImpl::HandleDlpAbilityClosed(const DlpStateData &data)
121 {
122     auto observers = GetObservers();
123     for (auto it = observers.begin(); it != observers.end(); ++it) {
124         auto observer = *it;
125         if (observer) {
126             observer->OnDlpAbilityClosed(data);
127         }
128     }
129 }
130 #endif // WITH_DLP
131 
RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)132 bool ConnectionObserverClientImpl::RegisterObserverToServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
133 {
134     if (isRegistered_) {
135         return true;
136     }
137 
138     if (!proxy) {
139         TAG_LOGE(AAFwkTag::CONNECTION, "fail to get service");
140         return false;
141     }
142 
143     if (!observer_) {
144         observer_ = sptr<IConnectionObserver>(new (std::nothrow) ConnectionObserverStubImpl(shared_from_this()));
145     }
146 
147     if (proxy->RegisterObserver(observer_) != ERR_OK) {
148         TAG_LOGE(AAFwkTag::CONNECTION, "register observer failed");
149         return false;
150     }
151     isRegistered_ = true;
152     return true;
153 }
154 
UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> & proxy)155 void ConnectionObserverClientImpl::UnregisterFromServiceLocked(const std::shared_ptr<ServiceProxyAdapter> &proxy)
156 {
157     if (!isRegistered_ || !observer_) {
158         return;
159     }
160 
161     if (!proxy) {
162         return;
163     }
164 
165     if (proxy->UnregisterObserver(observer_) != ERR_OK) {
166         TAG_LOGE(AAFwkTag::CONNECTION, "unregister observer failed");
167         return;
168     }
169     isRegistered_ = false;
170 }
171 
AddObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)172 int32_t ConnectionObserverClientImpl::AddObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
173 {
174     if (userObservers_.find(observer) != userObservers_.end()) {
175         TAG_LOGE(AAFwkTag::CONNECTION, "observer already registered");
176         return ERR_OBSERVER_ALREADY_REGISTERED;
177     }
178     userObservers_.emplace(observer);
179     return ERR_OK;
180 }
181 
RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> & observer)182 int32_t ConnectionObserverClientImpl::RemoveObserversLocked(const std::shared_ptr<ConnectionObserver> &observer)
183 {
184     if (userObservers_.find(observer) == userObservers_.end()) {
185         TAG_LOGE(AAFwkTag::CONNECTION, "no such observer");
186         return ERR_OBSERVER_NOT_REGISTERED;
187     }
188     userObservers_.erase(observer);
189     return ERR_OK;
190 }
191 
GetServiceProxy()192 std::shared_ptr<ServiceProxyAdapter> ConnectionObserverClientImpl::GetServiceProxy()
193 {
194     std::lock_guard<std::mutex> guard(proxyLock_);
195     if (!serviceAdapter_) {
196         ConnectLocked();
197     }
198     return serviceAdapter_;
199 }
200 
ConnectLocked()201 void ConnectionObserverClientImpl::ConnectLocked()
202 {
203     if (serviceAdapter_ != nullptr) {
204         return;
205     }
206     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
207     if (systemManager == nullptr) {
208         TAG_LOGE(AAFwkTag::CONNECTION, "get system ability registry failed");
209         return;
210     }
211     sptr<IRemoteObject> remoteObj = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
212     if (remoteObj == nullptr) {
213         TAG_LOGE(AAFwkTag::CONNECTION, "connect AMS failed");
214         return;
215     }
216 
217     deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(
218         new (std::nothrow) ServiceDeathRecipient(shared_from_this()));
219     if (deathRecipient_ == nullptr) {
220         TAG_LOGE(AAFwkTag::CONNECTION, "create AbilityMgrDeathRecipient failed");
221         return;
222     }
223     if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(deathRecipient_))) {
224         TAG_LOGE(AAFwkTag::CONNECTION, "Add death recipient failed");
225         return;
226     }
227 
228     serviceAdapter_ = std::make_shared<ServiceProxyAdapter>(remoteObj);
229     TAG_LOGI(AAFwkTag::CONNECTION, "Connect AMS success");
230 }
231 
HandleRemoteDied(const wptr<IRemoteObject> & remote)232 void ConnectionObserverClientImpl::HandleRemoteDied(const wptr<IRemoteObject> &remote)
233 {
234     if (!ResetProxy(remote)) {
235         return;
236     }
237     NotifyServiceDiedToObservers();
238 }
239 
ResetProxy(const wptr<IRemoteObject> & remote)240 bool ConnectionObserverClientImpl::ResetProxy(const wptr<IRemoteObject> &remote)
241 {
242     std::lock_guard<std::mutex> guard(proxyLock_);
243     if (serviceAdapter_ == nullptr) {
244         return false;
245     }
246 
247     auto proxyObject = serviceAdapter_->GetProxyObject();
248     if ((proxyObject != nullptr) && (proxyObject == remote.promote())) {
249         proxyObject->RemoveDeathRecipient(deathRecipient_);
250         serviceAdapter_ = nullptr;
251         return true;
252     }
253 
254     return false;
255 }
256 
ResetStatus()257 void ConnectionObserverClientImpl::ResetStatus()
258 {
259     std::lock_guard<std::mutex> guard(observerLock_);
260     isRegistered_ = false;
261     userObservers_.clear();
262 }
263 
NotifyServiceDiedToObservers()264 void ConnectionObserverClientImpl::NotifyServiceDiedToObservers()
265 {
266     auto observers = GetObservers();
267     ResetStatus();
268     for (auto it = observers.begin(); it != observers.end(); ++it) {
269         auto observer = *it;
270         if (observer) {
271             observer->OnServiceDied();
272         }
273     }
274 }
275 
GetObservers()276 std::unordered_set<std::shared_ptr<ConnectionObserver>> ConnectionObserverClientImpl::GetObservers()
277 {
278     std::lock_guard<std::mutex> guard(observerLock_);
279     return userObservers_;
280 }
281 
OnRemoteDied(const wptr<IRemoteObject> & remote)282 void ConnectionObserverClientImpl::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
283 {
284     TAG_LOGI(AAFwkTag::CONNECTION, "called");
285     auto owner = owner_.lock();
286     if (!owner) {
287         TAG_LOGE(AAFwkTag::CONNECTION, "OnRemoteDied");
288         return;
289     }
290     owner->HandleRemoteDied(remote);
291 }
292 } // namespace AbilityRuntime
293 } // namespace OHOS
294