matrix_sdk_ffi/
sync_service.rs1use std::{fmt::Debug, sync::Arc};
16
17use futures_util::pin_mut;
18use matrix_sdk::Client;
19use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm};
20use matrix_sdk_ui::{
21 sync_service::{
22 State as MatrixSyncServiceState, SyncService as MatrixSyncService,
23 SyncServiceBuilder as MatrixSyncServiceBuilder,
24 },
25 unable_to_decrypt_hook::UtdHookManager,
26};
27
28use crate::{
29 error::ClientError, helpers::unwrap_or_clone_arc, room_list::RoomListService,
30 runtime::get_runtime_handle, TaskHandle,
31};
32
33#[derive(uniffi::Enum)]
34pub enum SyncServiceState {
35 Idle,
36 Running,
37 Terminated,
38 Error,
39 Offline,
40}
41
42impl From<MatrixSyncServiceState> for SyncServiceState {
43 fn from(value: MatrixSyncServiceState) -> Self {
44 match value {
45 MatrixSyncServiceState::Idle => Self::Idle,
46 MatrixSyncServiceState::Running => Self::Running,
47 MatrixSyncServiceState::Terminated => Self::Terminated,
48 MatrixSyncServiceState::Error(_error) => Self::Error,
49 MatrixSyncServiceState::Offline => Self::Offline,
50 }
51 }
52}
53
54#[matrix_sdk_ffi_macros::export(callback_interface)]
55pub trait SyncServiceStateObserver: SendOutsideWasm + SyncOutsideWasm + Debug {
56 fn on_update(&self, state: SyncServiceState);
57}
58
59#[derive(uniffi::Object)]
60pub struct SyncService {
61 pub(crate) inner: Arc<MatrixSyncService>,
62 utd_hook: Option<Arc<UtdHookManager>>,
63}
64
65#[matrix_sdk_ffi_macros::export]
66impl SyncService {
67 pub fn room_list_service(&self) -> Arc<RoomListService> {
68 Arc::new(RoomListService {
69 inner: self.inner.room_list_service(),
70 utd_hook: self.utd_hook.clone(),
71 })
72 }
73
74 pub async fn start(&self) {
75 self.inner.start().await
76 }
77
78 pub async fn stop(&self) {
79 self.inner.stop().await
80 }
81
82 pub fn state(&self, listener: Box<dyn SyncServiceStateObserver>) -> Arc<TaskHandle> {
83 let state_stream = self.inner.state();
84
85 Arc::new(TaskHandle::new(get_runtime_handle().spawn(async move {
86 pin_mut!(state_stream);
87
88 while let Some(state) = state_stream.next().await {
89 listener.on_update(state.into());
90 }
91 })))
92 }
93
94 pub async fn expire_sessions(&self) {
100 self.inner.expire_sessions().await;
101 }
102}
103
104#[derive(Clone, uniffi::Object)]
105pub struct SyncServiceBuilder {
106 builder: MatrixSyncServiceBuilder,
107 utd_hook: Option<Arc<UtdHookManager>>,
108}
109
110impl SyncServiceBuilder {
111 pub(crate) fn new(client: Client, utd_hook: Option<Arc<UtdHookManager>>) -> Arc<Self> {
112 Arc::new(Self { builder: MatrixSyncService::builder(client), utd_hook })
113 }
114}
115
116#[matrix_sdk_ffi_macros::export]
117impl SyncServiceBuilder {
118 pub fn with_cross_process_lock(self: Arc<Self>) -> Arc<Self> {
119 let this = unwrap_or_clone_arc(self);
120 let builder = this.builder.with_cross_process_lock();
121 Arc::new(Self { builder, ..this })
122 }
123
124 pub fn with_offline_mode(self: Arc<Self>) -> Arc<Self> {
126 let this = unwrap_or_clone_arc(self);
127 let builder = this.builder.with_offline_mode();
128 Arc::new(Self { builder, ..this })
129 }
130
131 pub fn with_share_pos(self: Arc<Self>, enable: bool) -> Arc<Self> {
132 let this = unwrap_or_clone_arc(self);
133 let builder = this.builder.with_share_pos(enable);
134 Arc::new(Self { builder, ..this })
135 }
136
137 pub async fn finish(self: Arc<Self>) -> Result<Arc<SyncService>, ClientError> {
138 let this = unwrap_or_clone_arc(self);
139 Ok(Arc::new(SyncService {
140 inner: Arc::new(this.builder.build().await?),
141 utd_hook: this.utd_hook,
142 }))
143 }
144}