• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 "dhfwk_sa_manager.h"
17 
18 #include <cinttypes>
19 
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22 
23 #include "constants.h"
24 #include "distributed_hardware_log.h"
25 #include "distributed_hardware_proxy.h"
26 #include "distributed_hardware_errno.h"
27 
28 namespace OHOS {
29 namespace DistributedHardware {
30 constexpr uint32_t MAX_TOPIC_SIZE = 128;
31 constexpr uint32_t MAX_LISTENER_SIZE = 256;
32 
33 IMPLEMENT_SINGLE_INSTANCE(DHFWKSAManager);
DHFWKSAManager()34 DHFWKSAManager::DHFWKSAManager()
35     : dhfwkOnLine_(false), isSubscribeDHFWKSAChangeListener_(false), dhfwkProxy_(nullptr),
36       saListener_(sptr<SystemAbilityListener>(new SystemAbilityListener())), saStateCallback_(nullptr),
37       publisherListenersCache_({}), avTransControlCenterCbCache_({})
38 {
39     DHLOGI("Ctor DHFWKSAManager");
40 }
~DHFWKSAManager()41 DHFWKSAManager::~DHFWKSAManager()
42 {
43     DHLOGI("Dtor DHFWKSAManager");
44     dhfwkOnLine_ = false;
45     isSubscribeDHFWKSAChangeListener_.store(false);
46     dhfwkProxy_ = nullptr;
47     saListener_ = nullptr;
48 }
49 
RegisterAbilityListener()50 void DHFWKSAManager::RegisterAbilityListener()
51 {
52     DHLOGI("Register DHFWK sa listener");
53     sptr<ISystemAbilityManager> saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
54     if (saMgr == nullptr) {
55         DHLOGE("Get System Ability Manager failed");
56         return;
57     }
58 
59     if (!isSubscribeDHFWKSAChangeListener_.load()) {
60         DHLOGI("try subscribe sa change listener, sa id: %{public}d", DISTRIBUTED_HARDWARE_SA_ID);
61         int32_t ret = saMgr->SubscribeSystemAbility(DISTRIBUTED_HARDWARE_SA_ID, saListener_);
62         if (ret != 0) {
63             DHLOGE("subscribe DHFWK sa change listener failed, ret: %{public}d", ret);
64             return;
65         }
66         isSubscribeDHFWKSAChangeListener_.store(true);
67     }
68 }
69 
GetDHFWKProxy()70 sptr<IDistributedHardware> DHFWKSAManager::GetDHFWKProxy()
71 {
72     if (!isSubscribeDHFWKSAChangeListener_.load()) {
73         RegisterAbilityListener();
74     }
75 
76     std::lock_guard<std::mutex> lock(proxyMutex_);
77     if (dhfwkProxy_ == nullptr) {
78         sptr<ISystemAbilityManager> saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
79         if (saMgr == nullptr) {
80             DHLOGE("Get System Ability Manager failed");
81             return nullptr;
82         }
83         DHLOGI("Try get DHFWK sa");
84         sptr<IRemoteObject> remoteObject = saMgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_SA_ID);
85         if (remoteObject == nullptr) {
86             DHLOGE("Get DHFWK proxy return null");
87             return nullptr;
88         }
89 
90         dhfwkProxy_ = iface_cast<IDistributedHardware>(remoteObject);
91         if (!dhfwkProxy_ || !dhfwkProxy_->AsObject()) {
92             DHLOGE("Failed to Get DHFWK Proxy");
93             return nullptr;
94         }
95     }
96 
97     return dhfwkProxy_;
98 }
99 
RegisterSAStateCallback(DHFWKSAStateCb callback)100 void DHFWKSAManager::RegisterSAStateCallback(DHFWKSAStateCb callback)
101 {
102     std::lock_guard<std::mutex> lock(saStatCbMutex_);
103     saStateCallback_ = callback;
104 }
105 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)106 void DHFWKSAManager::SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
107 {
108     (void)deviceId;
109     if (systemAbilityId != DISTRIBUTED_HARDWARE_SA_ID) {
110         DHLOGW("Receive SA Start, but sa id is not DHFWK, id: %{public}" PRId32, systemAbilityId);
111         return;
112     }
113 
114     DHFWKSAManager::GetInstance().dhfwkOnLine_ = true;
115     {
116         std::lock_guard<std::mutex> lock(DHFWKSAManager::GetInstance().saStatCbMutex_);
117         if (DHFWKSAManager::GetInstance().saStateCallback_ != nullptr) {
118             DHFWKSAManager::GetInstance().saStateCallback_(true);
119         }
120     }
121     if (DHFWKSAManager::GetInstance().RestoreListener() != DH_FWK_SUCCESS) {
122         DHLOGE("Partial listeners failed to restore");
123     }
124     DHLOGI("sa %{public}" PRId32 " started", systemAbilityId);
125 }
126 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)127 void DHFWKSAManager::SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
128 {
129     (void)deviceId;
130     if (systemAbilityId != DISTRIBUTED_HARDWARE_SA_ID) {
131         DHLOGW("Receive SA Stop, but sa id is not DHFWK, id: %{public}" PRId32, systemAbilityId);
132         return;
133     }
134 
135     DHFWKSAManager::GetInstance().dhfwkOnLine_ = false;
136     {
137         std::lock_guard<std::mutex> lock(DHFWKSAManager::GetInstance().proxyMutex_);
138         DHFWKSAManager::GetInstance().dhfwkProxy_ = nullptr;
139     }
140     {
141         std::lock_guard<std::mutex> lock(DHFWKSAManager::GetInstance().saStatCbMutex_);
142         if (DHFWKSAManager::GetInstance().saStateCallback_ != nullptr) {
143             DHFWKSAManager::GetInstance().saStateCallback_(false);
144         }
145     }
146     DHLOGI("sa %{public}" PRId32 " stopped", systemAbilityId);
147 }
148 
RestoreListener()149 int32_t DHFWKSAManager::RestoreListener()
150 {
151     DHLOGI("Restore the failed listeners due to sa crash");
152     if (DHFWKSAManager::GetInstance().GetDHFWKProxy() == nullptr) {
153         return ERR_DH_FWK_POINTER_IS_NULL;
154     }
155     int32_t ret = DH_FWK_SUCCESS;
156     {
157         std::lock_guard<std::mutex> publisherListenersLock(publisherListenersMutex_);
158         for (const auto &entry : publisherListenersCache_) {
159             for (const auto &listener : entry.second) {
160                 int32_t innerRet =
161                     DHFWKSAManager::GetInstance().GetDHFWKProxy()->RegisterPublisherListener(entry.first, listener);
162                 if (ret != DH_FWK_SUCCESS) {
163                     ret = innerRet;
164                     DHLOGE("Register publisher listener failed, topic: %{public}" PRIu32, (uint32_t)entry.first);
165                 }
166             }
167         }
168     }
169     {
170         std::lock_guard<std::mutex> avTransControlCenterCbLock(avTransControlCenterCbMutex_);
171         for (auto &entry : avTransControlCenterCbCache_) {
172             int32_t innerRet =
173                 DHFWKSAManager::GetInstance().GetDHFWKProxy()->RegisterCtlCenterCallback(entry.first, entry.second);
174             if (innerRet != DH_FWK_SUCCESS) {
175                 ret = innerRet;
176                 DHLOGE("Restore register av control center callback failed, engineId: %{public}" PRId32, entry.first);
177             }
178         }
179     }
180     return ret;
181 }
182 
AddPublisherListenerToCache(const DHTopic topic,sptr<IPublisherListener> listener)183 int32_t DHFWKSAManager::AddPublisherListenerToCache(const DHTopic topic, sptr<IPublisherListener> listener)
184 {
185     std::lock_guard<std::mutex> publisherListenersLock(publisherListenersMutex_);
186     if (publisherListenersCache_.size() >= MAX_TOPIC_SIZE ||
187         publisherListenersCache_[topic].size() >= MAX_LISTENER_SIZE) {
188         DHLOGE("listeners are over size!");
189         return ERR_DH_FWK_PUBLISH_LISTENER_OVER_SIZE;
190     }
191     publisherListenersCache_[topic].insert(listener);
192     return DH_FWK_SUCCESS;
193 }
194 
RemovePublisherListenerFromCache(const DHTopic topic,sptr<IPublisherListener> listener)195 void DHFWKSAManager::RemovePublisherListenerFromCache(const DHTopic topic, sptr<IPublisherListener> listener)
196 {
197     std::lock_guard<std::mutex> publisherListenersLock(publisherListenersMutex_);
198     if (publisherListenersCache_.find(topic) == publisherListenersCache_.end()) {
199         DHLOGE("Can not find the topic: %{public}u In publisherListenersCache_.", static_cast<uint32_t>(topic));
200         return;
201     }
202     publisherListenersCache_[topic].erase(listener);
203 }
204 
AddAVTransControlCenterCbToCache(int32_t engineId,const sptr<IAvTransControlCenterCallback> callback)205 void DHFWKSAManager::AddAVTransControlCenterCbToCache(int32_t engineId,
206     const sptr<IAvTransControlCenterCallback> callback)
207 {
208     std::lock_guard<std::mutex> avTransControlCenterCbLock(avTransControlCenterCbMutex_);
209     avTransControlCenterCbCache_[engineId] = callback;
210 }
211 
RemoveAVTransControlCenterCbFromCache(int32_t engineId)212 void DHFWKSAManager::RemoveAVTransControlCenterCbFromCache(int32_t engineId)
213 {
214     std::lock_guard<std::mutex> avTransControlCenterCbLock(avTransControlCenterCbMutex_);
215     avTransControlCenterCbCache_.erase(engineId);
216 }
217 } // DistributedHardware
218 } // OHOS