From e0017c40be3723042781b1025fc3cc5446a882e0 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Fri, 20 Sep 2024 17:37:43 +0100 Subject: [PATCH] crypto: FFI bindings for subscribe_to_identity_status_changes --- .../src/identity_status_change.rs | 31 +++++++++++++ bindings/matrix-sdk-ffi/src/lib.rs | 1 + bindings/matrix-sdk-ffi/src/room.rs | 45 ++++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 bindings/matrix-sdk-ffi/src/identity_status_change.rs diff --git a/bindings/matrix-sdk-ffi/src/identity_status_change.rs b/bindings/matrix-sdk-ffi/src/identity_status_change.rs new file mode 100644 index 00000000000..2da290466ae --- /dev/null +++ b/bindings/matrix-sdk-ffi/src/identity_status_change.rs @@ -0,0 +1,31 @@ +// Copyright 2024 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[derive(uniffi::Record)] +pub struct IdentityStatusChange { + /// The user ID of the user whose identity status changed + pub user_id: String, + + /// The new state of the identity of the user. One of: + /// + /// * Verified + /// * Pinned + /// * PinViolation + /// * PreviouslyVerified + /// + /// See + /// [`matrix_sdk_crypto::identities::room_identity_state::RoomIdentityState`] + /// for details. + pub changed_to: String, +} diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index f475f7e862d..d74f62011a9 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -29,6 +29,7 @@ mod encryption; mod error; mod event; mod helpers; +mod identity_status_change; mod notification; mod notification_settings; mod platform; diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index c736007e381..9bf99dab4a9 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -1,6 +1,7 @@ -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, pin::pin, sync::Arc}; use anyhow::{Context, Result}; +use futures_util::StreamExt; use matrix_sdk::{ crypto::LocalTrust, event_cache::paginator::PaginatorError, @@ -35,6 +36,7 @@ use crate::{ chunk_iterator::ChunkIterator, error::{ClientError, MediaInfoError, RoomError}, event::{MessageLikeEventType, StateEventType}, + identity_status_change::IdentityStatusChange, room_info::RoomInfo, room_member::RoomMember, ruma::{ImageInfo, Mentions, NotifyType}, @@ -582,6 +584,42 @@ impl Room { }))) } + pub fn subscribe_to_identity_status_changes( + &self, + listener: Box, + ) -> Arc { + let room = self.inner.clone(); + Arc::new(TaskHandle::new(RUNTIME.spawn(async move { + let status_changes = room.subscribe_to_identity_status_changes().await; + if let Ok(status_changes) = status_changes { + // TODO: what to do with failures? + let mut status_changes = pin!(status_changes); + while let Some(identity_status_changes) = status_changes.next().await { + listener.call( + identity_status_changes + .iter() + .map(|change| { + let user_id = change.user_id.to_string(); + let changed_to = match change.changed_to { + matrix_sdk::crypto::IdentityState::Verified => "Verified", + matrix_sdk::crypto::IdentityState::Pinned => "Pinned", + matrix_sdk::crypto::IdentityState::PinViolation => { + "PinViolation" + } + matrix_sdk::crypto::IdentityState::PreviouslyVerified => { + "PreviouslyVerified" + } + } + .to_owned(); + IdentityStatusChange { user_id, changed_to } + }) + .collect(), + ); + } + } + }))) + } + /// Set (or unset) a flag on the room to indicate that the user has /// explicitly marked it as unread. pub async fn set_unread_flag(&self, new_value: bool) -> Result<(), ClientError> { @@ -898,6 +936,11 @@ pub trait TypingNotificationsListener: Sync + Send { fn call(&self, typing_user_ids: Vec); } +#[uniffi::export(callback_interface)] +pub trait IdentityStatusChangeListener: Sync + Send { + fn call(&self, identity_status_change: Vec); +} + #[derive(uniffi::Object)] pub struct RoomMembersIterator { chunk_iterator: ChunkIterator,