Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5f2d23e authored by Grzegorz Kolodziejczyk's avatar Grzegorz Kolodziejczyk Committed by Jakub Pawlowski
Browse files

Introduce LE Audio software provider for bluetooth audio 2.1

Patch introduces LE Audio software encoding provider for bluetooth audio 2.1.

Bug: 150670922
Tag: #feature
Test: vts-tradefed run vts -m VtsHalBluetoothAudioV2_1TargetTest
Sponsor: jpawlowski@
Change-Id: If668593be7a46c9abcc45d21c5bdb9b493864cc1
parent cc627931
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -87,7 +87,8 @@ int main(int /* argc */, char* /* argv */ []) {
        },
        {
            "Bluetooth Audio API",
            "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory"
            "android.hardware.bluetooth.audio@2.1::IBluetoothAudioProvidersFactory",
            "android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory",
        },
        // remove the old HIDL when Bluetooth Audio Hal V2 has offloading supported
        {
+22 −0
Original line number Diff line number Diff line
// This file is autogenerated by hidl-gen -Landroidbp.

hidl_interface {
    name: "android.hardware.bluetooth.audio@2.1",
    root: "android.hardware",
    srcs: [
        "types.hal",
        "IBluetoothAudioProvider.hal",
        "IBluetoothAudioProvidersFactory.hal",
    ],
    interfaces: [
        "android.hardware.audio.common@5.0",
        "android.hardware.bluetooth.audio@2.0",
        "android.hidl.base@1.0",
        "android.hidl.safe_union@1.0",
    ],
    apex_available: [
        "//apex_available:platform",
        "com.android.bluetooth.updatable",
    ],
    gen_java: false,
}
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

package android.hardware.bluetooth.audio@2.1;

import @2.0::IBluetoothAudioProvider;
import @2.0::IBluetoothAudioPort;
import @2.0::Status;

/**
 * HAL interface from the Bluetooth stack to the Audio HAL
 *
 * The Bluetooth stack calls methods in this interface to start and end audio
 * sessions and sends callback events to the Audio HAL.
 *
 * Note: For HIDL APIs with a "generates" statement, the callback parameter used
 * for return value must be invoked synchronously before the API call returns.
 */
interface IBluetoothAudioProvider extends @2.0::IBluetoothAudioProvider {

    /**
     * This method indicates that the Bluetooth stack is ready to stream audio.
     * It registers an instance of IBluetoothAudioPort with and provides the
     * current negotiated codec to the Audio HAL. After this method is called,
     * the Audio HAL can invoke IBluetoothAudioPort.startStream().
     *
     * Note: endSession() must be called to unregister this IBluetoothAudioPort
     *
     * @param hostIf An instance of IBluetoothAudioPort for stream control
     * @param audioConfig The audio configuration negotiated with the remote
     *    device. The PCM parameters are set if software based encoding,
     *    otherwise the correct codec configuration is used for hardware
     *    encoding.
     *
     * @return status One of the following
     *    SUCCESS if this IBluetoothAudioPort was successfully registered with
     *        the Audio HAL
     *    UNSUPPORTED_CODEC_CONFIGURATION if the Audio HAL cannot register this
     *        IBluetoothAudioPort with the given codec configuration
     *    FAILURE if the Audio HAL cannot register this IBluetoothAudioPort for
     *        any other reason
     * @return dataMQ The fast message queue for audio data from/to this
     *    provider. Audio data will be in PCM format as specified by the
     *    audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
     *    from/to hardware or on failure.
     */
    startSession_2_1(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
                generates (Status status, fmq_sync<uint8_t> dataMQ);
};
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

package android.hardware.bluetooth.audio@2.1;

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

/**
 * This factory allows a HAL implementation to be split into multiple
 * independent providers.
 *
 * When the Bluetooth stack is ready to create an audio session, it must first
 * obtain the IBluetoothAudioProvider for that session type by calling
 * openProvider().
 *
 * Note: For HIDL APIs with a "generates" statement, the callback parameter used
 * for return value must be invoked synchronously before the API call returns.
 */
interface IBluetoothAudioProvidersFactory extends @2.0::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_1(SessionType sessionType)
        generates (Status status, IBluetoothAudioProvider provider);

    /**
     * Gets a list of audio capabilities for a session type.
     *
     * For software encoding, the PCM capabilities are returned.
     * For hardware encoding, the supported codecs and their capabilities are
     * returned.
     *
     * @param sessionType The session type (e.g.
     *    A2DP_SOFTWARE_ENCODING_DATAPATH).
     * @return audioCapabilities A list containing all the capabilities
     *    supported by the sesson type. The capabilities is a list of
     *    available options when configuring the codec for the session.
     *    For software encoding it is the PCM data rate.
     *    For hardware encoding it is the list of supported codecs and their
     *    capabilities.
     *    If a provider isn't supported, an empty list should be returned.
     *    Note: Only one entry should exist per codec when using hardware
     *    encoding.
     */
     getProviderCapabilities_2_1(SessionType sessionType)
         generates (vec<AudioCapabilities> audioCapabilities);
};
+95 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

#define LOG_TAG "BTAudioProviderA2dpOffload"

#include "A2dpOffloadAudioProvider.h"

#include <android-base/logging.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>

#include "BluetoothAudioSessionReport.h"
#include "BluetoothAudioSupportedCodecsDB.h"

namespace android {
namespace hardware {
namespace bluetooth {
namespace audio {
namespace V2_1 {
namespace implementation {

using ::android::bluetooth::audio::BluetoothAudioSessionReport;
using ::android::hardware::kSynchronizedReadWrite;
using ::android::hardware::MessageQueue;
using ::android::hardware::Void;
using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;

using DataMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;

A2dpOffloadAudioProvider::A2dpOffloadAudioProvider()
    : BluetoothAudioProvider() {
  session_type_ = SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH;
}

bool A2dpOffloadAudioProvider::isValid(const V2_0::SessionType& sessionType) {
  return isValid(static_cast<SessionType>(sessionType));
}

bool A2dpOffloadAudioProvider::isValid(const SessionType& sessionType) {
  return (sessionType == session_type_);
}

Return<void> A2dpOffloadAudioProvider::startSession(
    const sp<IBluetoothAudioPort>& hostIf,
    const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
  /**
   * Initialize the audio platform if audioConfiguration is supported.
   * Save the IBluetoothAudioPort interface, so that it can be used
   * later to send stream control commands to the HAL client, based on
   * interaction with Audio framework.
   */
  if (audioConfig.getDiscriminator() !=
      AudioConfiguration::hidl_discriminator::codecConfig) {
    LOG(WARNING) << __func__
                 << " - Invalid Audio Configuration=" << toString(audioConfig);
    _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
             DataMQ::Descriptor());
    return Void();
  } else if (!android::bluetooth::audio::IsOffloadCodecConfigurationValid(
                 session_type_, audioConfig.codecConfig())) {
    _hidl_cb(BluetoothAudioStatus::UNSUPPORTED_CODEC_CONFIGURATION,
             DataMQ::Descriptor());
    return Void();
  }

  return BluetoothAudioProvider::startSession(hostIf, audioConfig, _hidl_cb);
}

Return<void> A2dpOffloadAudioProvider::onSessionReady(
    startSession_cb _hidl_cb) {
  BluetoothAudioSessionReport::OnSessionStarted(session_type_, stack_iface_,
                                                nullptr, audio_config_);
  _hidl_cb(BluetoothAudioStatus::SUCCESS, DataMQ::Descriptor());
  return Void();
}

}  // namespace implementation
}  // namespace V2_1
}  // namespace audio
}  // namespace bluetooth
}  // namespace hardware
}  // namespace android
Loading