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#include "bluetooth_connection.h"
17
18#include "audio_control_manager.h"
19#include "bluetooth_call_manager.h"
20#include "telephony_log_wrapper.h"
21#ifdef ABILITY_BLUETOOTH_SUPPORT
22#include "bluetooth_host.h"
23
24constexpr int32_t PHONE_NUMBER_TYPE = 0x81;
25#endif
26
27namespace OHOS {
28namespace Telephony {
29BluetoothConnection::BluetoothConnection() : connectedScoAddr_("") {}
30
31BluetoothConnection::~BluetoothConnection()
32{
33#ifdef ABILITY_BLUETOOTH_SUPPORT
34    if (statusChangeListener_ != nullptr) {
35        auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
36        if (samgrProxy != nullptr) {
37            samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
38            statusChangeListener_ = nullptr;
39        }
40    }
41    std::lock_guard<std::mutex> lock(bluetoothMutex_);
42    mapConnectedBtDevices_.clear();
43#endif
44}
45
46void BluetoothConnection::Init()
47{
48#ifdef ABILITY_BLUETOOTH_SUPPORT
49    statusChangeListener_ = new (std::nothrow) SystemAbilityListener();
50    if (statusChangeListener_ == nullptr) {
51        TELEPHONY_LOGE("failed to create statusChangeListener");
52        return;
53    }
54    auto managerPtr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
55    if (managerPtr == nullptr) {
56        TELEPHONY_LOGE("get system ability manager error");
57        return;
58    }
59    int32_t ret = managerPtr->SubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, statusChangeListener_);
60    if (ret != TELEPHONY_SUCCESS) {
61        TELEPHONY_LOGE("failed to subscribe bluetooth service SA:%{public}d", BLUETOOTH_HOST_SYS_ABILITY_ID);
62        return;
63    }
64    std::vector<Bluetooth::BluetoothRemoteDevice> devices;
65    Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
66    if (profile == nullptr) {
67        TELEPHONY_LOGE("profile is nullptr");
68        return;
69    }
70    int32_t result = profile->GetConnectedDevices(devices);
71    if (result != TELEPHONY_SUCCESS) {
72        TELEPHONY_LOGE("get connected devices fail");
73        return;
74    }
75    for (auto device : devices) {
76        std::string macAddress = device.GetDeviceAddr();
77        std::string deviceName = device.GetDeviceName();
78        AddBtDevice(macAddress, device);
79        DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(macAddress,
80            AudioDeviceType::DEVICE_BLUETOOTH_SCO, deviceName);
81    }
82    TELEPHONY_LOGI("BluetoothConnection init success!");
83#endif
84}
85
86#ifdef ABILITY_BLUETOOTH_SUPPORT
87
88bool BluetoothConnection::IsBtAvailble()
89{
90    std::lock_guard<std::mutex> lock(bluetoothMutex_);
91    if (mapConnectedBtDevices_.empty()) {
92        TELEPHONY_LOGE("mapConnectedBtDevices_ is empty");
93        return false;
94    }
95
96    return true;
97}
98#endif
99
100int32_t BluetoothConnection::SendBtCallState(
101    int32_t numActive, int32_t numHeld, int32_t callState, const std::string &number)
102{
103#ifdef ABILITY_BLUETOOTH_SUPPORT
104    Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
105    if (profile == nullptr) {
106        TELEPHONY_LOGE("profile is nullptr");
107        return TELEPHONY_ERROR;
108    }
109
110    std::string nickName = "";
111    profile->PhoneStateChanged(numActive, numHeld, callState, number, PHONE_NUMBER_TYPE, nickName);
112#endif
113    TELEPHONY_LOGI("PhoneStateChanged,numActive:%{public}d,numHeld:%{public}d,callState:%{public}d", numActive, numHeld,
114        callState);
115    return TELEPHONY_SUCCESS;
116}
117
118int32_t BluetoothConnection::SendCallDetailsChange(int32_t callId, int32_t callState)
119{
120#ifdef ABILITY_BLUETOOTH_SUPPORT
121    Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
122    if (profile == nullptr) {
123        TELEPHONY_LOGE("profile is nullptr");
124        return TELEPHONY_ERROR;
125    }
126
127    profile->CallDetailsChanged(callId, callState);
128#endif
129    TELEPHONY_LOGI("Send CallDetails");
130    return TELEPHONY_SUCCESS;
131}
132
133bool BluetoothConnection::IsAudioActivated()
134{
135    return DelayedSingleton<AudioControlManager>::GetInstance()->IsAudioActivated();
136}
137
138#ifdef ABILITY_BLUETOOTH_SUPPORT
139
140void BluetoothConnection::ResetBtConnection()
141{
142    std::lock_guard<std::mutex> lock(bluetoothMutex_);
143    mapConnectedBtDevices_.clear();
144}
145
146void BluetoothConnection::RegisterObserver()
147{
148    Bluetooth::HandsFreeAudioGateway *profile = Bluetooth::HandsFreeAudioGateway::GetProfile();
149    if (profile == nullptr) {
150        TELEPHONY_LOGE("BluetoothConnection RegisterObserver fail!");
151        return;
152    }
153
154    profile->RegisterObserver(shared_from_this());
155}
156
157void BluetoothConnection::AddBtDevice(const std::string &address, Bluetooth::BluetoothRemoteDevice device)
158{
159    std::lock_guard<std::mutex> lock(bluetoothMutex_);
160    auto iter = mapConnectedBtDevices_.find(address);
161    if (iter != mapConnectedBtDevices_.end()) {
162        TELEPHONY_LOGI("device is existenced");
163    } else {
164        mapConnectedBtDevices_.insert(std::pair<std::string, const Bluetooth::BluetoothRemoteDevice>(address, device));
165        TELEPHONY_LOGI("AddBtDevice success");
166    }
167}
168
169void BluetoothConnection::RemoveBtDevice(const std::string &address)
170{
171    std::lock_guard<std::mutex> lock(bluetoothMutex_);
172    if (mapConnectedBtDevices_.count(address) > 0) {
173        mapConnectedBtDevices_.erase(address);
174        TELEPHONY_LOGI("RemoveBtDevice success");
175    } else {
176        TELEPHONY_LOGE("device is not existenced");
177    }
178}
179
180Bluetooth::BluetoothRemoteDevice *BluetoothConnection::GetBtDevice(const std::string &address)
181{
182    std::lock_guard<std::mutex> lock(bluetoothMutex_);
183    if (mapConnectedBtDevices_.count(address) > 0) {
184        auto iter = mapConnectedBtDevices_.find(address);
185        if (iter != mapConnectedBtDevices_.end()) {
186            return &iter->second;
187        }
188    }
189    TELEPHONY_LOGE("device is not existenced");
190    return nullptr;
191}
192
193void BluetoothConnection::OnConnectionStateChanged(const Bluetooth::BluetoothRemoteDevice &device,
194    int32_t state, int32_t cause)
195{
196    TELEPHONY_LOGI("BluetoothConnection::OnConnectionStateChanged state : %{public}d", state);
197    std::string macAddress = device.GetDeviceAddr();
198    std::string deviceName = device.GetDeviceName();
199    switch (state) {
200        case (int32_t)Bluetooth::BTConnectState::CONNECTED:
201            DelayedSingleton<AudioDeviceManager>::GetInstance()->AddAudioDeviceList(
202                macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO, deviceName);
203            AddBtDevice(macAddress, device);
204            /** try to connect sco while new bluetooth device connected
205             *  if connect sco successfully , should switch current audio device to bluetooth sco
206             */
207            break;
208        case (int32_t)Bluetooth::BTConnectState::DISCONNECTED:
209            DelayedSingleton<AudioDeviceManager>::GetInstance()->RemoveAudioDeviceList(
210                macAddress, AudioDeviceType::DEVICE_BLUETOOTH_SCO);
211            RemoveBtDevice(macAddress);
212            break;
213        default:
214            break;
215    }
216}
217
218void SystemAbilityListener::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
219{
220    TELEPHONY_LOGI("SA:%{public}d is added!", systemAbilityId);
221    if (!CheckInputSysAbilityId(systemAbilityId)) {
222        TELEPHONY_LOGE("added SA is invalid!");
223        return;
224    }
225    if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
226        TELEPHONY_LOGE("added SA is not bluetooth service, ignored.");
227        return;
228    }
229
230    DelayedSingleton<BluetoothConnection>::GetInstance()->RegisterObserver();
231}
232
233void SystemAbilityListener::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
234{
235    TELEPHONY_LOGI("SA:%{public}d is removed!", systemAbilityId);
236    if (!CheckInputSysAbilityId(systemAbilityId)) {
237        TELEPHONY_LOGE("removed SA is invalid!");
238        return;
239    }
240    if (systemAbilityId != BLUETOOTH_HOST_SYS_ABILITY_ID) {
241        TELEPHONY_LOGE("removed SA is not bluetooth service, ignored.");
242        return;
243    }
244
245    DelayedSingleton<BluetoothConnection>::GetInstance()->ResetBtConnection();
246    std::shared_ptr<AudioDeviceManager> audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
247    audioDeviceManager->ResetBtAudioDevicesList();
248    audioDeviceManager->ProcessEvent(AudioEvent::INIT_AUDIO_DEVICE);
249}
250#endif
251} // namespace Telephony
252} // namespace OHOS
253