mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-02-01 07:39:11 +00:00
linux-rust: add anc control for nothing device
This commit is contained in:
@@ -103,6 +103,7 @@ impl AirPodsNoiseControlMode {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NothingState {
|
||||
pub anc_mode: NothingAncMode,
|
||||
pub anc_mode_state: combo_box::State<NothingAncMode>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
@@ -2,14 +2,20 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use iced::{Background, Border, Length, Theme};
|
||||
use iced::widget::{container, text, column, row, Space};
|
||||
use crate::bluetooth::att::ATTManager;
|
||||
use crate::devices::enums::{DeviceData, DeviceInformation, NothingState};
|
||||
use iced::widget::combo_box;
|
||||
use iced::border::Radius;
|
||||
use iced::overlay::menu;
|
||||
use iced::widget::text_input;
|
||||
use tokio::runtime::Runtime;
|
||||
use std::thread;
|
||||
use crate::bluetooth::att::{ATTManager, ATTHandles};
|
||||
use crate::devices::enums::{DeviceData, DeviceInformation, NothingState, DeviceState};
|
||||
use crate::ui::window::Message;
|
||||
|
||||
pub fn nothing_view<'a>(
|
||||
mac: &str,
|
||||
mac: &'a str,
|
||||
devices_list: &HashMap<String, DeviceData>,
|
||||
state: &NothingState,
|
||||
state: &'a NothingState,
|
||||
att_manager: Arc<ATTManager>
|
||||
) -> iced::widget::Container<'a, Message> {
|
||||
let mut information_col = iced::widget::column![];
|
||||
@@ -53,13 +59,116 @@ pub fn nothing_view<'a>(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let noise_control_mode = container(row![
|
||||
text("Noise Control Mode").size(16).style(
|
||||
|theme: &Theme| {
|
||||
let mut style = text::Style::default();
|
||||
style.color = Some(theme.palette().text);
|
||||
style
|
||||
}
|
||||
),
|
||||
Space::with_width(Length::Fill),
|
||||
{
|
||||
let state_clone = state.clone();
|
||||
let mac = mac.clone();
|
||||
let att_manager_clone = att_manager.clone();
|
||||
combo_box(
|
||||
&state.anc_mode_state,
|
||||
"Select Noise Control Mode",
|
||||
Some(&state.anc_mode.clone()),
|
||||
{
|
||||
move |selected_mode| {
|
||||
let att_manager = att_manager_clone.clone();
|
||||
let selected_mode_c = selected_mode.clone();
|
||||
let mac_s = mac.clone();
|
||||
run_async_in_thread(
|
||||
async move {
|
||||
if let Err(e) = att_manager.write(
|
||||
ATTHandles::NothingEverything,
|
||||
&[
|
||||
0x55,
|
||||
0x60, 0x01,
|
||||
0x0F, 0xF0,
|
||||
0x03, 0x00,
|
||||
0x00, 0x01,
|
||||
selected_mode_c.to_byte(), 0x00,
|
||||
0x00, 0x00
|
||||
]
|
||||
).await {
|
||||
log::error!("Failed to set noise cancellation mode for device {}: {}", mac_s, e);
|
||||
}
|
||||
}
|
||||
);
|
||||
let mut state = state_clone.clone();
|
||||
state.anc_mode = selected_mode.clone();
|
||||
Message::StateChanged(mac.to_string(), DeviceState::Nothing(state))
|
||||
}
|
||||
}
|
||||
)
|
||||
.width(Length::from(200))
|
||||
.input_style(
|
||||
|theme: &Theme, _status| {
|
||||
text_input::Style {
|
||||
background: Background::Color(theme.palette().primary.scale_alpha(0.2)),
|
||||
border: Border {
|
||||
width: 1.0,
|
||||
color: theme.palette().text.scale_alpha(0.3),
|
||||
radius: Radius::from(4.0)
|
||||
},
|
||||
icon: Default::default(),
|
||||
placeholder: theme.palette().text,
|
||||
value: theme.palette().text,
|
||||
selection: Default::default(),
|
||||
}
|
||||
}
|
||||
)
|
||||
.padding(iced::Padding{
|
||||
top: 5.0,
|
||||
bottom: 5.0,
|
||||
left: 10.0,
|
||||
right: 10.0,
|
||||
})
|
||||
.menu_style(
|
||||
|theme: &Theme| {
|
||||
menu::Style {
|
||||
background: Background::Color(theme.palette().background),
|
||||
border: Border {
|
||||
width: 1.0,
|
||||
color: theme.palette().text,
|
||||
radius: Radius::from(4.0)
|
||||
},
|
||||
text_color: theme.palette().text,
|
||||
selected_text_color: theme.palette().text,
|
||||
selected_background: Background::Color(theme.palette().primary.scale_alpha(0.3)),
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
]
|
||||
.align_y(iced::Alignment::Center)
|
||||
)
|
||||
.padding(iced::Padding{
|
||||
top: 5.0,
|
||||
bottom: 5.0,
|
||||
left: 18.0,
|
||||
right: 18.0,
|
||||
})
|
||||
.style(
|
||||
|theme: &Theme| {
|
||||
let mut style = container::Style::default();
|
||||
style.background = Some(Background::Color(theme.palette().primary.scale_alpha(0.1)));
|
||||
let mut border = Border::default();
|
||||
border.color = theme.palette().primary.scale_alpha(0.5);
|
||||
style.border = border.rounded(16);
|
||||
style
|
||||
}
|
||||
);
|
||||
|
||||
container(
|
||||
column![
|
||||
row![
|
||||
text("Noise Control Mode").size(18),
|
||||
Space::with_width(Length::Fill),
|
||||
// combobox here
|
||||
],
|
||||
noise_control_mode,
|
||||
Space::with_height(Length::from(20)),
|
||||
container(information_col)
|
||||
.style(
|
||||
|theme: &Theme| {
|
||||
@@ -79,18 +188,12 @@ pub fn nothing_view<'a>(
|
||||
.height(Length::Fill)
|
||||
}
|
||||
|
||||
|
||||
// if let Err(e) = manager.write(
|
||||
// ATTHandles::NothingEverything,
|
||||
// &[
|
||||
// 0x55,
|
||||
// 0x60, 0x01,
|
||||
// 0x0F, 0xF0,
|
||||
// 0x03, 0x00,
|
||||
// 0x00, 0x01, // the 0x00 is an incremental counter, but it works without it
|
||||
// mode.to_byte(), 0x00,
|
||||
// 0x00, 0x00 // these both bytes were something random, 0 works too
|
||||
// ]
|
||||
// ).await {
|
||||
// log::error!("Failed to set noise cancellation mode for device {}: {}", mac, e);
|
||||
// }
|
||||
fn run_async_in_thread<F>(fut: F)
|
||||
where
|
||||
F: Future<Output = ()> + Send + 'static,
|
||||
{
|
||||
thread::spawn(move || {
|
||||
let rt = Runtime::new().unwrap();
|
||||
rt.block_on(fut);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -341,6 +341,14 @@ impl App {
|
||||
Some(DeviceType::Nothing) => {
|
||||
self.device_states.insert(mac.clone(), DeviceState::Nothing(NothingState {
|
||||
anc_mode: NothingAncMode::Off,
|
||||
anc_mode_state: combo_box::State::new(vec![
|
||||
NothingAncMode::Off,
|
||||
NothingAncMode::Transparency,
|
||||
NothingAncMode::AdaptiveNoiseCancellation,
|
||||
NothingAncMode::LowNoiseCancellation,
|
||||
NothingAncMode::MidNoiseCancellation,
|
||||
NothingAncMode::HighNoiseCancellation
|
||||
]),
|
||||
}));
|
||||
}
|
||||
_ => {}
|
||||
@@ -444,6 +452,9 @@ impl App {
|
||||
}
|
||||
BluetoothUIMessage::ATTNotification(mac, handle, value) => {
|
||||
debug!("ATT Notification for {}: handle=0x{:04X}, value={:?}", mac, handle, value);
|
||||
|
||||
// TODO: Handle Nothing's ANC Mode changes here
|
||||
|
||||
let ui_rx = Arc::clone(&self.ui_rx);
|
||||
let wait_task = Task::perform(
|
||||
wait_for_message(ui_rx),
|
||||
|
||||
Reference in New Issue
Block a user