Skip to content

Commit a3cb1cd

Browse files
authored
Merge branch 'main' into rav/history_sharing/save_key_bundle_data
2 parents 85e0626 + 1554e05 commit a3cb1cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1447
-408
lines changed

.github/workflows/detect-long-path.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- uses: actions/checkout@v4
2626
- name: Check for changed files
2727
id: changed-files
28-
uses: tj-actions/changed-files@9b4bb2bedb217d3ede225b6b07ebde713177cd8f # v45
28+
uses: tj-actions/changed-files@c34c1c13a740b06851baff92ab9a653d93ad6ce7 # v45
2929
- name: Detect long path
3030
env:
3131
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} # ignore the deleted files

CONTRIBUTING.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ cargo insta test
5757
cargo insta review
5858
```
5959

60+
### Intermittent failure policy
61+
62+
While we strive to add test coverage for as many features as we can, it sometimes happens that the
63+
tests will be intermittently failing in CI (such tests are sometimes called "flaky"). This can be
64+
caused by race conditions of all sorts, either in the test code itself, but sometimes in the
65+
underlying feature being tested too, and as such, it requires some investigation, usually from the
66+
original author of the test.
67+
68+
Whenever such an intermittent failure happens, we try to open an issue to track the failures,
69+
adding the
70+
[`intermittent-failure`](https://github.com/matrix-org/matrix-rust-sdk/issues?q=is%3Aissue%20state%3Aopen%20label%3Aintermittent-failure)
71+
label to it, and commenting with links to CI runs where the failure happened.
72+
73+
If a test has been intermittently failing for **two weeks** or more, and no one is actively working
74+
on fixing it, then we might decide to mark the test as `ignored` until it is fixed, to not cause
75+
unrelated failures in other contributors' pull requests and pushes.
76+
6077
## Pull requests
6178

6279
Ideally, a PR should have a *proper title*, with *atomic logical commits*, and

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindings/matrix-sdk-crypto-ffi/src/machine.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,10 @@ impl OlmMachine {
554554
}),
555555
)?;
556556

557-
let to_device_events =
558-
to_device_events.into_iter().map(|event| event.json().get().to_owned()).collect();
557+
let to_device_events = to_device_events
558+
.into_iter()
559+
.map(|event| event.to_raw().json().get().to_owned())
560+
.collect();
559561
let room_key_infos = room_key_infos.into_iter().map(|info| info.into()).collect();
560562

561563
Ok(SyncChangesResult { to_device_events, room_key_infos })

bindings/matrix-sdk-ffi/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Additions:
1010

1111
- Add room topic string to `StateEventContent`
1212

13+
Breaking changes:
14+
15+
- `contacts` has been removed from `OidcConfiguration` (it was unused since the switch to OAuth).
16+
1317
## [0.11.0] - 2025-04-11
1418

1519
Breaking changes:

bindings/matrix-sdk-ffi/src/authentication.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,6 @@ pub struct OidcConfiguration {
119119
pub tos_uri: Option<String>,
120120
/// A URI that contains the client's privacy policy.
121121
pub policy_uri: Option<String>,
122-
/// An array of e-mail addresses of people responsible for this client.
123-
pub contacts: Option<Vec<String>>,
124122

125123
/// Pre-configured registrations for use with homeservers that don't support
126124
/// dynamic client registration.

crates/matrix-sdk-base/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ All notable changes to this project will be documented in this file.
4040
- [**breaking**] `BaseClient::set_session_metadata` is renamed
4141
`activate`, and `BaseClient::logged_in` is renamed `is_activated`
4242
([#4850](https://github.com/matrix-org/matrix-rust-sdk/pull/4850))
43+
- [**breaking] `DependentQueuedRequestKind::UploadFileWithThumbnail`
44+
was renamed to `DependentQueuedRequestKind::UploadFileOrThumbnail`.
45+
Under the `unstable-msc4274` feature, `DependentQueuedRequestKind::UploadFileOrThumbnail`
46+
and `SentMediaInfo` were generalized to allow chaining multiple dependent
47+
file / thumbnail uploads.
48+
([#4897](https://github.com/matrix-org/matrix-rust-sdk/pull/4897))
4349

4450
## [0.10.0] - 2025-02-04
4551

crates/matrix-sdk-base/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ testing = [
4343
"matrix-sdk-crypto?/testing",
4444
]
4545

46+
# Add support for inline media galleries via msgtypes
47+
unstable-msc4274 = []
48+
4649
[dependencies]
4750
as_variant = { workspace = true }
4851
assert_matches = { workspace = true, optional = true }

crates/matrix-sdk-base/src/client.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ impl BaseClient {
533533

534534
let push_rules = self.get_push_rules(&global_account_data_processor).await?;
535535

536-
let mut new_rooms = RoomUpdates::default();
536+
let mut room_updates = RoomUpdates::default();
537537
let mut notifications = Default::default();
538538

539539
let mut updated_members_in_room: BTreeMap<OwnedRoomId, BTreeSet<OwnedUserId>> =
@@ -564,7 +564,7 @@ impl BaseClient {
564564
)
565565
.await?;
566566

567-
new_rooms.joined.insert(room_id, joined_room_update);
567+
room_updates.joined.insert(room_id, joined_room_update);
568568
}
569569

570570
for (room_id, left_room) in response.rooms.leave {
@@ -591,7 +591,7 @@ impl BaseClient {
591591
)
592592
.await?;
593593

594-
new_rooms.left.insert(room_id, left_room_update);
594+
room_updates.left.insert(room_id, left_room_update);
595595
}
596596

597597
for (room_id, invited_room) in response.rooms.invite {
@@ -608,7 +608,7 @@ impl BaseClient {
608608
)
609609
.await?;
610610

611-
new_rooms.invited.insert(room_id, invited_room_update);
611+
room_updates.invited.insert(room_id, invited_room_update);
612612
}
613613

614614
for (room_id, knocked_room) in response.rooms.knock {
@@ -625,7 +625,7 @@ impl BaseClient {
625625
)
626626
.await?;
627627

628-
new_rooms.knocked.insert(room_id, knocked_room_update);
628+
room_updates.knocked.insert(room_id, knocked_room_update);
629629
}
630630

631631
global_account_data_processor.apply(&mut context, &self.state_store).await;
@@ -654,12 +654,19 @@ impl BaseClient {
654654
.await?;
655655
}
656656

657+
let mut context = Context::default();
658+
657659
// Now that all the rooms information have been saved, update the display name
658-
// cache (which relies on information stored in the database). This will
659-
// live in memory, until the next sync which will saves the room info to
660-
// disk; we do this to avoid saving that would be redundant with the
661-
// above. Oh well.
662-
new_rooms.update_in_memory_caches(&self.state_store).await;
660+
// of the updated rooms (which relies on information stored in the database).
661+
processors::room::display_name::update_for_rooms(
662+
&mut context,
663+
&room_updates,
664+
&self.state_store,
665+
)
666+
.await;
667+
668+
// Save the new display name updates if any.
669+
processors::changes::save_only(context, &self.state_store).await?;
663670

664671
for (room_id, member_ids) in updated_members_in_room {
665672
if let Some(room) = self.get_room(&room_id) {
@@ -673,7 +680,7 @@ impl BaseClient {
673680
}
674681

675682
let response = SyncResponse {
676-
rooms: new_rooms,
683+
rooms: room_updates,
677684
presence: response.presence.events,
678685
account_data: response.account_data.events,
679686
to_device,
@@ -1325,7 +1332,7 @@ mod tests {
13251332
let room = client.get_room(room_id).expect("Room not found");
13261333
assert_eq!(room.state(), RoomState::Invited);
13271334
assert_eq!(
1328-
room.compute_display_name().await.expect("fetching display name failed"),
1335+
room.compute_display_name().await.expect("fetching display name failed").into_inner(),
13291336
RoomDisplayName::Calculated("Kyra".to_owned())
13301337
);
13311338
}

crates/matrix-sdk-base/src/response_processors/changes.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ use crate::{
2525
Result,
2626
};
2727

28+
/// Save the [`StateChanges`] from the [`Context`] inside the [`BaseStateStore`]
29+
/// only! The changes aren't applied on the in-memory rooms.
30+
#[instrument(skip_all)]
31+
pub async fn save_only(context: Context, state_store: &BaseStateStore) -> Result<()> {
32+
save_changes(&context, state_store, None).await?;
33+
broadcast_room_info_notable_updates(&context, state_store);
34+
35+
Ok(())
36+
}
37+
2838
/// Save the [`StateChanges`] from the [`Context`] inside the
2939
/// [`BaseStateStore`], and apply them on the in-memory rooms.
3040
#[instrument(skip_all)]
@@ -39,28 +49,36 @@ pub async fn save_and_apply(
3949
let previous_ignored_user_list =
4050
state_store.get_account_data_event_static().await.ok().flatten();
4151

52+
save_changes(&context, state_store, sync_token).await?;
53+
apply_changes(&context, ignore_user_list_changes, previous_ignored_user_list);
54+
broadcast_room_info_notable_updates(&context, state_store);
55+
56+
trace!("applied changes");
57+
58+
Ok(())
59+
}
60+
61+
async fn save_changes(
62+
context: &Context,
63+
state_store: &BaseStateStore,
64+
sync_token: Option<String>,
65+
) -> Result<()> {
4266
state_store.save_changes(&context.state_changes).await?;
4367

4468
if let Some(sync_token) = sync_token {
4569
*state_store.sync_token.write().await = Some(sync_token);
4670
}
47-
apply_changes(context, state_store, ignore_user_list_changes, previous_ignored_user_list);
48-
49-
trace!("applied changes");
5071

5172
Ok(())
5273
}
5374

5475
fn apply_changes(
55-
context: Context,
56-
state_store: &BaseStateStore,
76+
context: &Context,
5777
ignore_user_list_changes: &SharedObservable<Vec<String>>,
5878
previous_ignored_user_list: Option<Raw<IgnoredUserListEvent>>,
5979
) {
60-
let (state_changes, room_info_notable_updates) = context.into_parts();
61-
6280
if let Some(event) =
63-
state_changes.account_data.get(&GlobalAccountDataEventType::IgnoredUserList)
81+
context.state_changes.account_data.get(&GlobalAccountDataEventType::IgnoredUserList)
6482
{
6583
match event.deserialize_as::<IgnoredUserListEvent>() {
6684
Ok(event) => {
@@ -93,11 +111,13 @@ fn apply_changes(
93111
}
94112
}
95113
}
114+
}
96115

97-
for (room_id, room_info) in &state_changes.room_infos {
116+
fn broadcast_room_info_notable_updates(context: &Context, state_store: &BaseStateStore) {
117+
for (room_id, room_info) in &context.state_changes.room_infos {
98118
if let Some(room) = state_store.room(room_id) {
99119
let room_info_notable_update_reasons =
100-
room_info_notable_updates.get(room_id).copied().unwrap_or_default();
120+
context.room_info_notable_updates.get(room_id).copied().unwrap_or_default();
101121

102122
room.set_room_info(room_info.clone(), room_info_notable_update_reasons)
103123
}

crates/matrix-sdk-base/src/response_processors/e2ee/to_device.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ async fn process(
9999
let (events, room_key_updates) =
100100
olm_machine.receive_sync_changes(encryption_sync_changes).await?;
101101

102+
let events = events
103+
.iter()
104+
// TODO: There is loss of information here, after calling `to_raw` it is not
105+
// possible to make the difference between a successfully decrypted event and a plain
106+
// text event. This information needs to be propagated to top layer at some point if
107+
// clients relies on custom encrypted to device events.
108+
.map(|p| p.to_raw())
109+
.collect();
110+
102111
Output { decrypted_to_device_events: events, room_key_updates: Some(room_key_updates) }
103112
} else {
104113
// If we have no `OlmMachine`, just return the events that were passed in.

crates/matrix-sdk-base/src/response_processors/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,4 @@ impl Context {
4646
pub fn new(state_changes: StateChanges) -> Self {
4747
Self { state_changes, room_info_notable_updates: Default::default() }
4848
}
49-
50-
pub fn into_parts(self) -> (StateChanges, RoomInfoNotableUpdates) {
51-
let Self { state_changes, room_info_notable_updates } = self;
52-
53-
(state_changes, room_info_notable_updates)
54-
}
5549
}

crates/matrix-sdk-base/src/response_processors/notification.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,22 @@ impl<'a> Notification<'a> {
5555

5656
/// Push a new [`sync::Notification`] in [`Self::notifications`] from
5757
/// `event` if and only if `predicate` returns `true` for at least one of
58-
/// the [`Action`]s associated to this event and this `push_context`
59-
/// (based on `Self::push_rules`).
58+
/// the [`Action`]s associated to this event and this
59+
/// `push_condition_room_ctx`. (based on `Self::push_rules`).
6060
///
6161
/// This method returns the fetched [`Action`]s.
6262
pub fn push_notification_from_event_if<E, P>(
6363
&mut self,
6464
room_id: &RoomId,
65-
push_context: &PushConditionRoomCtx,
65+
push_condition_room_ctx: &PushConditionRoomCtx,
6666
event: &Raw<E>,
6767
predicate: P,
6868
) -> &[Action]
6969
where
7070
Raw<E>: Into<RawAnySyncOrStrippedTimelineEvent>,
7171
P: Fn(&Action) -> bool,
7272
{
73-
let actions = self.push_rules.get_actions(event, push_context);
73+
let actions = self.push_rules.get_actions(event, push_condition_room_ctx);
7474

7575
if actions.iter().any(predicate) {
7676
self.push_notification(room_id, actions.to_owned(), event.clone().into());
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Matrix.org Foundation C.I.C.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use super::super::Context;
16+
use crate::{
17+
rooms::UpdatedRoomDisplayName, store::BaseStateStore, sync::RoomUpdates,
18+
RoomInfoNotableUpdateReasons,
19+
};
20+
21+
pub async fn update_for_rooms(
22+
context: &mut Context,
23+
room_updates: &RoomUpdates,
24+
state_store: &BaseStateStore,
25+
) {
26+
for room in room_updates
27+
.left
28+
.keys()
29+
.chain(room_updates.joined.keys())
30+
.chain(room_updates.invited.keys())
31+
.chain(room_updates.knocked.keys())
32+
.filter_map(|room_id| state_store.room(room_id))
33+
{
34+
// Compute the display name. If it's different, let's register the `RoomInfo` in
35+
// the `StateChanges`.
36+
if let Ok(UpdatedRoomDisplayName::New(_)) = room.compute_display_name().await {
37+
let room_id = room.room_id().to_owned();
38+
39+
context.state_changes.room_infos.insert(room_id.clone(), room.clone_info());
40+
context
41+
.room_info_notable_updates
42+
.entry(room_id)
43+
.or_default()
44+
.insert(RoomInfoNotableUpdateReasons::DISPLAY_NAME);
45+
}
46+
}
47+
}

crates/matrix-sdk-base/src/response_processors/room/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use tokio::sync::broadcast::Sender;
1717

1818
use crate::{store::ambiguity_map::AmbiguityCache, RequestedRequiredStates, RoomInfoNotableUpdate};
1919

20+
pub mod display_name;
2021
pub mod msc4186;
2122
pub mod sync_v2;
2223

crates/matrix-sdk-base/src/response_processors/state_events.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ pub mod stripped {
179179

180180
// We need to check for notifications after we have handled all state
181181
// events, to make sure we have the full push context.
182-
if let Some(push_context) =
182+
if let Some(push_condition_room_ctx) =
183183
timeline::get_push_room_context(context, room, room_info, notification.state_store)
184184
.await?
185185
{
@@ -189,7 +189,7 @@ pub mod stripped {
189189
for event in state_events.values().flat_map(|map| map.values()) {
190190
notification.push_notification_from_event_if(
191191
room_id,
192-
&push_context,
192+
&push_condition_room_ctx,
193193
event,
194194
Action::should_notify,
195195
);

0 commit comments

Comments
 (0)