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 "bluetooth_hfp_ag.h"
17#include <unistd.h>
18#include "bluetooth_device.h"
19#include "bluetooth_host.h"
20#include "bluetooth_profile_manager.h"
21#include "bluetooth_log.h"
22#include "bluetooth_utils.h"
23#include "bluetooth_observer_list.h"
24#include "bluetooth_phone_state.h"
25#include "i_bluetooth_hfp_ag.h"
26#include "bluetooth_hfp_ag_observer_stub.h"
27#include "i_bluetooth_host.h"
28#include "iservice_registry.h"
29#include "system_ability_definition.h"
30
31namespace OHOS {
32namespace Bluetooth {
33std::mutex g_hfpProxyMutex;
34class AgServiceObserver : public BluetoothHfpAgObserverStub {
35public:
36    explicit AgServiceObserver(BluetoothObserverList<HandsFreeAudioGatewayObserver> &observers) : observers_(observers)
37    {
38        HILOGD("enter");
39    }
40    ~AgServiceObserver() override
41    {
42        HILOGD("enter");
43    };
44
45    void OnConnectionStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t cause) override
46    {
47        HILOGD("hfpAg conn state, device: %{public}s, state: %{public}s, cause: %{public}d",
48            GET_ENCRYPT_RAW_ADDR(device), GetProfileConnStateName(state).c_str(), cause);
49        BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
50        observers_.ForEach([remoteDevice, state, cause](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
51            observer->OnConnectionStateChanged(remoteDevice, state, cause);
52        });
53    }
54
55    void OnScoStateChanged(const BluetoothRawAddress &device, int32_t state, int32_t reason) override
56    {
57        HILOGI("enter, device: %{public}s, state: %{public}u, reason: %{public}u",
58            GET_ENCRYPT_RAW_ADDR(device), state, reason);
59        BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
60        observers_.ForEach([remoteDevice, state, reason](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
61            observer->OnScoStateChanged(remoteDevice, state, reason);
62        });
63    }
64
65    void OnActiveDeviceChanged(const BluetoothRawAddress &device) override
66    {
67        HILOGD("enter, device: %{public}s", GET_ENCRYPT_RAW_ADDR(device));
68        BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
69        observers_.ForEach([remoteDevice](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
70            observer->OnActiveDeviceChanged(remoteDevice);
71        });
72    }
73
74    void OnHfEnhancedDriverSafetyChanged(
75        const BluetoothRawAddress &device, int32_t indValue) override
76    {
77        HILOGI("enter, device: %{public}s, indValue: %{public}d",
78            GET_ENCRYPT_RAW_ADDR(device), indValue);
79        BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
80        observers_.ForEach([remoteDevice, indValue](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
81            observer->OnHfEnhancedDriverSafetyChanged(remoteDevice, indValue);
82        });
83    }
84
85    void OnHfpStackChanged(const BluetoothRawAddress &device, int32_t action) override
86    {
87        HILOGI("enter, device: %{public}s, action: %{public}s",
88            GET_ENCRYPT_RAW_ADDR(device), GetUpdateOutputStackActionName(action).c_str());
89        BluetoothRemoteDevice remoteDevice(device.GetAddress(), 0);
90        observers_.ForEach([remoteDevice, action](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
91            observer->OnHfpStackChanged(remoteDevice, action);
92        });
93    }
94
95    void OnVirtualDeviceChanged(int32_t action, std::string address) override
96    {
97        HILOGI("enter, device: %{public}s, action: %{public}d", GetEncryptAddr(address).c_str(), action);
98        observers_.ForEach([action, address](std::shared_ptr<HandsFreeAudioGatewayObserver> observer) {
99            observer->OnVirtualDeviceChanged(action, address);
100        });
101    }
102
103private:
104    BluetoothObserverList<HandsFreeAudioGatewayObserver> &observers_;
105    BLUETOOTH_DISALLOW_COPY_AND_ASSIGN(AgServiceObserver);
106};
107
108std::string HfpAgServiceName = "bluetooth-hfp-ag-server";
109
110struct HandsFreeAudioGateway::impl {
111    impl();
112    ~impl();
113
114    int32_t GetConnectedDevices(std::vector<BluetoothRemoteDevice>& devices)
115    {
116        HILOGD("enter");
117        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
118        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_SERVICE_DISCONNECTED, "failed: no proxy");
119        std::vector<BluetoothRawAddress> ori;
120        int32_t ret = proxy->GetConnectDevices(ori);
121        if (ret != BT_NO_ERROR) {
122            HILOGE("inner error.");
123            return ret;
124        }
125        for (auto it = ori.begin(); it != ori.end(); it++) {
126            devices.push_back(BluetoothRemoteDevice(it->GetAddress(), 0));
127        }
128        return BT_NO_ERROR;
129    }
130
131    std::vector<BluetoothRemoteDevice> GetDevicesByStates(std::vector<int> states)
132    {
133        HILOGD("enter");
134        std::vector<BluetoothRemoteDevice> remoteDevices;
135        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
136        if (proxy != nullptr) {
137            std::vector<BluetoothRawAddress> rawDevices;
138            std::vector<int32_t> tmpstates;
139            for (int state : states) {
140                int32_t value = (int32_t)state;
141                tmpstates.push_back(value);
142            }
143            proxy->GetDevicesByStates(tmpstates, rawDevices);
144            for (BluetoothRawAddress rawDevice : rawDevices) {
145                BluetoothRemoteDevice remoteDevice(rawDevice.GetAddress(), 0);
146                remoteDevices.push_back(remoteDevice);
147            }
148        }
149        return remoteDevices;
150    }
151
152    int32_t GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
153    {
154        HILOGD("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
155        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
156        if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
157            HILOGE("invalid param.");
158            return BT_ERR_INVALID_PARAM;
159        }
160
161        return proxy->GetDeviceState(BluetoothRawAddress(device.GetDeviceAddr()), state);
162    }
163
164    int32_t Connect(const BluetoothRemoteDevice &device)
165    {
166        HILOGI("hfp connect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
167        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
168        if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
169            HILOGE("invalid param.");
170            return BT_ERR_INVALID_PARAM;
171        }
172        return proxy->Connect(BluetoothRawAddress(device.GetDeviceAddr()));
173    }
174
175    int32_t Disconnect(const BluetoothRemoteDevice &device)
176    {
177        HILOGI("hfp disconnect remote device: %{public}s", GET_ENCRYPT_ADDR(device));
178        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
179        if (proxy == nullptr || !device.IsValidBluetoothRemoteDevice()) {
180            HILOGE("invalid param.");
181            return BT_ERR_INVALID_PARAM;
182        }
183        return proxy->Disconnect(BluetoothRawAddress(device.GetDeviceAddr()));
184    }
185
186    int GetScoState(const BluetoothRemoteDevice &device)
187    {
188        HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
189        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
190        if (proxy != nullptr && IS_BT_ENABLED() && device.IsValidBluetoothRemoteDevice()) {
191            return proxy->GetScoState(BluetoothRawAddress(device.GetDeviceAddr()));
192        }
193        return HFP_AG_SCO_STATE_DISCONNECTED;
194    }
195
196    int32_t ConnectSco(uint8_t callType)
197    {
198        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
199        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_PARAM, "failed: no proxy");
200        return proxy->ConnectSco(callType);
201    }
202
203    int32_t DisconnectSco(uint8_t callType)
204    {
205        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
206        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INVALID_PARAM, "failed: no proxy");
207        return proxy->DisconnectSco(callType);
208    }
209
210    bool ConnectSco()
211    {
212        HILOGD("enter");
213        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
214        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, proxy->ConnectSco(), "failed: no proxy");
215        return false;
216    }
217
218    bool DisconnectSco()
219    {
220        HILOGD("enter");
221        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
222        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, proxy->DisconnectSco(), "failed: no proxy");
223        return false;
224    }
225
226    bool IsValidCallType(uint8_t callType)
227    {
228        if (callType == static_cast<uint8_t>(BTCallType::CALL_TYPE_CELLULAR) ||
229            callType == static_cast<uint8_t>(BTCallType::CALL_TYPE_VIRTUAL) ||
230            callType == static_cast<uint8_t>(BTCallType::CALL_TYPE_RECOGNITION)) {
231            return true;
232        }
233        return false;
234    }
235
236    void PhoneStateChanged(BluetoothPhoneState &phoneState)
237    {
238        HILOGI("numActive: %{public}d, numHeld: %{public}d, callState: %{public}d, type: %{public}d",
239            phoneState.GetActiveNum(), phoneState.GetHeldNum(), phoneState.GetCallState(), phoneState.GetCallType());
240        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
241        CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is null");
242        proxy->PhoneStateChanged(phoneState);
243    }
244
245    void ClccResponse(int index, int direction, int status, int mode, bool mpty, std::string number, int type)
246    {
247        HILOGI("enter, index: %{public}d, direction: %{public}d, status: %{public}d, mode: %{public}d, mpty: "
248            "%{public}d, type: %{public}d", index, direction, status, mode, mpty, type);
249        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
250        CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is null");
251        proxy->ClccResponse(index, direction, status, mode, mpty, number, type);
252    }
253
254    bool OpenVoiceRecognition(const BluetoothRemoteDevice &device)
255    {
256        HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
257        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
258        if (proxy != nullptr && device.IsValidBluetoothRemoteDevice()) {
259            return proxy->OpenVoiceRecognition(BluetoothRawAddress(device.GetDeviceAddr()));
260        }
261        return false;
262    }
263
264    bool CloseVoiceRecognition(const BluetoothRemoteDevice &device)
265    {
266        HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
267        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
268        if (proxy != nullptr && device.IsValidBluetoothRemoteDevice()) {
269            return proxy->CloseVoiceRecognition(BluetoothRawAddress(device.GetDeviceAddr()));
270        }
271        return false;
272    }
273
274    bool SetActiveDevice(const BluetoothRemoteDevice &device)
275    {
276        HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
277        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
278        if (proxy != nullptr && device.IsValidBluetoothRemoteDevice()) {
279            return proxy->SetActiveDevice(BluetoothRawAddress(device.GetDeviceAddr()));
280        }
281        return false;
282    }
283
284    bool IntoMock(const BluetoothRemoteDevice &device, int state)
285    {
286        HILOGD("enter");
287        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
288        if (proxy != nullptr && IS_BT_ENABLED()) {
289            return proxy->IntoMock(BluetoothRawAddress(device.GetDeviceAddr()), state);
290        }
291        return false;
292    }
293
294    bool SendNoCarrier(const BluetoothRemoteDevice &device)
295    {
296        HILOGD("enter");
297        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
298        if (proxy != nullptr && IS_BT_ENABLED() && device.IsValidBluetoothRemoteDevice()) {
299            return proxy->SendNoCarrier(BluetoothRawAddress(device.GetDeviceAddr()));
300        }
301        return false;
302    }
303
304    BluetoothRemoteDevice GetActiveDevice()
305    {
306        HILOGD("enter");
307        BluetoothRemoteDevice device;
308        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
309        if (proxy != nullptr) {
310            std::string address = proxy->GetActiveDevice();
311            BluetoothRemoteDevice remoteDevice(address, 0);
312            device = remoteDevice;
313        }
314        return device;
315    }
316
317    int SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
318    {
319        HILOGD("enter");
320        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
321        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "proxy is null");
322        return proxy->SetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
323    }
324
325    int GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
326    {
327        HILOGD("enter");
328        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
329        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "proxy is null");
330        return proxy->GetConnectStrategy(BluetoothRawAddress(device.GetDeviceAddr()), strategy);
331    }
332
333    int IsInbandRingingEnabled(bool &isEnabled) const
334    {
335        HILOGD("enter");
336        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
337        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "proxy is null");
338        return proxy->IsInbandRingingEnabled(isEnabled);
339    }
340
341    void CallDetailsChanged(int callId, int callState)
342    {
343        HILOGD("enter");
344        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
345        CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is null");
346        proxy->CallDetailsChanged(callId, callState);
347    }
348
349    int IsVgsSupported(const BluetoothRemoteDevice &device, bool &isSupported) const
350    {
351        HILOGD("enter");
352        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
353        CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "proxy is null");
354        return proxy->IsVgsSupported(BluetoothRawAddress(device.GetDeviceAddr()), isSupported);
355    }
356
357    void EnableBtCallLog(bool state)
358    {
359        HILOGD("enter");
360        sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
361        CHECK_AND_RETURN_LOG(proxy != nullptr, "proxy is null");
362        proxy->EnableBtCallLog(state);
363    }
364
365    void RegisterObserver(std::shared_ptr<HandsFreeAudioGatewayObserver> observer)
366    {
367        HILOGD("enter");
368        observers_.Register(observer);
369    }
370
371    void DeregisterObserver(std::shared_ptr<HandsFreeAudioGatewayObserver> observer)
372    {
373        HILOGD("enter");
374        observers_.Deregister(observer);
375        HILOGI("end");
376    }
377
378    int32_t profileRegisterId = 0;
379private:
380    const static int HFP_AG_SLC_STATE_DISCONNECTED = static_cast<int>(BTConnectState::DISCONNECTED);
381    const static int HFP_AG_SCO_STATE_DISCONNECTED = 3;
382
383    BluetoothObserverList<HandsFreeAudioGatewayObserver> observers_;
384    sptr<AgServiceObserver> serviceObserver_;
385};
386
387HandsFreeAudioGateway::impl::impl()
388{
389    serviceObserver_ = new AgServiceObserver(observers_);
390    profileRegisterId = BluetoothProfileManager::GetInstance().RegisterFunc(PROFILE_HFP_AG,
391        [this](sptr<IRemoteObject> remote) {
392        sptr<IBluetoothHfpAg> proxy = iface_cast<IBluetoothHfpAg>(remote);
393        CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
394        proxy->RegisterObserver(serviceObserver_);
395    });
396}
397
398HandsFreeAudioGateway::impl::~impl()
399{
400    HILOGD("enter");
401    BluetoothProfileManager::GetInstance().DeregisterFunc(profileRegisterId);
402    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
403    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
404    proxy->DeregisterObserver(serviceObserver_);
405}
406
407HandsFreeAudioGateway *HandsFreeAudioGateway::GetProfile()
408{
409    HILOGD("enter");
410#ifdef DTFUZZ_TEST
411    static BluetoothNoDestructor<HandsFreeAudioGateway> instance;
412    return instance.get();
413#else
414    static HandsFreeAudioGateway instance;
415    return &instance;
416#endif
417}
418
419HandsFreeAudioGateway::HandsFreeAudioGateway()
420{
421    HILOGD("enter");
422    pimpl = std::make_unique<impl>();
423}
424
425HandsFreeAudioGateway::~HandsFreeAudioGateway()
426{
427    HILOGD("enter");
428}
429
430std::vector<BluetoothRemoteDevice> HandsFreeAudioGateway::GetConnectedDevices() const
431{
432    std::vector<BluetoothRemoteDevice> devices;
433    if (!IS_BT_ENABLED()) {
434        HILOGE("bluetooth is off.");
435        return devices;
436    }
437    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
438    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, devices, "failed: no proxy");
439
440    pimpl->GetConnectedDevices(devices);
441    return devices;
442}
443
444int32_t HandsFreeAudioGateway::GetConnectedDevices(std::vector<BluetoothRemoteDevice> &devices)
445{
446    if (!IS_BT_ENABLED()) {
447        HILOGE("bluetooth is off.");
448        return BT_ERR_INVALID_STATE;
449    }
450
451    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
452    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
453
454    return pimpl->GetConnectedDevices(devices);
455}
456
457std::vector<BluetoothRemoteDevice> HandsFreeAudioGateway::GetDevicesByStates(std::vector<int> states)
458{
459    if (!IS_BT_ENABLED()) {
460        HILOGE("bluetooth is off.");
461        return std::vector<BluetoothRemoteDevice>();
462    }
463    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
464    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, std::vector<BluetoothRemoteDevice>(), "failed: no proxy");
465
466    return pimpl->GetDevicesByStates(states);
467}
468
469int32_t HandsFreeAudioGateway::GetDeviceState(const BluetoothRemoteDevice &device, int32_t &state)
470{
471    HILOGD("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
472    if (!IS_BT_ENABLED()) {
473        HILOGE("bluetooth is off.");
474        return BT_ERR_INVALID_STATE;
475    }
476
477    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
478    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
479
480    return pimpl->GetDeviceState(device, state);
481}
482
483int32_t HandsFreeAudioGateway::Connect(const BluetoothRemoteDevice &device)
484{
485    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
486    if (!IS_BT_ENABLED()) {
487        HILOGE("bluetooth is off.");
488        return BT_ERR_INVALID_STATE;
489    }
490
491    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
492    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
493
494    return pimpl->Connect(device);
495}
496
497int32_t HandsFreeAudioGateway::Disconnect(const BluetoothRemoteDevice &device)
498{
499    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
500    if (!IS_BT_ENABLED()) {
501        HILOGE("bluetooth is off.");
502        return BT_ERR_INVALID_STATE;
503    }
504    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
505    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
506
507    return pimpl->Disconnect(device);
508}
509
510int HandsFreeAudioGateway::GetScoState(const BluetoothRemoteDevice &device) const
511{
512    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
513    if (!IS_BT_ENABLED()) {
514        HILOGE("bluetooth is off.");
515        return static_cast<int>(HfpScoConnectState::SCO_DISCONNECTED);
516    }
517    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
518    CHECK_AND_RETURN_LOG_RET(proxy != nullptr,
519        static_cast<int>(HfpScoConnectState::SCO_DISCONNECTED), "failed: no proxy");
520
521    return pimpl->GetScoState(device);
522}
523
524int32_t HandsFreeAudioGateway::ConnectSco(uint8_t callType)
525{
526    HILOGI("enter, callType: %{public}d", callType);
527    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
528    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
529    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
530        "hfpAG proxy is nullptr.");
531    CHECK_AND_RETURN_LOG_RET((pimpl->IsValidCallType(callType)), BT_ERR_INVALID_PARAM,
532        "connect sco call type error.");
533    return pimpl->ConnectSco(callType);
534}
535
536int32_t HandsFreeAudioGateway::DisconnectSco(uint8_t callType)
537{
538    HILOGI("enter, callType: %{public}d", callType);
539    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
540    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
541    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY,
542        "hfpAG proxy is nullptr.");
543    CHECK_AND_RETURN_LOG_RET((pimpl->IsValidCallType(callType)), BT_ERR_INVALID_PARAM,
544        "disconnect sco call type error.");
545    return pimpl->DisconnectSco(callType);
546}
547
548bool HandsFreeAudioGateway::ConnectSco()
549{
550    return true;
551}
552
553bool HandsFreeAudioGateway::DisconnectSco()
554{
555    return true;
556}
557
558void HandsFreeAudioGateway::PhoneStateChanged(
559    int numActive, int numHeld, int callState, const std::string &number, int type, const std::string &name)
560{
561    CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
562    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
563    CHECK_AND_RETURN_LOG(proxy != nullptr, "hfpAG proxy is nullptr.");
564
565    BluetoothPhoneState phoneState;
566    phoneState.SetActiveNum(numActive);
567    phoneState.SetHeldNum(numHeld);
568    phoneState.SetCallState(callState);
569    phoneState.SetNumber(number);
570    phoneState.SetCallType(type);
571    phoneState.SetName(name);
572    pimpl->PhoneStateChanged(phoneState);
573}
574
575void HandsFreeAudioGateway::ClccResponse(
576    int index, int direction, int status, int mode, bool mpty, const std::string &number, int type)
577{
578    if (!IS_BT_ENABLED()) {
579        HILOGE("bluetooth is off.");
580        return;
581    }
582
583    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
584    CHECK_AND_RETURN_LOG(proxy != nullptr, "failed: no proxy");
585
586    pimpl->ClccResponse(index, direction, status, mode, mpty, number, type);
587}
588
589bool HandsFreeAudioGateway::OpenVoiceRecognition(const BluetoothRemoteDevice &device)
590{
591    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
592    if (!IS_BT_ENABLED()) {
593        HILOGE("bluetooth is off.");
594        return false;
595    }
596
597    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
598    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "failed: no proxy");
599
600    return pimpl->OpenVoiceRecognition(device);
601}
602
603bool HandsFreeAudioGateway::CloseVoiceRecognition(const BluetoothRemoteDevice &device)
604{
605    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
606    if (!IS_BT_ENABLED()) {
607        HILOGE("bluetooth is off.");
608        return false;
609    }
610
611    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
612    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "failed: no proxy");
613
614    return pimpl->CloseVoiceRecognition(device);
615}
616
617bool HandsFreeAudioGateway::SetActiveDevice(const BluetoothRemoteDevice &device)
618{
619    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
620    if (!IS_BT_ENABLED()) {
621        HILOGE("bluetooth is off.");
622        return false;
623    }
624
625    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
626    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, false, "failed: no proxy");
627
628    return pimpl->SetActiveDevice(device);
629}
630
631BluetoothRemoteDevice HandsFreeAudioGateway::GetActiveDevice() const
632{
633    BluetoothRemoteDevice device;
634    if (!IS_BT_ENABLED()) {
635        HILOGE("bluetooth is off.");
636        return device;
637    }
638
639    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
640    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, device, "failed: no proxy");
641
642    device = pimpl->GetActiveDevice();
643    return device;
644}
645
646int HandsFreeAudioGateway::SetConnectStrategy(const BluetoothRemoteDevice &device, int strategy)
647{
648    HILOGI("enter, device: %{public}s, strategy: %{public}d", GET_ENCRYPT_ADDR(device), strategy);
649    if (!IS_BT_ENABLED()) {
650        HILOGE("bluetooth is off.");
651        return BT_ERR_INVALID_STATE;
652    }
653
654    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
655    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
656
657    if ((!device.IsValidBluetoothRemoteDevice()) || (
658        (strategy != static_cast<int>(BTStrategyType::CONNECTION_ALLOWED)) &&
659        (strategy != static_cast<int>(BTStrategyType::CONNECTION_FORBIDDEN)))) {
660        HILOGI("input parameter error.");
661        return BT_ERR_INVALID_PARAM;
662    }
663    return pimpl->SetConnectStrategy(device, strategy);
664}
665
666int HandsFreeAudioGateway::GetConnectStrategy(const BluetoothRemoteDevice &device, int &strategy) const
667{
668    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
669    if (!IS_BT_ENABLED()) {
670        HILOGE("bluetooth is off.");
671        return BT_ERR_INVALID_STATE;
672    }
673
674    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
675    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
676
677    if (!device.IsValidBluetoothRemoteDevice()) {
678        HILOGI("input parameter error.");
679        return BT_ERR_INVALID_PARAM;
680    }
681    return pimpl->GetConnectStrategy(device, strategy);
682}
683
684int HandsFreeAudioGateway::IsInbandRingingEnabled(bool &isEnabled) const
685{
686    HILOGI("enter");
687    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
688    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
689    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_INTERNAL_ERROR, "hfpAG proxy is nullptr");
690    return pimpl->IsInbandRingingEnabled(isEnabled);
691}
692
693void HandsFreeAudioGateway::CallDetailsChanged(int callId, int callState)
694{
695    HILOGI("enter, callId: %{public}d, callState: %{public}d", callId, callState);
696    CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
697    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
698    CHECK_AND_RETURN_LOG(proxy != nullptr, "hfpAG proxy is nullptr");
699    pimpl->CallDetailsChanged(callId, callState);
700}
701
702void HandsFreeAudioGateway::EnableBtCallLog(bool state)
703{
704    HILOGI("enter");
705    CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
706    pimpl->EnableBtCallLog(state);
707}
708
709int HandsFreeAudioGateway::IsVgsSupported(const BluetoothRemoteDevice &device, bool &isSupported) const
710{
711    HILOGI("enter, device: %{public}s", GET_ENCRYPT_ADDR(device));
712    CHECK_AND_RETURN_LOG_RET(IS_BT_ENABLED(), BT_ERR_INVALID_STATE, "bluetooth is off.");
713    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
714    CHECK_AND_RETURN_LOG_RET(proxy != nullptr, BT_ERR_UNAVAILABLE_PROXY, "failed: no proxy");
715    CHECK_AND_RETURN_LOG_RET(device.IsValidBluetoothRemoteDevice(), BT_ERR_INVALID_PARAM, "input parameter error.");
716    return pimpl->IsVgsSupported(device, isSupported);
717}
718
719void HandsFreeAudioGateway::GetVirtualDeviceList(std::vector<std::string> &devices) const
720{
721    CHECK_AND_RETURN_LOG(IS_BT_ENABLED(), "bluetooth is off.");
722    sptr<IBluetoothHfpAg> proxy = GetRemoteProxy<IBluetoothHfpAg>(PROFILE_HFP_AG);
723    CHECK_AND_RETURN_LOG(proxy != nullptr, "hfpAG proxy is nullptr");
724    proxy->GetVirtualDeviceList(devices);
725}
726
727void HandsFreeAudioGateway::RegisterObserver(std::shared_ptr<HandsFreeAudioGatewayObserver> observer)
728{
729    HILOGD("enter");
730    CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
731    pimpl->RegisterObserver(observer);
732}
733
734void HandsFreeAudioGateway::DeregisterObserver(std::shared_ptr<HandsFreeAudioGatewayObserver> observer)
735{
736    HILOGD("enter");
737    CHECK_AND_RETURN_LOG(pimpl != nullptr, "pimpl is null.");
738    pimpl->DeregisterObserver(observer);
739}
740}  // namespace Bluetooth
741}  // namespace OHOS