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

Commit 05332200 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

Add Android build target and A2dp sink for topshim

Make it compile.

Test: build in Android and chromeos
Bug: 181590011
Tag: #refactor
Change-Id: I2dd0dbc8277e41f964da31ee0e59b6c7d23d56fa
parent 048977c3
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::*;