diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index ed96d5019..086813bfe 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -640,14 +640,12 @@ char* dc_get_connectivity_html (dc_context_t* context); #define DC_PUSH_NOT_CONNECTED 0 -#define DC_PUSH_HEARTBEAT 1 #define DC_PUSH_CONNECTED 2 /** * Get the current push notification state. * One of: * - DC_PUSH_NOT_CONNECTED - * - DC_PUSH_HEARTBEAT * - DC_PUSH_CONNECTED * * @memberof dc_context_t diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index d3ff6f42e..7d30eed34 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -398,7 +398,7 @@ pub unsafe extern "C" fn dc_get_push_state(context: *const dc_context_t) -> libc return 0; } let ctx = &*context; - block_on(ctx.push_state()) as libc::c_int + ctx.push_state() as libc::c_int } fn spawn_configure(ctx: Context) { @@ -5010,7 +5010,7 @@ pub unsafe extern "C" fn dc_accounts_set_push_device_token( block_on(async move { let accounts = accounts.read().await; - if let Err(err) = accounts.set_push_device_token(&token).await { + if let Err(err) = accounts.set_push_device_token(&token) { accounts.emit_event(EventType::Error(format!( "Failed to set notify token: {err:#}." ))); diff --git a/deltachat-jsonrpc/src/api.rs b/deltachat-jsonrpc/src/api.rs index 788a220f7..3b16483b8 100644 --- a/deltachat-jsonrpc/src/api.rs +++ b/deltachat-jsonrpc/src/api.rs @@ -333,7 +333,7 @@ impl CommandApi { /// Get the current push notification state. async fn get_push_state(&self, account_id: u32) -> Result { let ctx = self.get_context(account_id).await?; - Ok(ctx.push_state().await.into()) + Ok(ctx.push_state().into()) } /// Get the combined filesize of an account in bytes diff --git a/deltachat-jsonrpc/src/api/types/notify_state.rs b/deltachat-jsonrpc/src/api/types/notify_state.rs index 027f0ee23..1ede71169 100644 --- a/deltachat-jsonrpc/src/api/types/notify_state.rs +++ b/deltachat-jsonrpc/src/api/types/notify_state.rs @@ -8,9 +8,6 @@ pub enum JsonrpcNotifyState { /// Not subscribed to push notifications. NotConnected, - /// Subscribed to heartbeat push notifications. - Heartbeat, - /// Subscribed to push notifications for new messages. Connected, } @@ -19,7 +16,6 @@ impl From for JsonrpcNotifyState { fn from(state: NotifyState) -> Self { match state { NotifyState::NotConnected => Self::NotConnected, - NotifyState::Heartbeat => Self::Heartbeat, NotifyState::Connected => Self::Connected, } } diff --git a/deltachat-rpc-client/src/deltachat_rpc_client/const.py b/deltachat-rpc-client/src/deltachat_rpc_client/const.py index 581cf56a4..10d46dbce 100644 --- a/deltachat-rpc-client/src/deltachat_rpc_client/const.py +++ b/deltachat-rpc-client/src/deltachat_rpc_client/const.py @@ -250,7 +250,6 @@ class PushNotifyState(IntEnum): """Push notifications state.""" NOT_CONNECTED = 0 - HEARTBEAT = 1 CONNECTED = 2 diff --git a/src/accounts.rs b/src/accounts.rs index c825c2d15..1efaa63d1 100644 --- a/src/accounts.rs +++ b/src/accounts.rs @@ -534,8 +534,8 @@ impl Accounts { } /// Sets notification token for Apple Push Notification service. - pub async fn set_push_device_token(&self, token: &str) -> Result<()> { - self.push_subscriber.set_device_token(token).await; + pub fn set_push_device_token(&self, token: &str) -> Result<()> { + self.push_subscriber.set_device_token(token); Ok(()) } diff --git a/src/context.rs b/src/context.rs index e9d2f538a..230395199 100644 --- a/src/context.rs +++ b/src/context.rs @@ -293,8 +293,7 @@ pub struct InnerContext { /// because the lock is used from synchronous [`Context::emit_event`]. pub(crate) debug_logging: std::sync::RwLock>, - /// Push subscriber to store device token - /// and register for heartbeat notifications. + /// Push subscriber to store device token. pub(crate) push_subscriber: PushSubscriber, /// True if account has subscribed to push notifications via IMAP. diff --git a/src/imap.rs b/src/imap.rs index 03fd07203..fdcdb1c32 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1474,7 +1474,7 @@ impl Session { let transport_id = self.transport_id(); - let Some(device_token) = context.push_subscriber.device_token().await else { + let Some(device_token) = context.push_subscriber.device_token() else { return Ok(()); }; @@ -1547,10 +1547,6 @@ impl Session { context.push_subscribed.store(true, Ordering::Relaxed); } - } else if !context.push_subscriber.heartbeat_subscribed().await { - let context = context.clone(); - // Subscribe for heartbeat notifications. - tokio::spawn(async move { context.push_subscriber.subscribe(&context).await }); } Ok(()) diff --git a/src/net/http.rs b/src/net/http.rs index af86dfa41..aaaa4599d 100644 --- a/src/net/http.rs +++ b/src/net/http.rs @@ -423,35 +423,6 @@ pub(crate) async fn post_empty(context: &Context, url: &str) -> Result<(String, Ok((response_text, response_status.is_success())) } -/// Posts string to the given URL. -/// -/// Returns true if successful HTTP response code was returned. -/// -/// Does not follow redirects. -#[allow(dead_code)] -pub(crate) async fn post_string(context: &Context, url: &str, body: String) -> Result { - let parsed_url = url - .parse::() - .with_context(|| format!("Failed to parse URL {url:?}"))?; - let scheme = parsed_url.scheme_str().context("URL has no scheme")?; - if scheme != "https" { - bail!("POST requests to non-HTTPS URLs are not allowed"); - } - - let mut sender = get_http_sender(context, parsed_url.clone(), true).await?; - let authority = parsed_url - .authority() - .context("URL has no authority")? - .clone(); - - let request = hyper::Request::post(parsed_url) - .header(hyper::header::HOST, authority.as_str()) - .body(body)?; - let response = sender.send_request(request).await?; - - Ok(response.status().is_success()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/push.rs b/src/push.rs index 8c7580c85..d61522d17 100644 --- a/src/push.rs +++ b/src/push.rs @@ -13,7 +13,6 @@ use anyhow::{Context as _, Result}; use base64::Engine as _; use pgp::crypto::aead::{AeadAlgorithm, ChunkSize}; use pgp::crypto::sym::SymmetricKeyAlgorithm; -use tokio::sync::RwLock; use crate::context::Context; use crate::key::DcKey; @@ -27,13 +26,9 @@ use crate::key::DcKey; /// /// Each account (context) can then retrieve device token /// from this structure and give it to the email server. -/// If email server does not support push notifications, -/// account can call `subscribe` method -/// to register device token with the heartbeat -/// notification provider server as a fallback. #[derive(Debug, Clone, Default)] pub struct PushSubscriber { - inner: Arc>, + device_token: Arc>>, } /// The key was generated with @@ -103,8 +98,8 @@ impl PushSubscriber { /// Sets device token for Apple Push Notification service /// or Firebase Cloud Messaging. - pub(crate) async fn set_device_token(&self, token: &str) { - self.inner.write().await.device_token = Some(token.to_string()); + pub(crate) fn set_device_token(&self, token: &str) { + *self.device_token.write() = Some(token.to_string()); } /// Retrieves device token. @@ -117,59 +112,9 @@ impl PushSubscriber { /// /// IMAP loop should periodically check if device token is available /// and send the token to the email server if it supports push notifications. - pub(crate) async fn device_token(&self) -> Option { - self.inner.read().await.device_token.clone() + pub(crate) fn device_token(&self) -> Option { + self.device_token.read().clone() } - - /// Subscribes for heartbeat notifications with previously set device token. - #[cfg(target_os = "ios")] - pub(crate) async fn subscribe(&self, context: &Context) -> Result<()> { - use crate::net::http; - - let mut state = self.inner.write().await; - - if state.heartbeat_subscribed { - return Ok(()); - } - - let Some(ref token) = state.device_token else { - return Ok(()); - }; - - info!(context, "Subscribing for heartbeat notifications."); - if http::post_string( - context, - "https://notifications.delta.chat/register", - format!("{{\"token\":\"{token}\"}}"), - ) - .await? - { - info!(context, "Subscribed for heartbeat notifications."); - state.heartbeat_subscribed = true; - } - Ok(()) - } - - /// Placeholder to skip subscribing to heartbeat notifications outside iOS. - #[cfg(not(target_os = "ios"))] - pub(crate) async fn subscribe(&self, _context: &Context) -> Result<()> { - let mut state = self.inner.write().await; - state.heartbeat_subscribed = true; - Ok(()) - } - - pub(crate) async fn heartbeat_subscribed(&self) -> bool { - self.inner.read().await.heartbeat_subscribed - } -} - -#[derive(Debug, Default)] -pub(crate) struct PushSubscriberState { - /// Device token. - device_token: Option, - - /// If subscribed to heartbeat push notifications. - heartbeat_subscribed: bool, } /// Push notification state @@ -180,20 +125,15 @@ pub enum NotifyState { #[default] NotConnected = 0, - /// Subscribed to heartbeat push notifications. - Heartbeat = 1, - /// Subscribed to push notifications for new messages. Connected = 2, } impl Context { /// Returns push notification subscriber state. - pub async fn push_state(&self) -> NotifyState { + pub fn push_state(&self) -> NotifyState { if self.push_subscribed.load(Ordering::Relaxed) { NotifyState::Connected - } else if self.push_subscriber.heartbeat_subscribed().await { - NotifyState::Heartbeat } else { NotifyState::NotConnected } @@ -204,13 +144,13 @@ impl Context { mod tests { use super::*; - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_set_device_token() { + #[test] + fn test_set_device_token() { let push_subscriber = PushSubscriber::new(); - assert_eq!(push_subscriber.device_token().await, None); + assert_eq!(push_subscriber.device_token(), None); - push_subscriber.set_device_token("some-token").await; - let device_token = push_subscriber.device_token().await.unwrap(); + push_subscriber.set_device_token("some-token"); + let device_token = push_subscriber.device_token().unwrap(); assert_eq!(device_token, "some-token"); }