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

Commit 8a4411df authored by Ying Hsu's avatar Ying Hsu
Browse files

floss: Add and remove PID files in btadapterd

As btif_dm_hw_on happens after GD_SHIM_MODULE's start_up,
creating the PID file in the start_up would allow upper
applications use the bluetooth adapter before it's fully
initialized.
This patch fixes the issue by creating and removing the PID
file in btadapterd while receiving AdapterState callback
from BTIF.

Bug: 262646536
Tag: #floss
Test: Manual - restart chromebook / toggle bluetooth adapter

Change-Id: I67afe41441dfd6494eea353c033df84d16e0885c
parent b7818fa2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ fn main() -> Result<(), Box<dyn Error>> {
        tx.clone(),
    ))));
    let bluetooth = Arc::new(Mutex::new(Box::new(Bluetooth::new(
        adapter_index,
        tx.clone(),
        intf.clone(),
        bluetooth_media.clone(),
+31 −0
Original line number Diff line number Diff line
@@ -23,7 +23,10 @@ use btif_macros::{btif_callback, btif_callbacks_dispatcher};
use log::{debug, warn};
use num_traits::cast::ToPrimitive;
use std::collections::HashMap;
use std::fs::File;
use std::hash::Hash;
use std::io::Write;
use std::process;
use std::sync::{Arc, Condvar, Mutex};
use std::time::Duration;
use std::time::Instant;
@@ -50,6 +53,8 @@ const FOUND_DEVICE_FRESHNESS: Duration = Duration::from_secs(30);
// TODO(241930383): Add enum to topshim
const BTM_SUCCESS: i32 = 0;

const PID_DIR: &str = "/var/run/bluetooth";

/// Defines the adapter API.
pub trait IBluetooth {
    /// Adds a callback from a client who wishes to observe adapter events.
@@ -395,6 +400,7 @@ pub trait IBluetoothConnectionCallback: RPCProxy {
pub struct Bluetooth {
    intf: Arc<Mutex<BluetoothInterface>>,

    adapter_index: i32,
    bonded_devices: HashMap<String, BluetoothDeviceContext>,
    bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
    bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
@@ -422,6 +428,7 @@ pub struct Bluetooth {
impl Bluetooth {
    /// Constructs the IBluetooth implementation.
    pub fn new(
        adapter_index: i32,
        tx: Sender<Message>,
        intf: Arc<Mutex<BluetoothInterface>>,
        bluetooth_media: Arc<Mutex<Box<BluetoothMedia>>>,
@@ -429,6 +436,7 @@ impl Bluetooth {
        bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>,
    ) -> Bluetooth {
        Bluetooth {
            adapter_index,
            bonded_devices: HashMap::new(),
            callbacks: Callbacks::new(tx.clone(), Message::AdapterCallbackDisconnected),
            connection_callbacks: Callbacks::new(
@@ -728,6 +736,21 @@ impl Bluetooth {
            }
        }
    }

    /// Creates a file to notify btmanagerd the adapter is enabled.
    fn create_pid_file(&self) -> std::io::Result<()> {
        let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.adapter_index);
        let mut f = File::create(&file_name)?;
        f.write_all(process::id().to_string().as_bytes())?;
        Ok(())
    }

    /// Removes the file to notify btmanagerd the adapter is disabled.
    fn remove_pid_file(&self) -> std::io::Result<()> {
        let file_name = format!("{}/bluetooth{}.pid", PID_DIR, self.adapter_index);
        std::fs::remove_file(&file_name)?;
        Ok(())
    }
}

#[btif_callbacks_dispatcher(dispatch_base_callbacks, BaseCallbacks)]
@@ -856,11 +879,19 @@ impl BtifBluetoothCallbacks for Bluetooth {
        }

        if self.state == BtState::On {
            match self.create_pid_file() {
                Err(err) => warn!("create_pid_file() error: {}", err),
                _ => (),
            }
            self.bluetooth_media.lock().unwrap().initialize();
        }

        if self.state == BtState::Off {
            self.properties.clear();
            match self.remove_pid_file() {
                Err(err) => warn!("remove_pid_file() error: {}", err),
                _ => (),
            }

            // Let the signal notifier know we are turned off.
            *self.sig_notifier.0.lock().unwrap() = false;
+0 −34
Original line number Diff line number Diff line
@@ -68,31 +68,6 @@ namespace shim {
using ::bluetooth::common::InitFlags;
using ::bluetooth::common::StringFormat;

namespace {
// PID file format
constexpr char pid_file_format[] = "/var/run/bluetooth/bluetooth%d.pid";

void CreatePidFile() {
  std::string pid_file =
      StringFormat(pid_file_format, InitFlags::GetAdapterIndex());
  int pid_fd_ = open(pid_file.c_str(), O_WRONLY | O_CREAT, 0644);
  if (!pid_fd_) return;

  pid_t my_pid = getpid();
  dprintf(pid_fd_, "%d\n", my_pid);
  close(pid_fd_);

  LOG_INFO("%s - Created pid file %s", __func__, pid_file.c_str());
}

void RemovePidFile() {
  std::string pid_file =
      StringFormat(pid_file_format, InitFlags::GetAdapterIndex());
  unlink(pid_file.c_str());
  LOG_INFO("%s - Deleted pid file %s", __func__, pid_file.c_str());
}
}  // namespace

Stack* Stack::GetInstance() {
  static Stack instance;
  return &instance;
@@ -123,9 +98,6 @@ void Stack::StartEverything() {
        new ::rust::Box<rust::Controller>(rust::get_controller(**rust_stack_));
    bluetooth::shim::hci_on_reset_complete();

    // Create pid since we're up and running
    CreatePidFile();

    // Create the acl shim layer
    acl_ = new legacy::Acl(
        stack_handler_, legacy::GetAclInterface(),
@@ -212,9 +184,6 @@ void Stack::StartEverything() {
  if (common::init_flags::btaa_hci_is_enabled()) {
    bluetooth::shim::init_activity_attribution();
  }

  // Create pid since we're up and running
  CreatePidFile();
}

void Stack::Start(ModuleList* modules) {
@@ -231,9 +200,6 @@ void Stack::Start(ModuleList* modules) {
}

void Stack::Stop() {
  // First remove pid file so clients no stack is going down
  RemovePidFile();

  if (common::init_flags::gd_rust_is_enabled()) {
    if (rust_stack_ != nullptr) {
      rust::stack_stop(**rust_stack_);