• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "power_manager.h"
17 #include <cstring>
18 #include <list>
19 #include <map>
20 #include <mutex>
21 #include <string>
22 #include "adapter_manager.h"
23 #include "btm.h"
24 #include "log.h"
25 #include "log_util.h"
26 #include "power_device.h"
27 #include "timer.h"
28 
29 namespace OHOS {
30 namespace bluetooth {
31 // static function
32 static std::unique_ptr<PowerManager> g_powerManager = nullptr;
GetInstance()33 IPowerManager &IPowerManager::GetInstance()
34 {
35     return PowerManager::GetInstance();
36 }
Initialize(utility::Dispatcher & dispatcher)37 void IPowerManager::Initialize(utility::Dispatcher &dispatcher)
38 {
39     g_powerManager->Initialize(dispatcher);
40 }
41 
Uninitialize()42 void IPowerManager::Uninitialize()
43 {
44     g_powerManager->Uninitialize();
45 }
46 
GetInstance()47 PowerManager &PowerManager::GetInstance()
48 {
49     return *(g_powerManager.get());
50 }
51 
Initialize(utility::Dispatcher & dispatcher)52 void PowerManager::Initialize(utility::Dispatcher &dispatcher)
53 {
54     LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
55     if (g_powerManager == nullptr) {
56         g_powerManager = std::make_unique<PowerManager>(dispatcher);
57     }
58 }
59 
Uninitialize()60 void PowerManager::Uninitialize()
61 {
62     LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
63     g_powerManager = nullptr;
64 }
65 
66 /// PowerManager class
67 struct PowerManager::impl {
68 public:
implOHOS::bluetooth::PowerManager::impl69     explicit impl(utility::Dispatcher &dispatcher) : dispatcher_(dispatcher)
70     {
71         LOG_DEBUG("PM_: impl %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
72     };
~implOHOS::bluetooth::PowerManager::impl73     ~impl(){};
74 
75     std::mutex mutex_ {};
76     std::atomic_bool isEnabled_ = false;
77     BtmPmCallbacks btmPmCallbacks_ {};
78     BtmAclCallbacks btmAclCallbacks_ {};
79     utility::Dispatcher &dispatcher_;
80     std::map<RawAddress, std::shared_ptr<PowerDevice>> powerDevices_ {};
81     std::map<uint16_t, RawAddress> connectionHandles_ {};
82 
83     void PowerProcess(const RequestStatus status, const std::string &profileName, const RawAddress rawAddr);
84     void UpdatePowerDevicesInfo(const RawAddress rawAddr, const std::string &profileName, const RequestStatus status);
85 
86     void ModeChangeCallBackProcess(uint8_t status, const RawAddress rawAddr, uint8_t currentMode, uint16_t interval);
87     static void ModeChangeCallBack(
88         uint8_t status, const BtAddr *btAddr, uint8_t currentMode, uint16_t interval, void *context);
89 
90     void SsrCompleteCallBackProcess(uint8_t status, const RawAddress rawAddr);
91     static void SsrCompleteCallBack(uint8_t status, const BtAddr *btAddr, void *context);
92 
93     void ConnectionCompleteCallBackProcess(const RawAddress rawAddr, uint16_t connectionHandle);
94     static void ConnectionCompleteCallBack(const BtmAclConnectCompleteParam *param, void *context);
95 
96     void DisconnectionCompleteCallBackProcess(uint8_t status, uint16_t connectionHandle, uint8_t reason);
97     static void DisconnectionCompleteCallBack(uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context);
98 
99     BT_DISALLOW_COPY_AND_ASSIGN(impl);
100 };
101 
PowerManager(utility::Dispatcher & dispatcher)102 PowerManager::PowerManager(utility::Dispatcher &dispatcher) : pimpl(std::make_unique<PowerManager::impl>(dispatcher))
103 {}
~PowerManager()104 PowerManager::~PowerManager()
105 {}
106 
Enable()107 void PowerManager::Enable()
108 {
109     LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
110     pimpl->isEnabled_ = true;
111     int retVal = BTM_SetDefaultLinkPolicySettings(BTM_LINK_POLICY_ENABLE_ROLE_SWITCH |
112         BTM_LINK_POLICY_ENABLE_SNIFF_MODE);
113     LOG_DEBUG("PM_: BTM_SetDefaultLinkPolicySettings retVal: %{public}d\n", retVal);
114 
115     pimpl->btmPmCallbacks_.modeChange = PowerManager::impl::ModeChangeCallBack;
116     pimpl->btmPmCallbacks_.setSniffSubratingComplete = PowerManager::impl::SsrCompleteCallBack;
117     pimpl->btmAclCallbacks_.connectionComplete = PowerManager::impl::ConnectionCompleteCallBack;
118     pimpl->btmAclCallbacks_.disconnectionComplete = PowerManager::impl::DisconnectionCompleteCallBack;
119 
120     retVal = BTM_RegisterPmCallbacks(&pimpl->btmPmCallbacks_, this);
121     LOG_DEBUG("PM_: BTM_RegisterPmCallbacks retVal: %{public}d\n", retVal);
122 
123     retVal = BTM_RegisterAclCallbacks(&pimpl->btmAclCallbacks_, this);
124     LOG_DEBUG("PM_: BTM_RegisterPmCallbacks retVal: %{public}d\n", retVal);
125 }
126 
Disable()127 void PowerManager::Disable()
128 {
129     LOG_DEBUG("PM_: %{public}s start, line: %{public}d\n", __FUNCTION__, __LINE__);
130     pimpl->isEnabled_ = false;
131     BTM_DeregisterPmCallbacks(&pimpl->btmPmCallbacks_);
132     BTM_DeregisterAclCallbacks(&pimpl->btmAclCallbacks_);
133     pimpl->powerDevices_.clear();
134 }
135 
StatusUpdate(const RequestStatus status,const std::string & profileName,const RawAddress & addr) const136 void PowerManager::StatusUpdate(
137     const RequestStatus status, const std::string &profileName, const RawAddress &addr) const
138 {
139     HILOGI("profileName: %{public}s, status: %{public}u,  addr: %{public}s", profileName.c_str(), status,
140         GetEncryptAddr(addr.GetAddress()).c_str());
141 
142     if (pimpl->isEnabled_) {
143         pimpl->dispatcher_.PostTask(
144             std::bind(&PowerManager::impl::PowerProcess, pimpl.get(), status, profileName, addr));
145     }
146 }
147 
GetPowerMode(const RawAddress & addr) const148 BTPowerMode PowerManager::GetPowerMode(const RawAddress &addr) const
149 {
150     std::unique_lock<std::mutex> lock(pimpl->mutex_);
151     auto iter = pimpl->powerDevices_.find(addr);
152     if (iter != pimpl->powerDevices_.end()) {
153         return iter->second->GetPowerMode();
154     }
155     return BTPowerMode::MODE_INVALID;
156 }
157 
PowerProcess(const RequestStatus status,const std::string & profileName,const RawAddress rawAddr)158 void PowerManager::impl::PowerProcess(
159     const RequestStatus status, const std::string &profileName, const RawAddress rawAddr)
160 {
161     HILOGI("status: %{public}u, profileName: %{public}s", status, profileName.c_str());
162     std::unique_lock<std::mutex> lock(mutex_);
163     UpdatePowerDevicesInfo(rawAddr, profileName, status);
164     auto iter = powerDevices_.find(rawAddr);
165     if (iter != powerDevices_.end()) {
166         iter->second->SetPowerMode();
167     }
168 }
169 
UpdatePowerDevicesInfo(const RawAddress rawAddr,const std::string & profileName,const RequestStatus status)170 void PowerManager::impl::UpdatePowerDevicesInfo(
171     const RawAddress rawAddr, const std::string &profileName, const RequestStatus status)
172 {
173     auto iter = powerDevices_.find(rawAddr);
174     if (iter == powerDevices_.end()) {
175         LOG_DEBUG("PM_: UpdatePowerDevicesInfo(), create powerDevices\n");
176         powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
177     }
178 
179     if (status == RequestStatus::CONNECT_OFF) {
180         auto its = powerDevices_.find(rawAddr);
181         if (its != powerDevices_.end()) {
182             its->second->DeleteRequestPower(profileName);
183         }
184     } else {
185         LOG_DEBUG("PM_:: UpdatePowerDevicesInfo(), execute SetRequesetPower()\n");
186         powerDevices_[rawAddr]->SetRequestPower(profileName, status);
187     }
188 }
189 
ModeChangeCallBackProcess(uint8_t status,const RawAddress rawAddr,uint8_t currentMode,uint16_t interval)190 void PowerManager::impl::ModeChangeCallBackProcess(
191     uint8_t status, const RawAddress rawAddr, uint8_t currentMode, uint16_t interval)
192 {
193     LOG_DEBUG("PM_: %{public}s start, status: %u, currentMode: %u, interval: %u, line: %{public}d\n",
194         __FUNCTION__,
195         status,
196         currentMode,
197         interval,
198         __LINE__);
199     std::unique_lock<std::mutex> lock(mutex_);
200     auto iter = powerDevices_.find(rawAddr);
201     if (iter == powerDevices_.end()) {
202         if (status != 0) {
203             LOG_DEBUG("PM_: ModeChangeCallBackProcess(), no need to create powerDevices for error status\n");
204             return;
205         }
206         LOG_DEBUG("PM_: ModeChangeCallBackProcess(), create powerDevices\n");
207         powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
208     }
209     powerDevices_[rawAddr]->ModeChangeCallBack(status, currentMode, interval);
210 }
211 
ModeChangeCallBack(uint8_t status,const BtAddr * btAddr,uint8_t currentMode,uint16_t interval,void * context)212 void PowerManager::impl::ModeChangeCallBack(
213     uint8_t status, const BtAddr *btAddr, uint8_t currentMode, uint16_t interval, void *context)
214 {
215     RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(btAddr->addr);
216     static_cast<PowerManager*>(context)
217         ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::ModeChangeCallBackProcess,
218             static_cast<PowerManager*>(context)->pimpl.get(),
219             status,
220             rawAddr,
221             currentMode,
222             interval));
223 }
224 
SsrCompleteCallBackProcess(uint8_t status,const RawAddress rawAddr)225 void PowerManager::impl::SsrCompleteCallBackProcess(uint8_t status, const RawAddress rawAddr)
226 {
227     LOG_DEBUG("PM_: %{public}s start, status: %u, line: %{public}d\n", __FUNCTION__, status, __LINE__);
228     std::unique_lock<std::mutex> lock(mutex_);
229     auto iter = powerDevices_.find(rawAddr);
230     if (iter != powerDevices_.end()) {
231         iter->second->SniffSubratingCompleteCallback(status);
232     }
233 }
234 
SsrCompleteCallBack(uint8_t status,const BtAddr * btAddr,void * context)235 void PowerManager::impl::SsrCompleteCallBack(uint8_t status, const BtAddr *btAddr, void *context)
236 {
237     RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(btAddr->addr);
238     static_cast<PowerManager*>(context)
239         ->pimpl->dispatcher_.PostTask(std::bind(
240             &PowerManager::impl::SsrCompleteCallBackProcess, static_cast<PowerManager*>(context)->pimpl.get(), status, rawAddr));
241 }
242 
ConnectionCompleteCallBackProcess(const RawAddress rawAddr,uint16_t connectionHandle)243 void PowerManager::impl::ConnectionCompleteCallBackProcess(const RawAddress rawAddr, uint16_t connectionHandle)
244 {
245     HILOGI("addr: %{public}s", GetEncryptAddr(rawAddr.GetAddress()).c_str());
246     // construct
247     std::unique_lock<std::mutex> lock(mutex_);
248     auto iter = powerDevices_.find(rawAddr);
249     if (iter == powerDevices_.end()) {
250         LOG_DEBUG("PM_: ConnectionCompleteCallBackProcess(), create powerDevices\n");
251         powerDevices_[rawAddr] = std::make_shared<PowerDevice>(rawAddr, dispatcher_);
252     }
253     connectionHandles_[connectionHandle] = rawAddr;
254 }
255 
ConnectionCompleteCallBack(const BtmAclConnectCompleteParam * param,void * context)256 void PowerManager::impl::ConnectionCompleteCallBack(const BtmAclConnectCompleteParam *param, void *context)
257 {
258     RawAddress rawAddr = bluetooth::RawAddress::ConvertToString(param->addr->addr);
259     uint16_t connectionHandle = param->connectionHandle;
260     static_cast<PowerManager*>(context)
261         ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::ConnectionCompleteCallBackProcess,
262             static_cast<PowerManager*>(context)->pimpl.get(),
263             rawAddr,
264             connectionHandle));
265 }
266 
DisconnectionCompleteCallBackProcess(uint8_t status,uint16_t connectionHandle,uint8_t reason)267 void PowerManager::impl::DisconnectionCompleteCallBackProcess(uint8_t status, uint16_t connectionHandle, uint8_t reason)
268 {
269     LOG_DEBUG("PM_: DisconnectionCompleteCallBackProcess(), status=%u, reason=%u\n", status, reason);
270     // destruct
271     if (status == 0) {
272         std::unique_lock<std::mutex> lock(mutex_);
273         auto iter = connectionHandles_.find(connectionHandle);
274         if (iter != connectionHandles_.end()) {
275             auto its = powerDevices_.find(iter->second);
276             if (its != powerDevices_.end()) {
277                 powerDevices_.erase(its);
278             }
279             HILOGI("delete powerDevices, addr: %{public}s", GetEncryptAddr(iter->second.GetAddress()).c_str());
280             connectionHandles_.erase(iter);
281         }
282     }
283 }
284 
DisconnectionCompleteCallBack(uint8_t status,uint16_t connectionHandle,uint8_t reason,void * context)285 void PowerManager::impl::DisconnectionCompleteCallBack(
286     uint8_t status, uint16_t connectionHandle, uint8_t reason, void *context)
287 {
288     static_cast<PowerManager*>(context)
289         ->pimpl->dispatcher_.PostTask(std::bind(&PowerManager::impl::DisconnectionCompleteCallBackProcess,
290             static_cast<PowerManager*>(context)->pimpl.get(),
291             status,
292             connectionHandle,
293             reason));
294 }
295 }  // namespace bluetooth
296 }  // namespace OHOS