babfb58305
* hardware/interfaces/audio/aidl/default/ at android-16.0.0_r1.
238 lines
8.2 KiB
C++
238 lines
8.2 KiB
C++
/*
|
|
* Copyright 2023 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 <condition_variable>
|
|
#include <mutex>
|
|
|
|
#include <android-base/thread_annotations.h>
|
|
|
|
#include <aidl/android/hardware/audio/common/SinkMetadata.h>
|
|
#include <aidl/android/hardware/audio/common/SourceMetadata.h>
|
|
#include <aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.h>
|
|
#include <aidl/android/hardware/bluetooth/audio/PcmConfiguration.h>
|
|
#include <aidl/android/hardware/bluetooth/audio/PresentationPosition.h>
|
|
#include <aidl/android/hardware/bluetooth/audio/SessionType.h>
|
|
#include <aidl/android/media/audio/common/AudioDeviceDescription.h>
|
|
|
|
namespace android::bluetooth::audio::aidl {
|
|
|
|
enum class BluetoothStreamState : uint8_t {
|
|
DISABLED = 0, // This stream is closing or Bluetooth profiles (A2DP/LE) is disabled
|
|
STANDBY,
|
|
STARTING,
|
|
STARTED,
|
|
SUSPENDING,
|
|
UNKNOWN,
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const BluetoothStreamState& state);
|
|
|
|
/**
|
|
* Proxy for Bluetooth Audio HW Module to communicate with Bluetooth Audio
|
|
* Session Control. All methods are not thread safe, so users must acquire a
|
|
* lock. Note: currently, getState() of DevicePortProxy is only used for
|
|
* verbose logging, it is not locked, so the state may not be synchronized.
|
|
*/
|
|
class BluetoothAudioPort {
|
|
public:
|
|
BluetoothAudioPort() = default;
|
|
virtual ~BluetoothAudioPort() = default;
|
|
|
|
/**
|
|
* Fetch output control / data path of BluetoothAudioPort and setup
|
|
* callbacks into BluetoothAudioProvider. If registerPort() returns false, the audio
|
|
* HAL must delete this BluetoothAudioPort and return EINVAL to caller
|
|
*/
|
|
virtual bool registerPort(
|
|
const ::aidl::android::media::audio::common::AudioDeviceDescription&) = 0;
|
|
|
|
/**
|
|
* Unregister this BluetoothAudioPort from BluetoothAudioSessionControl.
|
|
* Audio HAL must delete this BluetoothAudioPort after calling this.
|
|
*/
|
|
virtual void unregisterPort() = 0;
|
|
|
|
/**
|
|
* When the Audio framework / HAL tries to query audio config about format,
|
|
* channel mask and sample rate, it uses this function to fetch from the
|
|
* Bluetooth stack
|
|
*/
|
|
virtual bool loadAudioConfig(
|
|
::aidl::android::hardware::bluetooth::audio::PcmConfiguration&) = 0;
|
|
|
|
/**
|
|
* When the Audio framework / HAL wants to change the stream state, it invokes
|
|
* these 4 functions to control the Bluetooth stack (Audio Control Path).
|
|
* Note: standby(), start() and suspend() will return true when there are no errors.
|
|
|
|
* Called by Audio framework / HAL to change the state to stand by. When A2DP/LE profile is
|
|
* disabled, the port is first set to STANDBY by calling suspend and then mState is set to
|
|
* DISABLED. To reset the state back to STANDBY this method is called.
|
|
*/
|
|
virtual bool standby() = 0;
|
|
|
|
/**
|
|
* Called by Audio framework / HAL to start the stream
|
|
*/
|
|
virtual bool start() = 0;
|
|
|
|
/**
|
|
* Called by Audio framework / HAL to suspend the stream
|
|
*/
|
|
virtual bool suspend() = 0;
|
|
|
|
/**
|
|
* Called by Audio framework / HAL to stop the stream
|
|
*/
|
|
virtual void stop() = 0;
|
|
|
|
/**
|
|
* Called by the Audio framework / HAL to fetch information about audio frames
|
|
* presented to an external sink, or frames presented fror an internal sink
|
|
*/
|
|
virtual bool getPresentationPosition(
|
|
::aidl::android::hardware::bluetooth::audio::PresentationPosition&) const = 0;
|
|
|
|
/**
|
|
* Called by the Audio framework / HAL when the metadata of the stream's
|
|
* source has been changed.
|
|
*/
|
|
virtual bool updateSourceMetadata(
|
|
const ::aidl::android::hardware::audio::common::SourceMetadata&) const {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Called by the Audio framework / HAL when the metadata of the stream's
|
|
* sink has been changed.
|
|
*/
|
|
virtual bool updateSinkMetadata(
|
|
const ::aidl::android::hardware::audio::common::SinkMetadata&) const {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return the current BluetoothStreamState
|
|
*/
|
|
virtual BluetoothStreamState getState() const = 0;
|
|
|
|
/**
|
|
* Set the current BluetoothStreamState
|
|
*/
|
|
virtual bool setState(BluetoothStreamState) = 0;
|
|
|
|
virtual bool isA2dp() const = 0;
|
|
|
|
virtual bool isLeAudio() const = 0;
|
|
|
|
virtual bool getPreferredDataIntervalUs(size_t&) const = 0;
|
|
|
|
virtual size_t writeData(const void*, size_t) const { return 0; }
|
|
|
|
virtual size_t readData(void*, size_t) const { return 0; }
|
|
};
|
|
|
|
class BluetoothAudioPortAidl : public BluetoothAudioPort {
|
|
public:
|
|
BluetoothAudioPortAidl();
|
|
virtual ~BluetoothAudioPortAidl();
|
|
|
|
bool registerPort(const ::aidl::android::media::audio::common::AudioDeviceDescription&
|
|
description) override;
|
|
|
|
void unregisterPort() override;
|
|
|
|
bool loadAudioConfig(
|
|
::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
|
|
|
|
bool standby() override;
|
|
bool start() override;
|
|
bool suspend() override;
|
|
void stop() override;
|
|
|
|
bool getPresentationPosition(::aidl::android::hardware::bluetooth::audio::PresentationPosition&
|
|
presentation_position) const override;
|
|
|
|
bool updateSourceMetadata(const ::aidl::android::hardware::audio::common::SourceMetadata&
|
|
sourceMetadata) const override;
|
|
|
|
bool updateSinkMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata&
|
|
sinkMetadata) const override;
|
|
|
|
/**
|
|
* Return the current BluetoothStreamState
|
|
* Note: This method is used for logging, does not lock, so value returned may not be latest
|
|
*/
|
|
BluetoothStreamState getState() const override NO_THREAD_SAFETY_ANALYSIS;
|
|
|
|
bool setState(BluetoothStreamState state) override;
|
|
|
|
bool isA2dp() const override;
|
|
|
|
bool isLeAudio() const override;
|
|
|
|
bool getPreferredDataIntervalUs(size_t& interval_us) const override;
|
|
|
|
protected:
|
|
uint16_t mCookie;
|
|
BluetoothStreamState mState GUARDED_BY(mCvMutex);
|
|
::aidl::android::hardware::bluetooth::audio::SessionType mSessionType;
|
|
// WR to support Mono: True if fetching Stereo and mixing into Mono
|
|
bool mIsStereoToMono = false;
|
|
|
|
bool inUse() const;
|
|
|
|
std::string debugMessage() const;
|
|
|
|
private:
|
|
// start()/suspend() report state change status via callback. Wait until kMaxWaitingTimeMs or a
|
|
// state change after a call to start()/suspend() and analyse the returned status. Below mutex,
|
|
// conditional variable serves this purpose.
|
|
mutable std::mutex mCvMutex;
|
|
std::condition_variable mInternalCv GUARDED_BY(mCvMutex);
|
|
|
|
// Check and initialize session type for |devices| If failed, this
|
|
// BluetoothAudioPortAidl is not initialized and must be deleted.
|
|
bool initSessionType(
|
|
const ::aidl::android::media::audio::common::AudioDeviceDescription& description);
|
|
|
|
bool condWaitState(BluetoothStreamState state);
|
|
|
|
void controlResultHandler(
|
|
uint16_t cookie,
|
|
const ::aidl::android::hardware::bluetooth::audio::BluetoothAudioStatus& status);
|
|
void sessionChangedHandler(uint16_t cookie);
|
|
};
|
|
|
|
class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl {
|
|
public:
|
|
bool loadAudioConfig(
|
|
::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
|
|
|
|
// The audio data path to the Bluetooth stack (Software encoding)
|
|
size_t writeData(const void* buffer, size_t bytes) const override;
|
|
};
|
|
|
|
class BluetoothAudioPortAidlIn : public BluetoothAudioPortAidl {
|
|
public:
|
|
// The audio data path from the Bluetooth stack (Software decoded)
|
|
size_t readData(void* buffer, size_t bytes) const override;
|
|
};
|
|
|
|
} // namespace android::bluetooth::audio::aidl
|