Implement some contact and request interfaces
Empathy still isn't happy, but it's going to take some debugging to work out why. I suspect it requires one of the "optional" interfaces in practice... but which one?
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::telepathy;
|
||||
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
|
||||
use dbus::channel::Sender;
|
||||
use dbus::message::SignalArgs;
|
||||
use dbus::tree;
|
||||
use dbus::{arg, tree};
|
||||
|
||||
use dc::config::Config;
|
||||
use dc::context::Context;
|
||||
@@ -68,7 +68,8 @@ impl Connection {
|
||||
let msgq = Arc::new(Mutex::new(VecDeque::<dbus::Message>::new()));
|
||||
|
||||
let id2 = id.clone();
|
||||
let msgq2 = msgq.clone();
|
||||
// Use this if we need to send messages in response to DC events:
|
||||
// let msgq2 = msgq.clone();
|
||||
let f = move |_c: &Context, e: Event| {
|
||||
match e {
|
||||
Event::Info(msg) => println!("Connection<{}>: INFO: {}", id2, msg),
|
||||
@@ -144,11 +145,26 @@ impl Connection {
|
||||
let c_rc = std::rc::Rc::new(self);
|
||||
|
||||
let f = tree::Factory::new_fn::<()>();
|
||||
let iface = telepathy::connection_server(&f, (), move |_| c_rc.clone());
|
||||
|
||||
let mut tree = f.tree(());
|
||||
tree = tree.add(f.object_path(path, ()).introspectable().add(iface));
|
||||
|
||||
let c_rc1 = c_rc.clone();
|
||||
let conn_iface = telepathy::connection_server(&f, (), move |_| c_rc1.clone());
|
||||
|
||||
let c_rc2 = c_rc.clone();
|
||||
let contacts_iface =
|
||||
telepathy::connection_interface_contacts_server(&f, (), move |_| c_rc2.clone());
|
||||
|
||||
let c_rc3 = c_rc.clone();
|
||||
let requests_iface =
|
||||
telepathy::connection_interface_requests_server(&f, (), move |_| c_rc3.clone());
|
||||
|
||||
tree = tree.add(
|
||||
f.object_path(path.clone(), ())
|
||||
.introspectable()
|
||||
.add(conn_iface)
|
||||
.add(contacts_iface)
|
||||
.add(requests_iface),
|
||||
);
|
||||
tree = tree.add(f.object_path("/", ()).introspectable());
|
||||
|
||||
// Setup DBus connection
|
||||
@@ -219,6 +235,18 @@ impl AsRef<dyn telepathy::Connection + 'static> for std::rc::Rc<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceContacts + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceContacts + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceRequests + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceRequests + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl telepathy::Connection for Connection {
|
||||
// In connect(), we start the threads that drive the deltachat context
|
||||
fn connect(&self) -> Result<(), tree::MethodErr> {
|
||||
@@ -443,6 +471,128 @@ impl telepathy::Connection for Connection {
|
||||
}
|
||||
}
|
||||
|
||||
impl telepathy::ConnectionInterfaceContacts for Connection {
|
||||
fn get_contact_attributes(
|
||||
&self,
|
||||
handles: Vec<u32>,
|
||||
interfaces: Vec<&str>,
|
||||
hold: bool,
|
||||
) -> Result<HashMap<u32, HashMap<String, super::Variant>>, tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::get_contact_attributes({:?}, {:?}, {})",
|
||||
self.id, handles, interfaces, hold
|
||||
);
|
||||
|
||||
let mut out = HashMap::<u32, HashMap<String, super::Variant>>::new();
|
||||
for id in handles.iter() {
|
||||
// FIXME: work out how to use get_all
|
||||
let contact = match dc::contact::Contact::get_by_id(&self.ctx.read().unwrap(), *id) {
|
||||
Ok(c) => c,
|
||||
Err(_e) => continue, // FIXME: Ignore the error. Whatevs.
|
||||
};
|
||||
|
||||
let mut props = HashMap::<String, super::Variant>::new();
|
||||
// This is mandatory
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Connection/contact-id".to_string(),
|
||||
arg::Variant(Box::new(contact.get_display_name().to_string())),
|
||||
);
|
||||
|
||||
// We don't advertise this interface but empathy is being weird.
|
||||
// The empty string means "no avatar"
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Avatars/token".to_string(),
|
||||
arg::Variant(Box::new("".to_string())),
|
||||
);
|
||||
|
||||
out.insert(*id, props);
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn get_contact_by_id(
|
||||
&self,
|
||||
identifier: &str,
|
||||
interfaces: Vec<&str>,
|
||||
) -> Result<
|
||||
(
|
||||
u32,
|
||||
::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>,
|
||||
),
|
||||
tree::MethodErr,
|
||||
> {
|
||||
println!(
|
||||
"Connection<{}>::get_contact_by_id({}, {:?})",
|
||||
self.id, identifier, interfaces
|
||||
);
|
||||
Err(tree::MethodErr::no_arg()) // FIXME: should be NotImplemented?
|
||||
}
|
||||
|
||||
fn contact_attribute_interfaces(&self) -> Result<Vec<String>, tree::MethodErr> {
|
||||
println!("Connection<{}>::contact_attribute_interfaces()", self.id);
|
||||
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
impl telepathy::ConnectionInterfaceRequests for Connection {
|
||||
fn create_channel(
|
||||
&self,
|
||||
request: ::std::collections::HashMap<&str, arg::Variant<Box<dyn arg::RefArg>>>,
|
||||
) -> Result<
|
||||
(
|
||||
dbus::Path<'static>,
|
||||
::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>,
|
||||
),
|
||||
tree::MethodErr,
|
||||
> {
|
||||
println!("Connection<{}>::create_channel({:?})", self.id, request);
|
||||
Err(tree::MethodErr::no_arg()) // FIXME: should be NotImplemented?
|
||||
}
|
||||
|
||||
fn ensure_channel(
|
||||
&self,
|
||||
request: ::std::collections::HashMap<&str, arg::Variant<Box<dyn arg::RefArg>>>,
|
||||
) -> Result<
|
||||
(
|
||||
bool,
|
||||
dbus::Path<'static>,
|
||||
::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>,
|
||||
),
|
||||
tree::MethodErr,
|
||||
> {
|
||||
println!("Connection<{}>::ensure_channel({:?})", self.id, request);
|
||||
Err(tree::MethodErr::no_arg()) // FIXME: should be NotImplemented?
|
||||
}
|
||||
|
||||
fn channels(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
dbus::Path<'static>,
|
||||
::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>,
|
||||
)>,
|
||||
tree::MethodErr,
|
||||
> {
|
||||
println!("Connection<{}>::channels()", self.id);
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn requestable_channel_classes(
|
||||
&self,
|
||||
) -> Result<
|
||||
Vec<(
|
||||
::std::collections::HashMap<String, arg::Variant<Box<dyn arg::RefArg + 'static>>>,
|
||||
Vec<String>,
|
||||
)>,
|
||||
tree::MethodErr,
|
||||
> {
|
||||
println!("Connection<{}>::requestable_channel_classes()", self.id);
|
||||
Ok(super::requestables())
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_one(b: u8) -> String {
|
||||
format!("_{:0<2x}", b)
|
||||
}
|
||||
|
Reference in New Issue
Block a user