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

Commit b1c24530 authored by Chris Manton's avatar Chris Manton
Browse files

Add headless::connect test

Bug: 147316415
Test: cert
Tag: #refactor

Change-Id: Ibe2a88aa832bd9a461c02158a6546d964828e295
parent 9a5883ad
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ cc_test {
    test_suites: ["device-tests"],
    defaults: ["fluoride_defaults"],
    srcs: [
        "connect/connect.cc",
        "get_options.cc",
        "headless.cc",
        "main.cc",
+82 −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 "bt_headless_mode"

#include <future>
#include <map>
#include <string>

#include "stack/include/btm_api_types.h"
#include "stack/include/l2cap_acl_interface.h"
#include "test/headless/connect/connect.h"
#include "test/headless/headless.h"
#include "test/headless/interface.h"
#include "types/raw_address.h"

void power_mode_callback(const RawAddress& p_bda, tBTM_PM_STATUS status,
                         uint16_t value, tHCI_STATUS hci_status) {
  fprintf(stdout, "Got callback\n");
};

std::promise<acl_state_changed_params_t> acl_state_changed_promise;

void callback_interface(interface_data_t data) {
  if (data.name == "acl_state_changed") {
    LOG(INFO) << "Received acl state changed";
    acl_state_changed_params_t p{
        .status = BT_STATUS_SUCCESS,
        .remote_bd_addr = nullptr,
        .state = BT_ACL_STATE_CONNECTED,
    };
    acl_state_changed_promise.set_value(p);
    return;
  }
  LOG(ERROR) << "Received unexpected interface callback";
}

namespace {

int do_mode(unsigned int num_loops, const RawAddress& bd_addr) {
  headless_add_callback("acl_state_changed", callback_interface);

  acl_state_changed_promise = std::promise<acl_state_changed_params_t>();
  auto future = acl_state_changed_promise.get_future();

  fprintf(stdout, "Creating connection to:%s\n", bd_addr.ToString().c_str());
  LOG(INFO) << "Creating classic connection to " << bd_addr.ToString();
  acl_create_classic_connection(bd_addr, false, false);

  acl_state_changed_params_t result = future.get();
  fprintf(stdout, "Connected created to:%s result:%u\n",
          bd_addr.ToString().c_str(), result.status);
  acl_state_changed_promise = std::promise<acl_state_changed_params_t>();
  future = acl_state_changed_promise.get_future();

  result = future.get();
  fprintf(stdout, "Disconnected from to:%s result:%u\n",
          bd_addr.ToString().c_str(), result.status);

  headless_remove_callback("acl_state_changed", callback_interface);
  return 0;
}

}  // namespace

int bluetooth::test::headless::Mode::Run() {
  return RunOnHeadlessStack<int>(
      [this]() { return do_mode(options_.loop_, options_.device_.front()); });
}
+35 −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.
 */

#pragma once

#include "test/headless/get_options.h"
#include "test/headless/headless.h"

namespace bluetooth {
namespace test {
namespace headless {

class Mode : public HeadlessTest<int> {
 public:
  Mode(const bluetooth::test::headless::GetOpt& options)
      : HeadlessTest<int>(options) {}
  int Run() override;
};

}  // namespace headless
}  // namespace test
}  // namespace bluetooth
+40 −1
Original line number Diff line number Diff line
@@ -17,17 +17,44 @@
#define LOG_TAG "bt_headless"

#include <dlfcn.h>  //  dlopen
#include <algorithm>
#include <iostream>
#include <map>

#include "base/logging.h"  // LOG() stdout and android log
#include "include/hardware/bluetooth.h"
#include "osi/include/log.h"  // android log only
#include "test/headless/get_options.h"
#include "test/headless/headless.h"
#include "test/headless/interface.h"

extern bt_interface_t bluetoothInterface;

using namespace bluetooth::test::headless;

std::map<const std::string, std::list<callback_function_t>>
    interface_api_callback_map_;

void headless_add_callback(const std::string interface_name,
                           callback_function_t function) {
  if (interface_api_callback_map_.find(interface_name) ==
      interface_api_callback_map_.end()) {
    interface_api_callback_map_.emplace(interface_name,
                                        std::list<callback_function_t>());
  }
  interface_api_callback_map_[interface_name].push_back(function);
}

void headless_remove_callback(const std::string interface_name,
                              callback_function_t function) {
  if (interface_api_callback_map_.find(interface_name) ==
      interface_api_callback_map_.end()) {
    ASSERT_LOG(false, "No callbacks registered for interface:%s",
               interface_name.c_str());
  }
  interface_api_callback_map_[interface_name].remove(function);
}

namespace {
std::mutex adapter_state_mutex_;
std::condition_variable adapter_state_cv_;
@@ -77,7 +104,19 @@ void bond_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
/** Bluetooth ACL connection state changed callback */
void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
                       bt_acl_state_t state) {
  LOG_INFO("%s", __func__);
  auto callback_list = interface_api_callback_map_.at(__func__);
  for (auto callback : callback_list) {
    interface_data_t params{
        .name = __func__,
        .params.acl_state_changed.status = status,
        .params.acl_state_changed.remote_bd_addr = remote_bd_addr,
        .params.acl_state_changed.state = state,
    };
    (callback)(params);
  }
  LOG_INFO("%s status:%s device:%s state:%s", __func__,
           bt_status_text(status).c_str(), remote_bd_addr->ToString().c_str(),
           (state) ? "disconnected" : "connected");
}

void thread_event(bt_cb_thread_evt evt) { LOG_INFO("%s", __func__); }
+35 −0
Original line number Diff line number Diff line


#pragma once

#include <list>
#include <map>
#include <string>

#include "include/hardware/bluetooth.h"

using acl_state_changed_params_t = struct {
  bt_status_t status;
  RawAddress* remote_bd_addr;
  bt_acl_state_t state;
};

using callback_params_t = union {
  acl_state_changed_params_t acl_state_changed;
};

using interface_data_t = struct {
  std::string name;
  callback_params_t params;
};

using callback_function_t = void (*)(interface_data_t);
using interface_callback_t = struct {
  std::string name;
  callback_function_t function;
};

void headless_add_callback(const std::string interface_name,
                           callback_function_t function);
void headless_remove_callback(const std::string interface_name,
                              callback_function_t function);