• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024-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 "distributed_source_switch_controller.h"
17 #include "cJSON.h"
18 #ifdef ABILITY_BLUETOOTH_SUPPORT
19 #include "bluetooth_device.h"
20 #endif
21 #include "audio_proxy.h"
22 #include "telephony_errors.h"
23 #include "audio_device_manager.h"
24 #include "telephony_log_wrapper.h"
25 #include "distributed_communication_manager.h"
26 
27 namespace OHOS {
28 namespace Telephony {
OnDeviceOnline(const std::string & devId,const std::string & devName,AudioDeviceType devType)29 void DistributedSourceSwitchController::OnDeviceOnline(const std::string &devId, const std::string &devName,
30     AudioDeviceType devType)
31 {
32     auto audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
33     if (audioDeviceManager != nullptr) {
34         std::string address = GetDevAddress(devId, devName);
35         audioDeviceManager->AddAudioDeviceList(address, devType, devName);
36     }
37 
38 #ifdef ABILITY_BLUETOOTH_SUPPORT
39     std::lock_guard<ffrt::mutex> lock(mutex_);
40     if (hfpListener_ == nullptr) {
41         hfpListener_ = std::make_shared<DcCallSourceHfpListener>();
42         Bluetooth::HandsFreeAudioGateway::GetProfile()->RegisterObserver(hfpListener_);
43     }
44 #endif
45 }
46 
OnDeviceOffline(const std::string & devId,const std::string & devName,AudioDeviceType devType)47 void DistributedSourceSwitchController::OnDeviceOffline(const std::string &devId, const std::string &devName,
48     AudioDeviceType devType)
49 {
50     auto audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
51     if (audioDeviceManager != nullptr) {
52         std::string address = GetDevAddress(devId, devName);
53         audioDeviceManager->RemoveAudioDeviceList(address, devType);
54         audioDeviceManager->InitAudioDevice();
55     }
56 
57 #ifdef ABILITY_BLUETOOTH_SUPPORT
58     std::lock_guard<ffrt::mutex> lock(mutex_);
59     if (hfpListener_ != nullptr) {
60         Bluetooth::HandsFreeAudioGateway::GetProfile()->DeregisterObserver(hfpListener_);
61         hfpListener_ = nullptr;
62     }
63 #endif
64 }
65 
OnDistributedAudioDeviceChange(const std::string & devId,const std::string & devName,AudioDeviceType devType,int32_t devRole)66 void DistributedSourceSwitchController::OnDistributedAudioDeviceChange(const std::string &devId,
67     const std::string &devName, AudioDeviceType devType, int32_t devRole)
68 {
69     {
70         std::lock_guard<ffrt::mutex> lock(mutex_);
71         isAudioOnSink_ = (devRole == static_cast<int32_t>(DistributedRole::SINK));
72         TELEPHONY_LOGI("OnDistributedAudioDeviceChange isAudioOnSink[%{public}d]", isAudioOnSink_);
73     }
74     auto audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
75     if (audioDeviceManager != nullptr) {
76         if (devRole == static_cast<int32_t>(DistributedRole::SINK)) {
77             if (AudioStandard::AudioSystemManager::GetInstance()->IsDeviceActive(
78                 AudioStandard::DeviceType::DEVICE_TYPE_BLUETOOTH_SCO)) { // deactive bt if switch from bt to sink
79                 AudioStandard::AudioSystemManager::GetInstance()->SetDeviceActive(
80                     AudioStandard::DeviceType::DEVICE_TYPE_BLUETOOTH_SCO, false);
81             }
82             std::string address = GetDevAddress(devId, devName);
83             AudioDevice targetDevice = {
84                 .deviceType = devType,
85             };
86             if (memcpy_s(targetDevice.address, kMaxAddressLen, address.c_str(), address.length()) != EOK ||
87                 memcpy_s(targetDevice.deviceName, kMaxDeviceNameLen, devName.c_str(), devName.length()) != EOK) {
88                 TELEPHONY_LOGE("memcpy_s address or deviceName failed.");
89                 return;
90             }
91             audioDeviceManager->SetCurrentAudioDevice(targetDevice);
92         } else {
93             AudioDevice audioDevice;
94             if (DelayedSingleton<AudioProxy>::GetInstance()->GetPreferredOutputAudioDevice(audioDevice) !=
95                 TELEPHONY_SUCCESS) {
96                 TELEPHONY_LOGE("get preferred output audio device fail");
97                 return;
98             }
99             audioDeviceManager->SetCurrentAudioDevice(audioDevice.deviceType);
100         }
101     }
102 }
103 
OnRemoveSystemAbility()104 void DistributedSourceSwitchController::OnRemoveSystemAbility()
105 {
106     auto audioDeviceManager = DelayedSingleton<AudioDeviceManager>::GetInstance();
107     if (audioDeviceManager != nullptr) {
108         audioDeviceManager->ResetDistributedCallDevicesList();
109         audioDeviceManager->InitAudioDevice();
110     }
111 
112     std::lock_guard<ffrt::mutex> lock(mutex_);
113     isAudioOnSink_ = false;
114 #ifdef ABILITY_BLUETOOTH_SUPPORT
115     if (hfpListener_ != nullptr) {
116         Bluetooth::HandsFreeAudioGateway::GetProfile()->DeregisterObserver(hfpListener_);
117         hfpListener_ = nullptr;
118     }
119 #endif
120 }
121 
SwitchDevice(const std::string & devId,int32_t direction)122 bool DistributedSourceSwitchController::SwitchDevice(const std::string &devId, int32_t direction)
123 {
124     auto distributedMgr = DelayedSingleton<DistributedCommunicationManager>::GetInstance();
125     if (distributedMgr == nullptr) {
126         return false;
127     }
128     auto ret = distributedMgr->SwitchDevWrapper(devId, direction);
129     TELEPHONY_LOGI("switch distributed device result[%{public}d]", ret);
130     return ret == TELEPHONY_SUCCESS;
131 }
132 
GetDevAddress(const std::string & devId,const std::string & devName)133 std::string DistributedSourceSwitchController::GetDevAddress(const std::string &devId, const std::string &devName)
134 {
135     std::string address = "";
136     cJSON *root = cJSON_CreateObject();
137     if (root == nullptr) {
138         TELEPHONY_LOGE("create json msg fail");
139         return address;
140     }
141     do {
142         if (cJSON_AddStringToObject(root, "devId", devId.c_str()) == nullptr) {
143             TELEPHONY_LOGE("add dev id fail");
144             break;
145         }
146         if (cJSON_AddStringToObject(root, "devName", devName.c_str()) == nullptr) {
147             TELEPHONY_LOGE("add dev name fail");
148             break;
149         }
150         char *jsonData = cJSON_PrintUnformatted(root);
151         if (jsonData != nullptr) {
152             address = jsonData;
153             free(jsonData);
154             jsonData = nullptr;
155         }
156     } while (false);
157     cJSON_Delete(root);
158     return address;
159 }
160 
161 #ifdef ABILITY_BLUETOOTH_SUPPORT
OnHfpStackChanged(const Bluetooth::BluetoothRemoteDevice & device,int32_t action)162 void DcCallSourceHfpListener::OnHfpStackChanged(const Bluetooth::BluetoothRemoteDevice &device, int32_t action)
163 {
164     TELEPHONY_LOGI("source hfp stack changed, action[%{public}d]", action);
165     if (IsNeedSwitchToSource(device, action)) {
166         (void)DelayedSingleton<DistributedCommunicationManager>::GetInstance()->SwitchToSourceDevice();
167     }
168 }
169 
IsNeedSwitchToSource(const Bluetooth::BluetoothRemoteDevice & device,int32_t action)170 bool DcCallSourceHfpListener::IsNeedSwitchToSource(const Bluetooth::BluetoothRemoteDevice &device, int32_t action)
171 {
172     if (!DelayedSingleton<DistributedCommunicationManager>::GetInstance()->IsAudioOnSink()) {
173         return false;
174     }
175     int32_t cod = DEFAULT_HFP_FLAG_VALUE;
176     int32_t majorClass = DEFAULT_HFP_FLAG_VALUE;
177     int32_t majorMinorClass = DEFAULT_HFP_FLAG_VALUE;
178     device.GetDeviceProductType(cod, majorClass, majorMinorClass);
179     TELEPHONY_LOGI("device major %{public}d, minor %{public}d", majorClass, majorMinorClass);
180     if (action == WEAR_ACTION && majorClass == Bluetooth::BluetoothDevice::MAJOR_AUDIO_VIDEO &&
181         (majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_HEADPHONES ||
182         majorMinorClass == Bluetooth::BluetoothDevice::AUDIO_VIDEO_WEARABLE_HEADSET)) {
183         return true;
184     }
185     if (action == USER_SELECTION_ACTION && majorClass == Bluetooth::BluetoothDevice::MAJOR_WEARABLE &&
186         majorMinorClass == Bluetooth::BluetoothDevice::WEARABLE_WRIST_WATCH) {
187         return true;
188     }
189     return false;
190 }
191 #endif
192 
193 } // namespace Telephony
194 } // namespace OHOS
195