Skip to content
This repository has been archived by the owner on Jul 15, 2024. It is now read-only.

Commit

Permalink
Merge "Fix the integration issue for HAL 2.2"
Browse files Browse the repository at this point in the history
  • Loading branch information
Treehugger Robot authored and Gerrit Code Review committed Nov 12, 2021
2 parents 6c6116a + 95ba6a2 commit c4718b7
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 2 deletions.
1 change: 1 addition & 0 deletions audio/common/all-versions/default/service/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ int main(int /* argc */, char* /* argv */ []) {
},
{
"Bluetooth Audio API",
"[email protected]::IBluetoothAudioProvidersFactory",
"[email protected]::IBluetoothAudioProvidersFactory",
"[email protected]::IBluetoothAudioProvidersFactory",
},
Expand Down
18 changes: 18 additions & 0 deletions bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package [email protected];

import IBluetoothAudioProvider;
import @2.1::IBluetoothAudioProvidersFactory;
import @2.0::Status;
import @2.1::SessionType;

/**
* This factory allows a HAL implementation to be split into multiple
Expand All @@ -30,4 +33,19 @@ import @2.1::IBluetoothAudioProvidersFactory;
* for return value must be invoked synchronously before the API call returns.
*/
interface IBluetoothAudioProvidersFactory extends @2.1::IBluetoothAudioProvidersFactory {
/**
* Opens an audio provider for a session type. To close the provider, it is
* necessary to release references to the returned provider object.
*
* @param sessionType The session type (e.g.
* LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
*
* @return status One of the following
* SUCCESS if the Audio HAL successfully opens the provider with the
* given session type
* FAILURE if the Audio HAL cannot open the provider
* @return provider The provider of the specified session type
*/
openProvider_2_2(SessionType sessionType)
generates (Status status, IBluetoothAudioProvider provider);
};
43 changes: 43 additions & 0 deletions bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,49 @@ Return<void> BluetoothAudioProvidersFactory::openProvider_2_1(
return Void();
}

Return<void> BluetoothAudioProvidersFactory::openProvider_2_2(
const V2_1::SessionType sessionType, openProvider_2_2_cb _hidl_cb) {
LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType);
BluetoothAudioStatus status = BluetoothAudioStatus::SUCCESS;
BluetoothAudioProvider* provider = nullptr;

switch (sessionType) {
case V2_1::SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH:
provider = &a2dp_software_provider_instance_;
break;
case V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH:
provider = &a2dp_offload_provider_instance_;
break;
case V2_1::SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
provider = &hearing_aid_provider_instance_;
break;
case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
provider = &leaudio_output_provider_instance_;
break;
case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
provider = &leaudio_offload_output_provider_instance_;
break;
case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
provider = &leaudio_input_provider_instance_;
break;
case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
provider = &leaudio_offload_input_provider_instance_;
break;
default:
status = BluetoothAudioStatus::FAILURE;
}

if (provider == nullptr || !provider->isValid(sessionType)) {
provider = nullptr;
status = BluetoothAudioStatus::FAILURE;
LOG(ERROR) << __func__ << " - SessionType=" << toString(sessionType)
<< ", status=" << toString(status);
}

_hidl_cb(status, provider);
return Void();
}

Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities(
const V2_0::SessionType sessionType, getProviderCapabilities_cb _hidl_cb) {
hidl_vec<V2_0::AudioCapabilities> audio_capabilities =
Expand Down
3 changes: 3 additions & 0 deletions bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class BluetoothAudioProvidersFactory : public IBluetoothAudioProvidersFactory {
Return<void> openProvider_2_1(const V2_1::SessionType sessionType,
openProvider_2_1_cb _hidl_cb) override;

Return<void> openProvider_2_2(const V2_1::SessionType sessionType,
openProvider_2_2_cb _hidl_cb) override;

Return<void> getProviderCapabilities_2_1(
const V2_1::SessionType sessionType,
getProviderCapabilities_2_1_cb _hidl_cb) override;
Expand Down
160 changes: 160 additions & 0 deletions bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "BluetoothAudioSession_2_2.h"

namespace android {
namespace bluetooth {
namespace audio {

class BluetoothAudioSessionControl_2_2 {
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
using AudioConfiguration_2_2 =
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration;

public:
// The control API helps to check if session is ready or not
// @return: true if the Bluetooth stack has started th specified session
static bool IsSessionReady(const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->IsSessionReady();
}
return false;
}

// The control API helps the bluetooth_audio module to register
// PortStatusCallbacks
// @return: cookie - the assigned number to this bluetooth_audio output
static uint16_t RegisterControlResultCback(
const SessionType_2_1& session_type, const PortStatusCallbacks& cbacks) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
}
return kObserversCookieUndefined;
}

// The control API helps the bluetooth_audio module to unregister
// PortStatusCallbacks
// @param: cookie - indicates which bluetooth_audio output is
static void UnregisterControlResultCback(const SessionType_2_1& session_type,
uint16_t cookie) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
}
}

// The control API for the bluetooth_audio module to get current
// AudioConfiguration
static const AudioConfiguration_2_2 GetAudioConfig(
const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioConfig();
} else if (session_type ==
SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
} else {
return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
}
}

