Look online to Empathy
It seems Empathy requires the ContactLists and Presence interfaces if it is to use your connection and show it as online. In addition, we were emitting the "connected" signal from the wrong source - it needed to have the object path of the specific connection, rather than the general connection object path. So now we can show as connected in Empathy, but we can't add a contact yet - presumably that's another interface. Sending a message to a connected deltachat account does nothing yet, as the message from deltachat-core is unhandled.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use crate::telepathy;
|
||||
use crate::telepathy::ConnectionInterfaceContacts;
|
||||
use dbus::blocking::{stdintf::org_freedesktop_dbus::RequestNameReply, LocalConnection};
|
||||
use dbus::channel::Sender;
|
||||
use dbus::message::SignalArgs;
|
||||
@@ -10,6 +11,7 @@ use dc::Event;
|
||||
use deltachat as dc;
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::convert::TryInto;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@@ -25,6 +27,7 @@ enum ConnState {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
// A Deltachast connection uses email addresses as handles, and delta's Db IDs
|
||||
pub struct Connection {
|
||||
id: String,
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
@@ -35,6 +38,23 @@ pub struct Connection {
|
||||
msgq: Arc<Mutex<VecDeque<dbus::Message>>>,
|
||||
}
|
||||
|
||||
pub fn connection_interfaces() -> Vec<String> {
|
||||
vec![
|
||||
"org.freedesktop.Telepathy.Connection".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Avatars".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Contacts".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Requests".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.SimplePresence".to_string(),
|
||||
]
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::Connection + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::Connection + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl Connection {
|
||||
pub fn new(params: HashMap<&str, super::Variant>) -> Result<Self, dbus::tree::MethodErr> {
|
||||
let err = Err(dbus::tree::MethodErr::no_arg());
|
||||
@@ -151,19 +171,34 @@ impl Connection {
|
||||
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 avatars_iface =
|
||||
telepathy::connection_interface_avatars_server(&f, (), move |_| c_rc2.clone());
|
||||
|
||||
let c_rc3 = c_rc.clone();
|
||||
let contacts_iface =
|
||||
telepathy::connection_interface_contacts_server(&f, (), move |_| c_rc3.clone());
|
||||
|
||||
let c_rc4 = c_rc.clone();
|
||||
let contact_list_iface =
|
||||
telepathy::connection_interface_contact_list_server(&f, (), move |_| c_rc4.clone());
|
||||
|
||||
let c_rc5 = c_rc.clone();
|
||||
let requests_iface =
|
||||
telepathy::connection_interface_requests_server(&f, (), move |_| c_rc3.clone());
|
||||
telepathy::connection_interface_requests_server(&f, (), move |_| c_rc5.clone());
|
||||
|
||||
let c_rc6 = c_rc.clone();
|
||||
let simple_presence_iface =
|
||||
telepathy::connection_interface_simple_presence_server(&f, (), move |_| c_rc6.clone());
|
||||
|
||||
tree = tree.add(
|
||||
f.object_path(path.clone(), ())
|
||||
.introspectable()
|
||||
.add(conn_iface)
|
||||
.add(avatars_iface)
|
||||
.add(contacts_iface)
|
||||
.add(requests_iface),
|
||||
.add(contact_list_iface)
|
||||
.add(requests_iface)
|
||||
.add(simple_presence_iface),
|
||||
);
|
||||
tree = tree.add(f.object_path("/", ()).introspectable());
|
||||
|
||||
@@ -229,24 +264,6 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::Connection + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::Connection + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
@@ -254,6 +271,7 @@ impl telepathy::Connection for Connection {
|
||||
|
||||
let inbox_ctx = self.ctx.clone();
|
||||
let state = self.state.clone();
|
||||
let id = self.id.clone();
|
||||
let _inbox_thread = thread::spawn(move || {
|
||||
while *state.read().unwrap() != ConnState::Disconnected {
|
||||
dc::job::perform_inbox_jobs(&inbox_ctx.read().unwrap());
|
||||
@@ -265,10 +283,13 @@ impl telepathy::Connection for Connection {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Connection<{}>::connect(): inbox thread exited", id);
|
||||
});
|
||||
|
||||
let smtp_ctx = self.ctx.clone();
|
||||
let state = self.state.clone();
|
||||
let id = self.id.clone();
|
||||
let _smtp_thread = thread::spawn(move || {
|
||||
while *state.read().unwrap() != ConnState::Disconnected {
|
||||
dc::job::perform_smtp_jobs(&smtp_ctx.read().unwrap());
|
||||
@@ -276,10 +297,13 @@ impl telepathy::Connection for Connection {
|
||||
dc::job::perform_smtp_idle(&smtp_ctx.read().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
println!("Connection<{}>::connect(): smtp thread exited", id);
|
||||
});
|
||||
|
||||
let mvbox_ctx = self.ctx.clone();
|
||||
let state = self.state.clone();
|
||||
let id = self.id.clone();
|
||||
let _mvbox_thread = thread::spawn(move || {
|
||||
while *state.read().unwrap() != ConnState::Disconnected {
|
||||
dc::job::perform_mvbox_fetch(&mvbox_ctx.read().unwrap());
|
||||
@@ -287,10 +311,13 @@ impl telepathy::Connection for Connection {
|
||||
dc::job::perform_mvbox_idle(&mvbox_ctx.read().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
println!("Connection<{}>::connect(): mvbox thread exited", id);
|
||||
});
|
||||
|
||||
let sentbox_ctx = self.ctx.clone();
|
||||
let state = self.state.clone();
|
||||
let id = self.id.clone();
|
||||
let _sentbox_thread = thread::spawn(move || {
|
||||
while *state.read().unwrap() != ConnState::Disconnected {
|
||||
dc::job::perform_sentbox_fetch(&sentbox_ctx.read().unwrap());
|
||||
@@ -298,6 +325,8 @@ impl telepathy::Connection for Connection {
|
||||
dc::job::perform_sentbox_idle(&sentbox_ctx.read().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
println!("Connection<{}>::connect(): sentbox thread exited", id);
|
||||
});
|
||||
|
||||
// Just pretend to be connected all the time for now. Tracking IMAP+SMTP
|
||||
@@ -306,14 +335,14 @@ impl telepathy::Connection for Connection {
|
||||
let mut w = state.write().unwrap();
|
||||
*w = ConnState::Connected;
|
||||
|
||||
// Emit a NewConnection signal for the benefit of others, but the caller
|
||||
// Emit a StatusChanged signal for the benefit of others, but the caller
|
||||
// learns from our RPC response
|
||||
let sig = telepathy::ConnectionStatusChanged {
|
||||
status: 0, // Connected
|
||||
reason: 1, // Requested
|
||||
};
|
||||
|
||||
let dbus_conn_path = dbus::strings::Path::new(CONN_OBJECT_PATH.to_string())
|
||||
let dbus_conn_path = dbus::strings::Path::new(self.path().to_string())
|
||||
.expect("Object path should meet DBUS requirements");
|
||||
|
||||
self.msgq
|
||||
@@ -347,10 +376,7 @@ impl telepathy::Connection for Connection {
|
||||
fn get_interfaces(&self) -> Result<Vec<String>, tree::MethodErr> {
|
||||
println!("Connection<{}>::get_interfaces()", self.id);
|
||||
|
||||
Ok(vec![
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Contacts".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Requests".to_string(),
|
||||
])
|
||||
Ok(connection_interfaces())
|
||||
}
|
||||
|
||||
fn get_protocol(&self) -> Result<String, tree::MethodErr> {
|
||||
@@ -368,7 +394,7 @@ impl telepathy::Connection for Connection {
|
||||
fn get_self_handle(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::get_self_handle()", self.id);
|
||||
|
||||
Ok(deltachat::constants::DC_CONTACT_ID_SELF)
|
||||
Ok(dc::constants::DC_CONTACT_ID_SELF)
|
||||
}
|
||||
|
||||
fn status(&self) -> Result<u32, tree::MethodErr> {
|
||||
@@ -389,7 +415,9 @@ impl telepathy::Connection for Connection {
|
||||
"Connection<{}>::hold_handles({}, {:?})",
|
||||
self.id, handle_type, handles
|
||||
);
|
||||
Err(tree::MethodErr::no_arg()) // FIXME: should be NotImplemented?
|
||||
|
||||
// Since HasImmortalHandles is true, this doesn't need to do anything
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inspect_handles(
|
||||
@@ -416,7 +444,9 @@ impl telepathy::Connection for Connection {
|
||||
"Connection<{}>::release_handles({}, {:?})",
|
||||
self.id, handle_type, handles
|
||||
);
|
||||
Err(tree::MethodErr::no_arg()) // FIXME: should be NotImplemented?
|
||||
|
||||
// Since HasImmortalHandles is true, we don't need to do anything
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn request_channel(
|
||||
@@ -461,7 +491,18 @@ impl telepathy::Connection for Connection {
|
||||
fn self_id(&self) -> Result<String, tree::MethodErr> {
|
||||
println!("Connection<{}>::self_id()", self.id);
|
||||
|
||||
Ok("Yourself".to_string()) // FIXME: this could be passed through config
|
||||
let contact = match dc::contact::Contact::get_by_id(
|
||||
&self.ctx.read().unwrap(),
|
||||
dc::constants::DC_CONTACT_ID_SELF,
|
||||
) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!(" err: {}", e);
|
||||
return Err(tree::MethodErr::no_arg());
|
||||
}
|
||||
};
|
||||
|
||||
Ok(contact.get_addr().to_string())
|
||||
}
|
||||
|
||||
fn has_immortal_handles(&self) -> Result<bool, tree::MethodErr> {
|
||||
@@ -471,6 +512,107 @@ impl telepathy::Connection for Connection {
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceAvatars + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceAvatars + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: come back and do this properly, I'm just putting it in for consistency
|
||||
impl telepathy::ConnectionInterfaceAvatars for Connection {
|
||||
fn get_avatar_requirements(
|
||||
&self,
|
||||
) -> Result<(Vec<String>, u16, u16, u16, u16, u32), tree::MethodErr> {
|
||||
println!("Connection<{}>::get_avatar_requirements()", self.id);
|
||||
Ok((vec![], 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
fn get_avatar_tokens(&self, contacts: Vec<u32>) -> Result<Vec<String>, tree::MethodErr> {
|
||||
println!("Connection<{}>::get_avatar_tokens({:?})", self.id, contacts);
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn get_known_avatar_tokens(
|
||||
&self,
|
||||
contacts: Vec<u32>,
|
||||
) -> Result<::std::collections::HashMap<u32, String>, tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::get_known_avatar_tokens({:?})",
|
||||
self.id, contacts
|
||||
);
|
||||
Ok(HashMap::<u32, String>::new())
|
||||
}
|
||||
|
||||
fn request_avatar(&self, contact: u32) -> Result<(Vec<u8>, String), tree::MethodErr> {
|
||||
println!("Connection<{}>::request_avatar({})", self.id, contact);
|
||||
Ok((vec![], "".to_string()))
|
||||
}
|
||||
|
||||
fn request_avatars(&self, contacts: Vec<u32>) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::request_avatar({:?})", self.id, contacts);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_avatar(&self, _avatar: Vec<u8>, mimetype: &str) -> Result<String, tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::set_avatar((data), {:?})",
|
||||
self.id, mimetype
|
||||
);
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
fn clear_avatar(&self) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::clear_avatar()", self.id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn supported_avatar_mimetypes(&self) -> Result<Vec<String>, tree::MethodErr> {
|
||||
println!("Connection<{}>::supported_avatar_mimetypes()", self.id);
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
fn minimum_avatar_height(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::minimum_avatar_height()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn minimum_avatar_width(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::minimum_avatar_width()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn recommended_avatar_height(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::recommended_avatar_height()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn recommended_avatar_width(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::recommended_avatar_width()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn maximum_avatar_height(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::maximum_avatar_height()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn maximum_avatar_width(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::maximum_avatar_width()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn maximum_avatar_bytes(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::maximum_avatar_bytes()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceContacts + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceContacts + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl telepathy::ConnectionInterfaceContacts for Connection {
|
||||
fn get_contact_attributes(
|
||||
&self,
|
||||
@@ -488,23 +630,33 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
|
||||
// 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.
|
||||
Err(_e) => continue, // Invalid IDs are silently ignored
|
||||
};
|
||||
|
||||
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())),
|
||||
arg::Variant(Box::new(contact.get_addr().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())),
|
||||
);
|
||||
|
||||
// TODO: we need to publish DBUS services on these endpoints
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Connection.Interface.ContactList/publish".to_string(),
|
||||
arg::Variant(Box::new(4)),
|
||||
);
|
||||
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Connection.Interface.ContactList/subscribe".to_string(),
|
||||
arg::Variant(Box::new(4)),
|
||||
);
|
||||
|
||||
out.insert(*id, props);
|
||||
}
|
||||
|
||||
@@ -532,7 +684,113 @@ impl telepathy::ConnectionInterfaceContacts for Connection {
|
||||
fn contact_attribute_interfaces(&self) -> Result<Vec<String>, tree::MethodErr> {
|
||||
println!("Connection<{}>::contact_attribute_interfaces()", self.id);
|
||||
|
||||
Ok(vec![])
|
||||
Ok(vec![
|
||||
"org.freedesktop.Telepathy.Connection".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Avatars".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.ContactList".to_string(),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceContactList + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceContactList + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: come back and do this properly later
|
||||
impl telepathy::ConnectionInterfaceContactList for Connection {
|
||||
fn get_contact_list_attributes(
|
||||
&self,
|
||||
interfaces: Vec<&str>,
|
||||
hold: bool,
|
||||
) -> Result<HashMap<u32, HashMap<String, super::Variant>>, tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::get_contact_list_attributes({:?}, {})",
|
||||
self.id, interfaces, hold
|
||||
);
|
||||
|
||||
let ids = match dc::contact::Contact::get_all(
|
||||
&self.ctx.read().unwrap(),
|
||||
dc::constants::DC_GCL_ADD_SELF.try_into().unwrap(),
|
||||
None::<String>,
|
||||
) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
println!(" err: {}", e);
|
||||
return Err(tree::MethodErr::no_arg());
|
||||
}
|
||||
};
|
||||
|
||||
self.get_contact_attributes(ids, vec![], true)
|
||||
}
|
||||
|
||||
fn request_subscription(
|
||||
&self,
|
||||
contacts: Vec<u32>,
|
||||
message: &str,
|
||||
) -> Result<(), tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::request_subscription({:?}, {})",
|
||||
self.id, contacts, message
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn authorize_publication(&self, contacts: Vec<u32>) -> Result<(), tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::authorize_publication({:?})",
|
||||
self.id, contacts
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
fn remove_contacts(&self, contacts: Vec<u32>) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::remove_contacts({:?})", self.id, contacts);
|
||||
Ok(())
|
||||
}
|
||||
fn unsubscribe(&self, contacts: Vec<u32>) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::unsubscribe({:?})", self.id, contacts);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unpublish(&self, contacts: Vec<u32>) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::unpublish({:?})", self.id, contacts);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn download(&self) -> Result<(), tree::MethodErr> {
|
||||
println!("Connection<{}>::download()", self.id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn contact_list_state(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::contact_list_state()", self.id);
|
||||
Ok(3) // Success
|
||||
}
|
||||
|
||||
fn contact_list_persists(&self) -> Result<bool, tree::MethodErr> {
|
||||
println!("Connection<{}>::contact_list_persists()", self.id);
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn can_change_contact_list(&self) -> Result<bool, tree::MethodErr> {
|
||||
println!("Connection<{}>::can_change_contact_list()", self.id);
|
||||
Ok(false)
|
||||
}
|
||||
fn request_uses_message(&self) -> Result<bool, tree::MethodErr> {
|
||||
println!("Connection<{}>::request_uses_message()", self.id);
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn download_at_connection(&self) -> Result<bool, tree::MethodErr> {
|
||||
println!("Connection<{}>::download_at_connection()", self.id);
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceRequests + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceRequests + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,6 +851,68 @@ impl telepathy::ConnectionInterfaceRequests for Connection {
|
||||
}
|
||||
}
|
||||
|
||||
pub type SimplePresenceSpec = (
|
||||
u32, // connection presence type
|
||||
String, // status
|
||||
String, // status message
|
||||
);
|
||||
|
||||
pub type SimpleStatusSpec = (
|
||||
u32, // connection presence type
|
||||
bool, // may set on self?
|
||||
bool, // can have message?
|
||||
);
|
||||
|
||||
impl AsRef<dyn telepathy::ConnectionInterfaceSimplePresence + 'static> for std::rc::Rc<Connection> {
|
||||
fn as_ref(&self) -> &(dyn telepathy::ConnectionInterfaceSimplePresence + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl telepathy::ConnectionInterfaceSimplePresence for Connection {
|
||||
fn set_presence(&self, status: &str, status_message: &str) -> Result<(), tree::MethodErr> {
|
||||
println!(
|
||||
"Connection<{}>::set_presence({}, {:?})",
|
||||
self.id, status, status_message
|
||||
);
|
||||
|
||||
// FIXME: emit a presence changed signal
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_presences(
|
||||
&self,
|
||||
contacts: Vec<u32>,
|
||||
) -> Result<HashMap<u32, SimplePresenceSpec>, tree::MethodErr> {
|
||||
println!("Connection<{}>::get_presences({:?})", self.id, contacts);
|
||||
|
||||
let mut out = HashMap::<u32, SimplePresenceSpec>::new();
|
||||
|
||||
for id in contacts {
|
||||
out.insert(id, (2, "available".to_string(), "".to_string())); // Available
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn statuses(&self) -> Result<HashMap<String, SimpleStatusSpec>, tree::MethodErr> {
|
||||
println!("Connection<{}>::statuses()", self.id);
|
||||
|
||||
let mut out = HashMap::<String, SimpleStatusSpec>::new();
|
||||
|
||||
out.insert("available".to_string(), (2, true, false));
|
||||
out.insert("offline".to_string(), (1, true, false));
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn maximum_status_message_length(&self) -> Result<u32, tree::MethodErr> {
|
||||
println!("Connection<{}>::maximum_status_message_length()", self.id);
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_one(b: u8) -> String {
|
||||
format!("_{:0<2x}", b)
|
||||
}
|
||||
|
@@ -129,10 +129,7 @@ impl telepathy::ConnectionManager for ConnectionManager {
|
||||
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Protocol.ConnectionInterfaces".to_string(),
|
||||
arg::Variant(Box::new(vec![
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Contacts".to_string(),
|
||||
"org.freedesktop.Telepathy.Connection.Interface.Requests".to_string(),
|
||||
])),
|
||||
arg::Variant(Box::new(super::connection_interfaces())),
|
||||
);
|
||||
props.insert(
|
||||
"org.freedesktop.Telepathy.Protocol.EnglishName".to_string(),
|
||||
|
Reference in New Issue
Block a user