Merge "Fix the integration issue for HAL 2.2" am: c4718b793c
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1881111 Change-Id: Ia68335b145295dd0bff8e1900933f5de6b97b95b
This commit is contained in:
commit
5e070c733a
7 changed files with 251 additions and 2 deletions
|
@ -90,6 +90,7 @@ int main(int /* argc */, char* /* argv */ []) {
|
|||
},
|
||||
{
|
||||
"Bluetooth Audio API",
|
||||
"android.hardware.bluetooth.audio@2.2::IBluetoothAudioProvidersFactory",
|
||||
"android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory",
|
||||
"android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory",
|
||||
},
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package android.hardware.bluetooth.audio@2.2;
|
||||
|
||||
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
|
||||
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
160
bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
Normal file
160
bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
Normal file
|
@ -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
|
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "BluetoothAudioSession.h"
|
||||
#include "BluetoothAudioSession_2_1.h"
|
||||
|
||||
namespace android {
|
||||
namespace bluetooth {
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue