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

Commit a8a683b6 authored by Hansong Zhang's avatar Hansong Zhang Committed by Automerger Merge Worker
Browse files

Add Android build target and A2dp sink for topshim am: 05332200 am: df37320f

Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1774260

Change-Id: I21e45967076bdc9ce8eefb60d83cdfb8df07bd59
parents 783fc987 df37320f
Loading
Loading
Loading
Loading
+120 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "system_bt_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["system_bt_license"],
}

rust_library_host_rlib {
    name: "libbt_topshim",
    defaults: ["gd_rust_defaults"],
    crate_name: "bt_topshim",
    srcs: [
        "src/lib.rs",
        ":libbt_topshim_wrapper_bindgen",
    ],
    rustlibs: [
        "libbitflags",
        "libbluetooth_rs",
        "libbt_common",
        "libbt_facade_helpers",
        "libclap",
        "libcxx",
        "libgrpcio",
        "libtokio",
        "libtokio_stream",
        "libbt_packets",
        "libfutures",
        "libnum_traits",
        "libnix",
        "liblog_rust",
    ],
    proc_macros: [
        "libnum_derive",
        "libpaste",
        "libtopshim_macros",
    ],
    lints: "none",
    clippy_lints: "none",
}


cc_library_static {
    name: "libbt_topshim_cxx",
    defaults: ["gd_ffi_defaults"],
    header_libs: ["libbt_callbacks_cxx_headers"],
    srcs: [
        "btav/btav_shim.cc",
        "btav_sink/btav_sink_shim.cc",
        "btif/btif_shim.cc",
    ],
    generated_headers: ["libbt_topshim_bridge_header", "cxx-bridge-header"],
    generated_sources: ["libbt_topshim_bridge_code"],
    shared_libs: [
        "libchrome",
    ],
    include_dirs: [
        "packages/modules/Bluetooth/system",
        "packages/modules/Bluetooth/system/gd/rust/topshim",
        "packages/modules/Bluetooth/system/include",
        "packages/modules/Bluetooth/system/types",
    ],
    host_supported: true,
}

gensrcs {
    name: "libbt_topshim_bridge_header",
    tools: ["cxxbridge"],
    cmd: "$(location cxxbridge) $(in) --header > $(out)",
    srcs: [
        "src/btif.rs",
        "src/profiles/a2dp.rs",
        "src/profiles/avrcp.rs"
    ],
    output_extension: "rs.h",
    export_include_dirs: ["."],
}

gensrcs {
    name: "libbt_topshim_bridge_code",
    tools: ["cxxbridge"],
    cmd: "$(location cxxbridge) $(in) > $(out)",
    srcs: [
        "src/btif.rs",
        "src/profiles/a2dp.rs",
        "src/profiles/avrcp.rs"
    ],
    output_extension: "cc",
    export_include_dirs: ["."],
}

rust_bindgen {
    name: "libbt_topshim_wrapper_bindgen",
    wrapper_src: "bindings/wrapper.hpp",
    crate_name: "bt_topshim_wrapper_bindgen",
    source_stem: "bindings",
    cpp_std: "c++17",
    host_supported: true,
    bindgen_flags: [
        "--size_t-is-usize",
        "--allowlist-function=bt_.*",
        "--allowlist-function=bthh_.*",
        "--allowlist-function=hal_util_.*",
        "--allowlist-type=bt_.*",
        "--allowlist-type=bthh_.*",
        "--enable-cxx-namespaces",
        "--opaque-type=std::.*",
        "--with-derive-default",
        "--with-derive-partialeq",
        "--with-derive-eq",
    ],
    shared_libs: [
        "libc++",
    ],
    header_libs: [
        "libbluetooth_headers",
    ],
    include_dirs: ["packages/modules/Bluetooth/system"],
}
+2 −1
Original line number Diff line number Diff line
@@ -45,7 +45,8 @@ cxxbridge_cc("btif_bridge_code") {
source_set("btif_cxx_bridge_code") {
  sources = [
    "btif/btif_shim.cc",
    "btav/btav_shim.cc"
    "btav/btav_shim.cc",
    "btav_sink/btav_sink_shim.cc"
  ]

  deps = [":btif_bridge_header"]
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.
 */

#include <memory>

#include "gd/rust/topshim/btav_sink/btav_sink_shim.h"
#include "include/hardware/bluetooth.h"

namespace bluetooth {
namespace topshim {
namespace rust {
namespace internal {
static A2dpSinkIntf* g_a2dp_sink_if;

static void connection_state_cb(const RawAddress&, btav_connection_state_t) {}
static void audio_state_cb(const RawAddress&, btav_audio_state_t) {}
static void audio_config_cb(const RawAddress&, uint32_t, uint8_t) {}

btav_sink_callbacks_t g_a2dp_sink_callbacks = {
    sizeof(btav_sink_callbacks_t),
    connection_state_cb,
    audio_state_cb,
    audio_config_cb,
};
}  // namespace internal

A2dpSinkIntf::~A2dpSinkIntf() {
  // TODO
}

std::unique_ptr<A2dpSinkIntf> GetA2dpSinkProfile(const unsigned char* btif) {
  if (internal::g_a2dp_sink_if) std::abort();

  const bt_interface_t* btif_ = reinterpret_cast<const bt_interface_t*>(btif);

  auto a2dp_sink = std::make_unique<A2dpSinkIntf>(
      reinterpret_cast<const btav_sink_interface_t*>(btif_->get_profile_interface("a2dp_sink")));
  internal::g_a2dp_sink_if = a2dp_sink.get();
  return a2dp_sink;
}

int A2dpSinkIntf::init() {
  return intf_->init(&internal::g_a2dp_sink_callbacks, 1);
}

void A2dpSinkIntf::cleanup() {
  // TODO: Implement.
}

}  // namespace rust
}  // namespace topshim
}  // namespace bluetooth
+44 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 <memory>

#include "include/hardware/bt_av.h"

namespace bluetooth {
namespace topshim {
namespace rust {

class A2dpSinkIntf {
 public:
  A2dpSinkIntf(const btav_sink_interface_t* intf) : intf_(intf){};
  ~A2dpSinkIntf();

  // interface for Settings
  int init();
  void cleanup();

 private:
  const btav_sink_interface_t* intf_;
};

std::unique_ptr<A2dpSinkIntf> GetA2dpSinkProfile(const unsigned char* btif);

}  // namespace rust
}  // namespace topshim
}  // namespace bluetooth
+34 −0
Original line number Diff line number Diff line
@@ -148,8 +148,10 @@ pub mod ffi {

    unsafe extern "C++" {
        include!("btav/btav_shim.h");
        include!("btav_sink/btav_sink_shim.h");

        type A2dpIntf;
        type A2dpSinkIntf;

        unsafe fn GetA2dpProfile(btif: *const u8) -> UniquePtr<A2dpIntf>;

@@ -172,6 +174,12 @@ pub mod ffi {
        fn stop_audio_request(self: Pin<&mut A2dpIntf>) -> bool;
        fn cleanup(self: Pin<&mut A2dpIntf>);

        // A2dp sink functions

        unsafe fn GetA2dpSinkProfile(btif: *const u8) -> UniquePtr<A2dpSinkIntf>;

        fn init(self: Pin<&mut A2dpSinkIntf>) -> i32;
        fn cleanup(self: Pin<&mut A2dpSinkIntf>);
    }
    extern "Rust" {
        fn connection_state_callback(addr: RustRawAddress, state: u32);
@@ -318,6 +326,32 @@ impl A2dp {
    }
}

pub struct A2dpSink {
    internal: cxx::UniquePtr<ffi::A2dpSinkIntf>,
    _is_init: bool,
}

// For *const u8 opaque btif
unsafe impl Send for A2dpSink {}

impl A2dpSink {
    pub fn new(intf: &BluetoothInterface) -> A2dpSink {
        let a2dp_sink: cxx::UniquePtr<ffi::A2dpSinkIntf>;
        unsafe {
            a2dp_sink = ffi::GetA2dpSinkProfile(intf.as_raw_ptr());
        }

        A2dpSink { internal: a2dp_sink, _is_init: false }
    }

    pub fn initialize(&mut self) -> bool {
        self.internal.pin_mut().init();
        true
    }

    pub fn cleanup(&mut self) {}
}

#[cfg(test)]
mod tests {
    use super::*;