// Those control APIs for the bluetooth_audio module to start / suspend / stop
// stream, to check position, and to update metadata.
static bool StartStream(const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->StartStream();
}
return false;
}

static bool SuspendStream(const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->SuspendStream();
}
return false;
}

static void StopStream(const SessionType_2_1& session_type) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
session_ptr->GetAudioSession()->StopStream();
}
}

static bool GetPresentationPosition(const SessionType_2_1& session_type,
uint64_t* remote_delay_report_ns,
uint64_t* total_bytes_readed,
timespec* data_position) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->GetPresentationPosition(
remote_delay_report_ns, total_bytes_readed, data_position);
}
return false;
}

static void UpdateTracksMetadata(
const SessionType_2_1& session_type,
const struct source_metadata* source_metadata) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
session_ptr->GetAudioSession()->UpdateTracksMetadata(source_metadata);
}
}

// The control API writes stream to FMQ
static size_t OutWritePcmData(const SessionType_2_1& session_type,
const void* buffer, size_t bytes) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->OutWritePcmData(buffer, bytes);
}
return 0;
}

// The control API reads stream from FMQ
static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
size_t bytes) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
}
return 0;
}
};

} // namespace audio
} // namespace bluetooth
} // namespace android
25 changes: 23 additions & 2 deletions bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ using SessionType_2_1 =
using SessionType_2_0 =
::android::hardware::bluetooth::audio::V2_0::SessionType;

using AudioConfiguration_2_1 =
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;

::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
Expand All @@ -52,7 +55,9 @@ BluetoothAudioSession_2_2::BluetoothAudioSession_2_2(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type)
: audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
static_cast<SessionType_2_0>(session_type))) {
static_cast<SessionType_2_0>(session_type))),
audio_session_2_1(
BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type)) {
if (is_2_0_session_type(session_type)) {
session_type_2_1_ = (SessionType_2_1::UNKNOWN);
} else {
Expand All @@ -74,6 +79,10 @@ std::shared_ptr<BluetoothAudioSession>
BluetoothAudioSession_2_2::GetAudioSession() {
return audio_session;
}
std::shared_ptr<BluetoothAudioSession_2_1>
BluetoothAudioSession_2_2::GetAudioSession_2_1() {
return audio_session_2_1;
}

// The control function is for the bluetooth_audio module to get the current
// AudioConfiguration
Expand All @@ -82,7 +91,19 @@ BluetoothAudioSession_2_2::GetAudioConfig() {
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
if (IsSessionReady()) {
// If session is unknown it means it should be 2.0 type
if (session_type_2_1_ != SessionType_2_1::UNKNOWN) return audio_config_2_2_;
if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
if (audio_config_2_2_ != invalidSoftwareAudioConfiguration)
return audio_config_2_2_;

::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
const AudioConfiguration_2_1 fromConf =
GetAudioSession_2_1()->GetAudioConfig();
if (fromConf.getDiscriminator() ==
AudioConfiguration_2_1::hidl_discriminator::pcmConfig) {
toConf.pcmConfig() = fromConf.pcmConfig();
return toConf;
}
}

::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
Expand Down
3 changes: 3 additions & 0 deletions bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <unordered_map>

#include "BluetoothAudioSession.h"
#include "BluetoothAudioSession_2_1.h"

namespace android {
namespace bluetooth {
Expand All @@ -30,6 +31,7 @@ namespace audio {
class BluetoothAudioSession_2_2 {
private:
std::shared_ptr<BluetoothAudioSession> audio_session;
std::shared_ptr<BluetoothAudioSession_2_1> audio_session_2_1;

::android::hardware::bluetooth::audio::V2_1::SessionType session_type_2_1_;

Expand All @@ -56,6 +58,7 @@ class BluetoothAudioSession_2_2 {
bool IsSessionReady();

std::shared_ptr<BluetoothAudioSession> GetAudioSession();
std::shared_ptr<BluetoothAudioSession_2_1> GetAudioSession_2_1();

// The report function is used to report that the Bluetooth stack has started
// this session without any failure, and will invoke session_changed_cb_ to
Expand Down

0 comments on commit c4718b7

Please sign in to comment.