Merge remote-tracking branch 'upstream/develop' into rust-verification

This commit is contained in:
Damir Jelić 2021-07-23 15:03:10 +02:00
commit e2006f9dc6
299 changed files with 4000 additions and 1522 deletions

84
.github/ISSUE_TEMPLATE/release.md vendored Normal file
View File

@ -0,0 +1,84 @@
---
name: Release
about: Checklist for each release. To be used by the core team only.
title: "[Release] Element Android v"
labels: "\U0001F680 Release"
assignees: bmarty
---
For the example, we are releasing the version 1.1.10. Delete this line and replace 1.1.10 with the version in the issue content.
### Before the release
- [ ] Weblate sync, fix lint issue if any (in a dedicated PR)
- [ ] Check the update of the store descriptions (using Google Translate if necessary) to ensure that the changes are acceptable to be published to the stores.
- [ ] Run the script `./tools/release/pushPlayStoreMetaData.sh`. You can check in the GooglePlay console the Activity log to check the effect.
### Do the release
- [ ] Create release with gitflow, branch name `release/1.1.10`
- [ ] Run `./tools/import_emojis.py` and commit the change if any.
- [ ] Run `./tools/import_sas_strings.py` and commit the change if any. If there is no change since a while, ping Travis
- [ ] Check the crashes from the PlayStore
- [ ] Check the rageshake with the current dev version: https://github.com/matrix-org/element-android-rageshakes/labels/1.1.10-dev
- [ ] Run the integration test, and especially `UiAllScreensSanityTest.allScreensTest()`
- [ ] Create an account on matrix.org
- [ ] Run towncrier: `towncrier --version v1.1.10 --draft` (remove `--draft` do write the file CHANGES.md)
- [ ] Add file for fastlane under ./fastlane/metadata/android/en-US/changelogs
- [ ] Push the branch and start a draft PR (will not be merged), to check that the CI is happy with all the changes.
- [ ] Finish release with gitflow, delete the draft PR
- [ ] Push `main` and the new tag `v1.1.10` to origin
- [ ] Checkout `develop`
- [ ] Increase version in `./vector/build.gradle`
- [ ] Commit and push `develop`
- [ ] Wait for [Buildkite](https://buildkite.com/matrix-dot-org/element-android/builds?branch=main) to build the `main` branch.
- [ ] Run the script `~/scripts/releaseElement.sh`. It will download the APKs from Buildkite check them and sign them.
- [ ] Install the APK on your phone to check that the upgrade went well (no init sync, etc.)
- [ ] Create a new beta release on the GooglePlay console and upload the 4 signed Apks.
- [ ] Check that the version codes are correct
- [ ] Copy the fastlane change to the GooglePlay console in the section en-GB.
- [ ] Push to beta release to 100% of the users
- [ ] Create the release on gitHub [from the tag](https://github.com/vector-im/element-android/tags), copy paste the block from the file CHANGES.md
- [ ] Add the 4 signed APKs to the GitHub release
- [ ] Ping the Android Internal room
- [ ] Add an entry in the internal diary
### Once Live on PlayStore
- [ ] Ping the Android public room and update its topic
### After at least 2 days
- [ ] Check the [rageshakes](https://github.com/matrix-org/element-android-rageshakes/issues)
- [ ] Check the crash reports on the GooglePlay console
- [ ] Check the Android Element room for any reported issues on the new version
- [ ] If all is OK, push to production and notify Markus (Bubu) to release the F-Droid version
- [ ] Ping the Android public room and update its topic with the new available version
### Android SDK2
- [ ] Checkout the `main` branch on Element Android project
#### On the SDK2 project
https://github.com/matrix-org/matrix-android-sdk2
- [ ] Create a release with GitFlow
- [ ] Update the files `./build.gradle` and `./gradle/gradle-wrapper.properties` manually, to use the latest version for the dependency. You can get inspired by the same files on Element Android project.
- [ ] Run the script `./tools/import_from_element.sh`
- [ ] Update the version in `./matrix-sdk-android/build.gradle` and let the script finish to build the library
- [ ] Update the file `CHANGES.md`
- [ ] Finish the release using GitFlow
- [ ] Create the release on GitHub from [the tag](https://github.com/matrix-org/matrix-android-sdk2/tags)
- [ ] Upload the AAR on the GitHub release
### Android SDK2 sample
https://github.com/matrix-org/matrix-android-sdk2-sample
- [ ] Update the dependency to the new version of the SDK2. Jitpack will have to build the AAR, it can take a few minutes. You can check status on https://jitpack.io/#matrix-org/matrix-android-sdk2
- [ ] Build and run the sample, you may have to fix some API break
- [ ] Commit and push directly on `main`
<!-- Note: some scripts are not public because they contain some private keys -->

View File

@ -38,6 +38,7 @@
<w>unpublish</w>
<w>unwedging</w>
<w>vctr</w>
<w>wellknown</w>
</words>
</dictionary>
</component>

View File

@ -1,3 +1,69 @@
Changes in Element 1.1.14 (2021-07-23)
======================================
Features ✨
----------
- Add low priority section in DM tab ([#3463](https://github.com/vector-im/element-android/issues/3463))
- Show missed call notification. ([#3710](https://github.com/vector-im/element-android/issues/3710))
Bugfixes 🐛
----------
- Don't use the transaction ID of the verification for the request ([#3589](https://github.com/vector-im/element-android/issues/3589))
- Avoid incomplete downloads in cache ([#3656](https://github.com/vector-im/element-android/issues/3656))
- Fix a crash which can happen when user signs out ([#3720](https://github.com/vector-im/element-android/issues/3720))
- Ensure OTKs are uploaded when the session is created ([#3724](https://github.com/vector-im/element-android/issues/3724))
SDK API changes ⚠️
------------------
- Add initialState support to CreateRoomParams (#3713) ([#3713](https://github.com/vector-im/element-android/issues/3713))
Other changes
-------------
- Apply grammatical fixes to the Server ACL timeline messages. ([#3721](https://github.com/vector-im/element-android/issues/3721))
- Add tags in the log, especially for VoIP, but can be used for other features in the future ([#3723](https://github.com/vector-im/element-android/issues/3723))
Changes in Element v1.1.13 (2021-07-19)
=======================================
Features ✨
----------
- Remove redundant mimetype (vector-im/element-web#2547) ([#3273](https://github.com/vector-im/element-android/issues/3273))
- Room version capabilities and room upgrade support, better error feedback ([#3551](https://github.com/vector-im/element-android/issues/3551))
- Add retry support in room addresses screen ([#3635](https://github.com/vector-im/element-android/issues/3635))
- Better management of permission requests ([#3667](https://github.com/vector-im/element-android/issues/3667))
Bugfixes 🐛
----------
- Standardise spelling and casing of homeserver, identity server, and integration manager. ([#491](https://github.com/vector-im/element-android/issues/491))
- Perform .well-known request first, even if the entered URL is a valid homeserver base url ([#2843](https://github.com/vector-im/element-android/issues/2843))
- Use different copy for self verification. ([#3624](https://github.com/vector-im/element-android/issues/3624))
- Crash when opening room addresses screen with no internet connection ([#3634](https://github.com/vector-im/element-android/issues/3634))
- Fix unread messages marker being hidden in collapsed membership item ([#3655](https://github.com/vector-im/element-android/issues/3655))
- Ensure reaction emoji picker tabs look fine on small displays ([#3661](https://github.com/vector-im/element-android/issues/3661))
SDK API changes ⚠️
------------------
- RawService.getWellknown() now takes a domain instead of a matrixId as parameter ([#3572](https://github.com/vector-im/element-android/issues/3572))
Changes in Element 1.1.12 (2021-07-05)
======================================
Features ✨
----------
- Reveal password: use facility from com.google.android.material.textfield.TextInputLayout instead of manual handling. ([#3545](https://github.com/vector-im/element-android/issues/3545))
- Implements new design for Jump to unread and quick fix visibility issues. ([#3547](https://github.com/vector-im/element-android/issues/3547))
Bugfixes 🐛
----------
- Fix some issues with timeline cache invalidation and visibility. ([#3542](https://github.com/vector-im/element-android/issues/3542))
- Fix call invite processed after call is ended because of fastlane mode. ([#3564](https://github.com/vector-im/element-android/issues/3564))
- Fix crash after video call. ([#3577](https://github.com/vector-im/element-android/issues/3577))
- Fix crash out of memory ([#3583](https://github.com/vector-im/element-android/issues/3583))
- CryptoStore migration has to be object to avoid crash ([#3605](https://github.com/vector-im/element-android/issues/3605))
Changes in Element v1.1.11 (2021-06-22)
=======================================

View File

@ -2,25 +2,25 @@ GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.3)
addressable (2.7.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.1.1)
aws-partitions (1.462.0)
aws-sdk-core (3.114.0)
aws-partitions (1.479.0)
aws-sdk-core (3.117.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.43.0)
aws-sdk-kms (1.44.0)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.95.1)
aws-sdk-s3 (1.96.1)
aws-sdk-core (~> 3, >= 3.112.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.3)
aws-sigv4 (1.2.4)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.0.3)
@ -35,13 +35,15 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.2.2)
excon (0.81.0)
faraday (1.4.2)
excon (0.85.0)
faraday (1.5.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-cookie_jar (0.0.7)
@ -50,12 +52,14 @@ GEM
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
fastimage (2.2.3)
fastlane (2.184.0)
fastimage (2.2.4)
fastlane (2.187.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
artifactory (~> 3.0)
@ -94,37 +98,36 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.4.0)
google-apis-core (~> 0.1)
google-apis-core (0.3.0)
google-apis-androidpublisher_v3 (0.8.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.0)
addressable (~> 2.5, >= 2.5.1)
googleauth (~> 0.14)
httpclient (>= 2.8.1, < 3.0)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
retriable (>= 2.0, < 4.a)
rexml
signet (~> 0.14)
webrick
google-apis-iamcredentials_v1 (0.4.0)
google-apis-core (~> 0.1)
google-apis-playcustomapp_v1 (0.3.0)
google-apis-core (~> 0.1)
google-apis-storage_v1 (0.4.0)
google-apis-core (~> 0.1)
google-apis-iamcredentials_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-playcustomapp_v1 (0.5.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-storage_v1 (0.6.0)
google-apis-core (>= 0.4, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.5.0)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.1.0)
google-cloud-storage (1.31.1)
google-cloud-storage (1.34.1)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
google-apis-storage_v1 (~> 0.1)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
googleauth (0.16.2)
faraday (>= 0.17.3, < 2.0)
@ -134,7 +137,7 @@ GEM
os (>= 0.9, < 2.0)
signet (~> 0.14)
highline (2.0.3)
http-cookie (1.0.3)
http-cookie (1.0.4)
domain_name (~> 0.5)
httpclient (2.8.3)
jmespath (1.4.0)
@ -150,7 +153,7 @@ GEM
os (1.1.1)
plist (3.6.0)
public_suffix (4.0.6)
rake (13.0.3)
rake (13.0.6)
representable (3.1.1)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
@ -158,8 +161,8 @@ GEM
retriable (3.1.2)
rexml (3.2.5)
rouge (2.0.7)
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.15.0)
addressable (~> 2.3)
@ -184,12 +187,13 @@ GEM
unicode-display_width (1.7.0)
webrick (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.19.0)
xcodeproj (1.20.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)

View File

@ -55,9 +55,9 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.5.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation "androidx.recyclerview:recyclerview:1.2.1"
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
}

View File

@ -2,7 +2,7 @@
buildscript {
// Ref: https://kotlinlang.org/releases.html
ext.kotlin_version = '1.5.20'
ext.kotlin_version = '1.5.21'
ext.kotlin_coroutines_version = "1.5.0"
repositories {
google()
@ -12,7 +12,7 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.google.gms:google-services:4.3.8'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'

View File

@ -1 +0,0 @@
Reveal password: use facility from com.google.android.material.textfield.TextInputLayout instead of manual handling.

View File

@ -1 +0,0 @@
Implements new design for Jump to unread and quick fix visibility issues.

View File

@ -1 +0,0 @@
Fix call invite processed after call is ended because of fastlane mode.

View File

@ -1 +0,0 @@
Fix crash after video call.

View File

@ -4,7 +4,7 @@ Issue: #607
PR: #1354
## Introduction
Identity Servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
Identity servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
## Implementation
@ -87,6 +87,6 @@ This screen displays the identity server configuration and the binding of the us
This screen is a form to set a new identity server URL
## Ref:
- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an Identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
- API documentation: https://matrix.org/docs/spec/identity_service/latest
- vector.im TOS: https://vector.im/identity-server-privacy-notice

View File

@ -2,11 +2,11 @@ This document aims to describe how Element android displays notifications to the
# Table of Contents
1. [Prerequisites Knowledge](#prerequisites-knowledge)
* [How does a matrix client get a message from a Home Server?](#how-does-a-matrix-client-get-a-message-from-a-home-server)
* [How does a matrix client get a message from a homeserver?](#how-does-a-matrix-client-get-a-message-from-a-homeserver)
* [How does a mobile app receives push notification?](#how-does-a-mobile-app-receives-push-notification)
* [Push VS Notification](#push-vs-notification)
* [Push in the matrix federated world](#push-in-the-matrix-federated-world)
* [How does the Home Server knows when to notify a client?](#how-does-the-home-server-knows-when-to-notify-a-client)
* [How does the homeserver know when to notify a client?](#how-does-the-homeserver-know-when-to-notify-a-client)
* [Push vs privacy, and mitigation](#push-vs-privacy-and-mitigation)
* [Background processing limitations](#background-processing-limitations)
2. [Element Notification implementations](#element-notification-implementations)
@ -22,7 +22,7 @@ First let's start with some prerequisite knowledge
# Prerequisites Knowledge
## How does a matrix client get a message from a Home Server?
## How does a matrix client get a message from a homeserver?
In order to get messages from a homeserver, a matrix client need to perform a ``sync`` operation.
@ -90,7 +90,7 @@ That means that Element Android, a matrix client created by New Vector, is using
If you create your own matrix client, you will also need to deploy an instance of a **Push Gateway** with the credentials needed to use FCM for your app.
On registration, a matrix client must tell to it's Home Server what Push Gateway to use.
On registration, a matrix client must tell its homeserver what Push Gateway to use.
See [Sygnal](https://github.com/matrix-org/sygnal/) for a reference implementation.
```
@ -122,13 +122,13 @@ Recommended reading:
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id128
## How does the Home Server knows when to notify a client?
## How does the homeserver know when to notify a client?
This is defined by [**push rules**](https://matrix.org/docs/spec/client_server/r0.4.0.html#push-rules-).
`A push rule is a single rule that states under what conditions an event should be passed onto a push gateway and how the notification should be presented (sound / importance).`
A Home Server can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
A homeserver can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
There are different kind of push rules, it can be per room (each new message on this room should be notified), it can also define a pattern that a message should match (when you are mentioned, or key word based).
@ -187,7 +187,7 @@ In background, and depending on wether push is available or not, Element will us
## Push (FCM) received in background
In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the HomeServer.
In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the homeserver.
When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for Element, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org.
@ -199,7 +199,7 @@ Homeserver ----> Sygnal (configured for Element) ----> FCM ----> Element
The push gateway is configured to only send `(eventId,roomId)` in the push payload (for better [privacy](#push-vs-privacy-and-mitigation)).
Element needs then to synchronise with the user's HomeServer, in order to resolve the event and create a notification.
Element needs then to synchronise with the user's homeserver, in order to resolve the event and create a notification.
As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), Element will then use the WorkManager API in order to trigger a background sync.
@ -217,7 +217,7 @@ Homeserver ----> Sygnal ----> FCM ----> Element
**Possible outcomes**
Upon reception of the FCM push, Element will perform a sync call to the Home Server, during this process it is possible that:
Upon reception of the FCM push, Element will perform a sync call to the homeserver, during this process it is possible that:
* Happy path, the sync is performed, the message resolved and displayed in the notification drawer
* The notified message is not in the sync. Can happen if a lot of things did happen since the push (`gappy sync`)
* The sync generates additional notifications (e.g an encrypted message where the user is mentioned detected locally)

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: beta podpora pro Spaces. Komprimace videa před odesláním.
Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.7

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: vylepšení pro Spaces
Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.8

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: doplněna podpora pro síť gitter.im
Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.9

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: aktualizace vzhledu a stylu a nové funkce prostorů.
Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Hlavní změny v této verzi: aktualizace vzhledu a stylu a nové funkce prostorů (bugfix pro 1.1.10)
Úplný záznam změn: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
Hauptänderungen: Design-Update und neue Features für Spaces
Vollständige Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Hauptänderungen: Design-Update und neue Features für Spaces (Bugfix für 1.1.10)
Vollständige Änderungsliste: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
Main changes in this version: theme and style update and fix a crash after video call
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.12

View File

@ -0,0 +1,2 @@
Main changes in this version: mainly stability and bugfixes update.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.13

View File

@ -0,0 +1,2 @@
Main changes in this version: fix an issue about encrypted messages.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.1.14

View File

@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: teemade ja välimuse uuendused ning mõned kogukondade uuendused
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: teemade ja välimuse uuendused ning mõned kogukondade uuendused (1.1.10 veaparandus)
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
Principaux changements pour cette version : prise en charge des espaces en bêta. Compression des vidéos avant envoi.
Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.7

View File

@ -0,0 +1,2 @@
Principaux changements pour cette version : amélioration des espaces.
Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.8

View File

@ -0,0 +1,2 @@
Principaux changements pour cette version : ajout de la prise en charge de gitter.im
Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.1.9

View File

@ -1,30 +1,39 @@
Element est une nouvelle application de messagerie et de collaboration qui :
Element est à la fois une messagerie sécurisée et une application de collaboration en équipe, idéale pour les conversations de groupe en télétravail. Cette application utilise le chiffrement de bout en bout. Elle permet de mettre en place des téléconférences vidéo, du partage de fichier et des appels vocaux.
1. Vous permet de préserver votre vie privée
2. Vous permet de communiquer avec nimporte qui sur réseau Matrix, et plus encore grâce aux intégrations dautres applications telles que Slack ou Discord
3. Vous protège de la publicité et de la collecte de données
4. Vous protège grâce au chiffrement de bout-à-bout et à la signature croisée pour authentifier les autres utilisateurs
<b>Les fonctionnalités dElement incluent :</b>
- Outils de communication en ligne avancés
- Communication dentreprise sécurisée par le chiffrement de bout en bout des messages, même pour les travailleurs à distance
- Messagerie décentralisée basée sur le framework open source Matrix
- Partage sécurisé de fichiers avec chiffrement des données lors de la gestion de projet
- Conversations vidéo par voix sur IP et partage décran
- Intégration facile avec vos outils de collaboration, de gestion de projet, services de VoIP et autres applications de messagerie
Element est complètement différente des autres applications de messagerie et de collaboration puisque lapplication est décentralisée et open-source.
Element est complètement différente des autres applications de messagerie et de collaboration. Elle sappuie sur Matrix, un réseau ouvert de communication décentralisée. Elle permet lauto-hébergement pour que ses utilisateurs restent le plus en contrôle possible de leurs données et leurs messages.
Element vous permet dhéberger vous-même ou de choisir un hôte vous permettant dassurer votre vie privée, la propriété et le contrôle de vos données et de vos conversations. Cela vous donne accès à un réseau ouvert. Vous nêtes donc pas condamné à parler à dautres utilisateurs dElement seulement. Et c'est très sécurisé.
<b>Confidentialité et messagerie chiffrée</b>
Element vous protège des publicités non désirées, du minage de données et des prisons dorées. Elle protègé vos données et vos communications vocales grâce au chiffrement de bout en bout et à la vérification de signature croisée entre appareils.
Element peut faire tout ça car elle est basée sur Matrix, le protocole standard pour la communication ouverte et décentralisée.
Element vous donne la main sur votre confidentialité en vous permettant de communiquer de manière sécurisée avec tout le réseau Matrix ou dautres applications de communication dentreprise au travers dintégrations dapplications comme Slack.
Element vous donne le contrôle en vous laissant choisir qui héberge vos conversations. Depuis l'application Element, vous pouvez choisir votre hôte de différentes manières :
<b>Element peut être auto-hébergé</b>
Pour une meilleure souveraineté sur vos données et conversations, Element peut être auto-hébergé ou vous pouvez choisir votre hôte Matrix - la norme open source pour les communications décentralisées. Element garantit votre confidentialité, conformité aux normes de sécurité, tout en proposant une intégration souple.
1. Créer un compte gratuit sur le serveur public matrix.org hébergé par les développeurs de Matrix, ou choisir parmi les milliers de serveurs public hébergés par des bénévoles
2. Héberger vous-même votre compte en installant un serveur sur votre propre machine
3. Créer un compte sur un serveur personnalisé en souscrivant sur la plateforme d'hébergement « Element Matrix Services » (EMS)
<b>Vos données vous appartiennent</b>
Vous décidez où stocker vos données et messages. Aucun risque de minage de données où daccès par des tierce parties.
<b>Pourquoi choisir Element ?</b>
Element vous place aux commandes de différente manières :
1. Inscrivez vous sur le serveur public matrix.org hébergé par les développeurs de Matrix ou choisissez parmi des milliers de serveurs publics hébergés par des bénévoles
2. Auto-hébergez votre compte sur un serveur de votre proper infrastructure informatique
3. Inscrivez vous à la plateforme dhébergement Element Matrix Services
<b>VOS DONNÉES VOUS APPARTIENNENT</b> : vous décidez où stocker vos données et messages. Ils vous appartiennent et vous les maîtrisez. Aucune multinationale ne viendra extraire vos données pour les envoyer au plus offrant.
<b>Messagerie et collaboration ouvertes</b>
Vous pouvez discuter avec tout le réseau Matrix, que vos interlocuteurs utilisent Element, une autre application Matrix, ou même sils utilisent une application complètement différente.
<b>MESSAGERIE ET COLLABORATION OUVERTES</b> : vous pouvez discuter avec tout le réseau Matrix, quils utilisent Element ou une autre application Matrix, même sils utilisent une autre plateforme de messagerie telle que Slack, IRC ou XMPP.
<b>Ultra sécurisé</b>
Chiffrement de bout en bout (seules les personnes dans la conversation peuvent déchiffrer les messages) et vérification de signature croisée entre appareils.
<b>ULTRA SÉCURISÉ</b> : chiffrement de bout en bout (seuls les membres dune conversation peuvent déchiffrer les messages), et signature croisée pour vérifier les appareils de vos interlocuteurs.
<b>Communication et intégration parfaites</b>
Messagerie instantannée, appels audio et vidéo, partage de fichier, partage décran et bien dautres intégrations, bots et widgets. Lancez des salons, des communautés, restez en contact et menez vos projets à bien.
<b>TOUTES VOS COMMUNICATIONS</b> : messagerie, appels audio et vidéo, partage de fichier, partage décran et un grand nombre dintégrations, robots et widgets. Participez à des salons, des communautés, restez en contact et faites avancer vos projets.
<b>PARTOUT AVEC VOUS</b> : votre historique reste synchronisé entre tous vos appareils et sur le web sur https://element.io/app.
<b>Reprenez où vous vous êtes arrêté</b>
Restez en contact où que vous soyez grâce à lhistorique des messages synchronisé entre tous vos appareils et sur le web sur https://app.element.io

View File

@ -0,0 +1,2 @@
Főbb változtatások ebben a verzióban: kinézet és stílus frissítések és új funkciók a terekhez
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Főbb változtatások ebben a verzióban: kinézet és stílus frissítések és új funkciók a terekhez (hibajavítás az 1.1.10-hez)
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
Modifiche principali in questa versione: aggiornati tema e stile e nuove funzioni per gli spazi .
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Modifiche principali in questa versione: aggiornati tema e stile e nuove funzioni per gli spazi (bugfix per 1.1.10)
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -1,2 +1,2 @@
Principais mudanças nesta version: suporte beta para Espaços. Comprimir vídeo antes de enviar.
Principais mudanças nesta versão: suporte beta para Espaços. Comprimir vídeo antes de enviar.
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.7

View File

@ -1,2 +1,2 @@
Principais mudanças nesta version: melhoramento para Espaços.
Principais mudanças nesta versão: melhoramento para Espaços.
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.8

View File

@ -1,2 +1,2 @@
Principais mudanças nesta version: adicionar supporte a rede gitter.im.
Principais mudanças nesta versão: adicionar supporte a rede gitter.im.
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.9

View File

@ -0,0 +1,2 @@
Principais mudanças nesta versão: atualização de tema e estilo e novas funcionalidades para espaços.
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Principais mudanças nesta versão: atualização de tema e estilo e novas funcionalidades para espaços (bugfix para 1.1.10)
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
Основні зміни цієї версії: оновлено зовнішній вигляд та нові можливості для просторів
Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
Основні зміни цієї версії: оновлено зовнішній вигляд та нові можливості для просторів (bugfix для 1.1.10)
Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
此版本的主要变化:主题和样式更新以及空间的新功能。
完整更新日志https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
此版本的主要变化主题和样式更新以及空间的新功能1.1.10 的错误修复)
完整更新日志https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -0,0 +1,2 @@
此版本中的主要變動:佈景主題與樣式更新,以及空間的新功能。
完整的變更紀錄https://github.com/vector-im/element-android/releases/tag/v1.1.10

View File

@ -0,0 +1,2 @@
此版本中的主要變動佈景主題與樣式更新以及空間的新功能1.1.10 的臭蟲修復版本)
完整的變更紀錄https://github.com/vector-im/element-android/releases/tag/v1.1.11

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=a9e356a21595348b6f04b024ed0b08ac8aea6b2ac37e6c0ef58e51549cd7b9cb
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-all.zip
distributionSha256Sum=9bb8bc05f562f2d42bdf1ba8db62f6b6fa1c3bf6c392228802cc7cb0578fe7e0
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -52,8 +52,8 @@ android {
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
// Pref theme
implementation 'androidx.preference:preference-ktx:1.1.1'
// PFLockScreen attrs

View File

@ -35,7 +35,7 @@ android {
dependencies {
implementation project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlin_coroutines_version"

View File

@ -9,7 +9,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:10.6.0"
classpath "io.realm:realm-gradle-plugin:10.6.1"
}
}
@ -126,7 +126,7 @@ dependencies {
def lifecycle_version = '2.2.0'
def arch_version = '2.1.0'
def markwon_version = '3.1.0'
def daggerVersion = '2.37'
def daggerVersion = '2.38'
def work_version = '2.5.0'
def retrofit_version = '2.9.0'
@ -136,8 +136,8 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
implementation "androidx.appcompat:appcompat:1.3.0"
implementation "androidx.core:core-ktx:1.5.0"
implementation "androidx.appcompat:appcompat:1.3.1"
implementation "androidx.core:core-ktx:1.6.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
@ -185,30 +185,30 @@ dependencies {
implementation 'com.otaliastudios:transcoder:0.10.3'
// Phone number https://github.com/google/libphonenumber
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.26'
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.28'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.5.1'
//testImplementation 'org.robolectric:shadows-support-v4:3.0'
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
testImplementation 'io.mockk:mockk:1.11.0'
testImplementation 'org.amshove.kluent:kluent-android:1.67'
testImplementation 'io.mockk:mockk:1.12.0'
testImplementation 'org.amshove.kluent:kluent-android:1.68'
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
// Plant Timber tree for test
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
kaptAndroidTest "com.google.dagger:dagger-compiler:$daggerVersion"
androidTestImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'org.amshove.kluent:kluent-android:1.65'
androidTestImplementation 'io.mockk:mockk-android:1.11.0'
androidTestImplementation 'androidx.test:core:1.4.0'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'org.amshove.kluent:kluent-android:1.68'
androidTestImplementation 'io.mockk:mockk-android:1.12.0'
androidTestImplementation "androidx.arch.core:core-testing:$arch_version"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
// Plant Timber tree for test
androidTestImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
androidTestUtil 'androidx.test:orchestrator:1.3.0'
androidTestUtil 'androidx.test:orchestrator:1.4.0'
}

View File

@ -78,7 +78,7 @@ class CommonTestHelper(context: Context) {
}
/**
* Create a Home server configuration, with Http connection allowed for test
* Create a homeserver configuration, with Http connection allowed for test
*/
fun createHomeServerConfig(): HomeServerConnectionConfig {
return HomeServerConnectionConfig.Builder()

View File

@ -16,8 +16,12 @@
package org.matrix.android.sdk.api
import org.matrix.android.sdk.BuildConfig
import timber.log.Timber
/**
* This class contains pattern to match the different Matrix ids
* Ref: https://matrix.org/docs/spec/appendices#identifier-grammar
*/
object MatrixPatterns {
@ -25,7 +29,7 @@ object MatrixPatterns {
private const val DOMAIN_REGEX = ":[A-Z0-9.-]+(:[0-9]{2,5})?"
// regex pattern to find matrix user ids in a string.
// See https://matrix.org/speculator/spec/HEAD/appendices.html#historical-user-ids
// See https://matrix.org/docs/spec/appendices#historical-user-ids
private const val MATRIX_USER_IDENTIFIER_REGEX = "@[A-Z0-9\\x21-\\x39\\x3B-\\x7F]+$DOMAIN_REGEX"
val PATTERN_CONTAIN_MATRIX_USER_IDENTIFIER = MATRIX_USER_IDENTIFIER_REGEX.toRegex(RegexOption.IGNORE_CASE)
@ -163,4 +167,18 @@ object MatrixPatterns {
"[^a-z0-9._%#@=+-]".toRegex().replace(it, "")
}
}
/**
* Return the domain form a userId
* Examples:
* - "@alice:domain.org".getDomain() will return "domain.org"
* - "@bob:domain.org:3455".getDomain() will return "domain.org:3455"
*/
fun String.getDomain(): String {
if (BuildConfig.DEBUG && !isUserId(this)) {
// They are some invalid userId localpart in the wild, but the domain part should be there anyway
Timber.w("Not a valid user ID: $this")
}
return substringAfter(":")
}
}

View File

@ -18,11 +18,11 @@ package org.matrix.android.sdk.api.auth.data
import android.net.Uri
import com.squareup.moshi.JsonClass
import okhttp3.CipherSuite
import okhttp3.TlsVersion
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
import org.matrix.android.sdk.internal.util.ensureTrailingSlash
import okhttp3.CipherSuite
import okhttp3.TlsVersion
/**
* This data class holds how to connect to a specific Homeserver.
@ -31,7 +31,12 @@ import okhttp3.TlsVersion
*/
@JsonClass(generateAdapter = true)
data class HomeServerConnectionConfig(
// This is the homeserver URL entered by the user
val homeServerUri: Uri,
// This is the homeserver base URL for the client-server API. Default to homeServerUri,
// but can be updated with data from .Well-Known before login, and/or with the data
// included in the login response
val homeServerUriBase: Uri = homeServerUri,
val identityServerUri: Uri? = null,
val antiVirusServerUri: Uri? = null,
val allowedFingerprints: List<Fingerprint> = emptyList(),
@ -47,7 +52,6 @@ data class HomeServerConnectionConfig(
* This builder should be use to create a [HomeServerConnectionConfig] instance.
*/
class Builder {
private lateinit var homeServerUri: Uri
private var identityServerUri: Uri? = null
private var antiVirusServerUri: Uri? = null
@ -234,16 +238,16 @@ data class HomeServerConnectionConfig(
*/
fun build(): HomeServerConnectionConfig {
return HomeServerConnectionConfig(
homeServerUri,
identityServerUri,
antiVirusServerUri,
allowedFingerprints,
shouldPin,
tlsVersions,
tlsCipherSuites,
shouldAcceptTlsExtensions,
allowHttpExtension,
forceUsageTlsVersions
homeServerUri = homeServerUri,
identityServerUri = identityServerUri,
antiVirusServerUri = antiVirusServerUri,
allowedFingerprints = allowedFingerprints,
shouldPin = shouldPin,
tlsVersions = tlsVersions,
tlsCipherSuites = tlsCipherSuites,
shouldAcceptTlsExtensions = shouldAcceptTlsExtensions,
allowHttpExtension = allowHttpExtension,
forceUsageTlsVersions = forceUsageTlsVersions
)
}
}

View File

@ -51,13 +51,18 @@ data class SessionParams(
val deviceId = credentials.deviceId
/**
* The current homeserver Url. It can be different that the homeserver url entered
* during login phase, because a redirection may have occurred
* The homeserver Url entered by the user during the login phase.
*/
val homeServerUrl = homeServerConnectionConfig.homeServerUri.toString()
/**
* The current homeserver host
* The current homeserver Url for client-server API. It can be different that the homeserver url entered
* during login phase, because a redirection may have occurred
*/
val homeServerUrlBase = homeServerConnectionConfig.homeServerUriBase.toString()
/**
* The current homeserver host, using what has been entered by the user during login phase
*/
val homeServerHost = homeServerConnectionConfig.homeServerUri.host

View File

@ -22,11 +22,6 @@ import org.matrix.android.sdk.api.auth.data.WellKnown
* Ref: https://matrix.org/docs/spec/client_server/latest#well-known-uri
*/
sealed class WellknownResult {
/**
* The provided matrixId is no valid. Unable to extract a domain name.
*/
object InvalidMatrixId : WellknownResult()
/**
* Retrieve the specific piece of information from the user in a way which fits within the existing client user experience,
* if the client is inclined to do so. Failure can take place instead if no good user experience for this is possible at this point.

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2021 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.
*/
package org.matrix.android.sdk.api.failure
sealed class MatrixIdFailure : Failure.FeatureFailure() {
object InvalidMatrixId : MatrixIdFailure()
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021 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.
*/
package org.matrix.android.sdk.api.logger
/**
* Parent class for custom logger tags. Can be used with Timber :
*
* val loggerTag = LoggerTag("MyTag", LoggerTag.VOIP)
* Timber.tag(loggerTag.value).v("My log message")
*/
open class LoggerTag(_value: String, parentTag: LoggerTag? = null) {
object VOIP : LoggerTag("VOIP")
val value: String = if (parentTag == null) {
_value
} else {
"${parentTag.value}/$_value"
}
}

View File

@ -29,8 +29,10 @@ interface RawService {
/**
* Specific case for the well-known file. Cache validity is 8 hours
* @param domain the domain to get the .well-known file, for instance "matrix.org".
* The URL will be "https://{domain}/.well-known/matrix/client"
*/
suspend fun getWellknown(userId: String): String
suspend fun getWellknown(domain: String): String
/**
* Clear all the cache data

View File

@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.call
import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
sealed class CallState {
/** Idle, setting up objects */
@ -42,6 +44,6 @@ sealed class CallState {
* */
data class Connected(val iceConnectionState: MxPeerConnectionState) : CallState()
/** Terminated. Incoming/Outgoing call, the call is terminated */
object Terminated : CallState()
/** Ended. Incoming/Outgoing call, the call is terminated */
data class Ended(val reason: EndCallReason? = null) : CallState()
}

View File

@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.call
import org.matrix.android.sdk.api.session.room.model.call.CallCandidate
import org.matrix.android.sdk.api.session.room.model.call.CallCapabilities
import org.matrix.android.sdk.api.session.room.model.call.CallHangupContent
import org.matrix.android.sdk.api.session.room.model.call.EndCallReason
import org.matrix.android.sdk.api.session.room.model.call.SdpType
import org.matrix.android.sdk.api.util.Optional
@ -69,7 +69,7 @@ interface MxCall : MxCallDetail {
/**
* End the call
*/
fun hangUp(reason: CallHangupContent.Reason? = null)
fun hangUp(reason: EndCallReason? = null)
/**
* Start a call

View File

@ -32,7 +32,13 @@ data class HomeServerCapabilities(
/**
* Default identity server url, provided in Wellknown
*/
val defaultIdentityServerUrl: String? = null
val defaultIdentityServerUrl: String? = null,
/**
* Room versions supported by the server
* This capability describes the default and available room versions a server supports, and at what level of stability.
* Clients should make use of this capability to determine if users need to be encouraged to upgrade their rooms.
*/
val roomVersions: RoomVersionCapabilities? = null
) {
companion object {
const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L

View File

@ -0,0 +1,32 @@
/*
* Copyright 2021 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.
*/
package org.matrix.android.sdk.api.session.homeserver
data class RoomVersionCapabilities(
val defaultRoomVersion: String,
val supportedVersion: List<RoomVersionInfo>
)
data class RoomVersionInfo(
val version: String,
val status: RoomVersionStatus
)
enum class RoomVersionStatus {
STABLE,
UNSTABLE
}

View File

@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.session.room.tags.TagsService
import org.matrix.android.sdk.api.session.room.timeline.TimelineService
import org.matrix.android.sdk.api.session.room.typing.TypingService
import org.matrix.android.sdk.api.session.room.uploads.UploadsService
import org.matrix.android.sdk.api.session.room.version.RoomVersionService
import org.matrix.android.sdk.api.session.search.SearchResult
import org.matrix.android.sdk.api.session.space.Space
import org.matrix.android.sdk.api.util.Optional
@ -57,7 +58,8 @@ interface Room :
RelationService,
RoomCryptoService,
RoomPushRuleService,
RoomAccountDataService {
RoomAccountDataService,
RoomVersionService {
/**
* The roomId of this room

View File

@ -39,12 +39,6 @@ fun spaceSummaryQueryParams(init: (RoomSummaryQueryParams.Builder.() -> Unit) =
.build()
}
enum class RoomCategoryFilter {
ONLY_DM,
ONLY_ROOMS,
ALL
}
/**
* This class can be used to filter room summaries to use with:
* [org.matrix.android.sdk.api.session.room.Room] and [org.matrix.android.sdk.api.session.room.RoomService]
@ -59,11 +53,10 @@ data class RoomSummaryQueryParams(
val excludeType: List<String?>?,
val includeType: List<String?>?,
val activeSpaceFilter: ActiveSpaceFilter?,
var activeGroupId: String? = null
val activeGroupId: String? = null
) {
class Builder {
var roomId: QueryStringValue = QueryStringValue.IsNotEmpty
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
var canonicalAlias: QueryStringValue = QueryStringValue.NoCondition

View File

@ -43,29 +43,5 @@ data class CallHangupContent(
* or `invite_timeout` for when the other party did not answer in time.
* One of: ["ice_failed", "invite_timeout"]
*/
@Json(name = "reason") val reason: Reason? = null
) : CallSignalingContent {
@JsonClass(generateAdapter = false)
enum class Reason {
@Json(name = "ice_failed")
ICE_FAILED,
@Json(name = "ice_timeout")
ICE_TIMEOUT,
@Json(name = "user_hangup")
USER_HANGUP,
@Json(name = "replaced")
REPLACED,
@Json(name = "user_media_failed")
USER_MEDIA_FAILED,
@Json(name = "invite_timeout")
INVITE_TIMEOUT,
@Json(name = "unknown_error")
UNKWOWN_ERROR
}
}
@Json(name = "reason") val reason: EndCallReason? = null
) : CallSignalingContent

View File

@ -36,5 +36,10 @@ data class CallRejectContent(
/**
* Required. The version of the VoIP specification this message adheres to.
*/
@Json(name = "version") override val version: String?
@Json(name = "version") override val version: String?,
/**
* Optional error reason for the reject.
*/
@Json(name = "reason") val reason: EndCallReason? = null
) : CallSignalingContent

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2021 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.
*/
package org.matrix.android.sdk.api.session.room.model.call
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = false)
enum class EndCallReason {
@Json(name = "ice_failed")
ICE_FAILED,
@Json(name = "ice_timeout")
ICE_TIMEOUT,
@Json(name = "user_hangup")
USER_HANGUP,
@Json(name = "replaced")
REPLACED,
@Json(name = "user_media_failed")
USER_MEDIA_FAILED,
@Json(name = "invite_timeout")
INVITE_TIMEOUT,
@Json(name = "unknown_error")
UNKWOWN_ERROR,
@Json(name = "user_busy")
USER_BUSY,
@Json(name = "answered_elsewhere")
ANSWERED_ELSEWHERE
}

View File

@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
// TODO Give a way to include other initial states
open class CreateRoomParams {
/**
* A public visibility indicates that the room will be shown in the published room list.
@ -103,6 +102,13 @@ open class CreateRoomParams {
*/
val creationContent = mutableMapOf<String, Any>()
/**
* A list of state events to set in the new room. This allows the user to override the default state events
* set in the new room. The expected format of the state events are an object with type, state_key and content keys set.
* Takes precedence over events set by preset, but gets overridden by name and topic keys.
*/
val initialStates = mutableListOf<CreateRoomStateEvent>()
/**
* Set to true to disable federation of this room.
* Default: false

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 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.
*/
package org.matrix.android.sdk.api.session.room.model.create
import org.matrix.android.sdk.api.session.events.model.Content
data class CreateRoomStateEvent(
/**
* Required. The type of event to send.
*/
val type: String,
/**
* Required. The content of the event.
*/
val content: Content,
/**
* The state_key of the state event. Defaults to an empty string.
*/
val stateKey: String = ""
)

View File

@ -54,5 +54,5 @@ data class MessageAudioContent(
) : MessageWithAttachmentContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype ?: audioInfo?.mimeType
get() = audioInfo?.mimeType
}

View File

@ -60,8 +60,7 @@ data class MessageFileContent(
) : MessageWithAttachmentContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype
?: info?.mimeType
get() = info?.mimeType
?: MimeTypeMap.getFileExtensionFromUrl(filename ?: body)?.let { extension ->
MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
}

View File

@ -20,7 +20,6 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
import org.matrix.android.sdk.api.util.MimeTypes
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
@JsonClass(generateAdapter = true)
@ -55,5 +54,5 @@ data class MessageImageContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageImageInfoContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: MimeTypes.Images
get() = info?.mimeType
}

View File

@ -55,5 +55,5 @@ data class MessageStickerContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageImageInfoContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype ?: info?.mimeType
get() = info?.mimeType
}

View File

@ -53,5 +53,5 @@ data class MessageVideoContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageWithAttachmentContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype ?: videoInfo?.mimeType
get() = videoInfo?.mimeType
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2021 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.
*/
package org.matrix.android.sdk.api.session.room.version
interface RoomVersionService {
/**
* Return the room version of this room
*/
fun getRoomVersion(): String
/**
* Upgrade to the given room version
* @return the replacement room id
*/
suspend fun upgradeToVersion(version: String): String
/**
* Get the recommended room version for the current homeserver
*/
fun getRecommendedVersion() : String
/**
* Ask if the user has enough power level to upgrade the room
*/
fun userMayUpgradeRoom(userId: String): Boolean
/**
* Return true if the current room version is declared unstable by the homeserver
*/
fun isUsingUnstableRoomVersion(): Boolean
}

View File

@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.space
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.space.model.SpaceChildContent
interface Space {
@ -38,6 +39,8 @@ interface Space {
autoJoin: Boolean = false,
suggested: Boolean? = false)
fun getChildInfo(roomId: String): SpaceChildContent?
suspend fun removeChildren(roomId: String)
@Throws

View File

@ -21,8 +21,8 @@ import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.auth.data.Availability
import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
import org.matrix.android.sdk.internal.auth.data.PasswordLoginParams
import org.matrix.android.sdk.internal.auth.data.RiotConfig
import org.matrix.android.sdk.internal.auth.data.TokenLoginParams
import org.matrix.android.sdk.internal.auth.data.WebClientConfig
import org.matrix.android.sdk.internal.auth.login.ResetPasswordMailConfirmed
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationParams
import org.matrix.android.sdk.internal.auth.registration.AddThreePidRegistrationResponse
@ -44,16 +44,16 @@ import retrofit2.http.Url
*/
internal interface AuthAPI {
/**
* Get a Riot config file, using the name including the domain
* Get a Web client config file, using the name including the domain
*/
@GET("config.{domain}.json")
suspend fun getRiotConfigDomain(@Path("domain") domain: String): RiotConfig
suspend fun getWebClientConfigDomain(@Path("domain") domain: String): WebClientConfig
/**
* Get a Riot config file
* Get a Web client default config file
*/
@GET("config.json")
suspend fun getRiotConfig(): RiotConfig
suspend fun getWebClientConfig(): WebClientConfig
/**
* Get the version information of the homeserver

View File

@ -19,6 +19,8 @@ package org.matrix.android.sdk.internal.auth
import android.net.Uri
import dagger.Lazy
import okhttp3.OkHttpClient
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.MatrixPatterns.getDomain
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
@ -28,10 +30,11 @@ import org.matrix.android.sdk.api.auth.login.LoginWizard
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixIdFailure
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.util.appendParamToUrl
import org.matrix.android.sdk.internal.SessionManager
import org.matrix.android.sdk.internal.auth.data.RiotConfig
import org.matrix.android.sdk.internal.auth.data.WebClientConfig
import org.matrix.android.sdk.internal.auth.db.PendingSessionData
import org.matrix.android.sdk.internal.auth.login.DefaultLoginWizard
import org.matrix.android.sdk.internal.auth.login.DirectLoginTask
@ -122,7 +125,7 @@ internal class DefaultAuthenticationService @Inject constructor(
private fun getHomeServerUrlBase(): String? {
return pendingSessionData
?.homeServerConnectionConfig
?.homeServerUri
?.homeServerUriBase
?.toString()
?.trim { it == '/' }
}
@ -143,9 +146,9 @@ internal class DefaultAuthenticationService @Inject constructor(
return result.fold(
{
// The homeserver exists and up to date, keep the config
// Homeserver url may have been changed, if it was a Riot url
// Homeserver url may have been changed, if it was a Web client url
val alteredHomeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = Uri.parse(it.homeServerUrl)
homeServerUriBase = Uri.parse(it.homeServerUrl)
)
pendingSessionData = PendingSessionData(alteredHomeServerConnectionConfig)
@ -154,7 +157,7 @@ internal class DefaultAuthenticationService @Inject constructor(
},
{
if (it is UnrecognizedCertificateException) {
throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUri.toString(), it.fingerprint)
throw Failure.UnrecognizedCertificateFailure(homeServerConnectionConfig.homeServerUriBase.toString(), it.fingerprint)
} else {
throw it
}
@ -165,6 +168,13 @@ internal class DefaultAuthenticationService @Inject constructor(
private suspend fun getLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
// First check if there is a well-known file
return try {
getWellknownLoginFlowInternal(homeServerConnectionConfig)
} catch (failure: Throwable) {
if (failure is Failure.OtherServerError
&& failure.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// 404, no well-known data, try direct access to the API
// First check the homeserver version
return runCatching {
executeRequest(null) {
@ -173,7 +183,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
.map { versions ->
// Ok, it seems that the homeserver url is valid
getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUri.toString())
getLoginFlowResult(authAPI, versions, homeServerConnectionConfig.homeServerUriBase.toString())
}
.fold(
{
@ -182,29 +192,33 @@ internal class DefaultAuthenticationService @Inject constructor(
{
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// It's maybe a Riot url?
getRiotDomainLoginFlowInternal(homeServerConnectionConfig)
// It's maybe a Web client url?
getWebClientDomainLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
}
)
} else {
throw failure
}
}
}
private suspend fun getRiotDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
private suspend fun getWebClientDomainLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
val domain = homeServerConnectionConfig.homeServerUri.host
?: return getRiotLoginFlowInternal(homeServerConnectionConfig)
?: return getWebClientLoginFlowInternal(homeServerConnectionConfig)
// Ok, try to get the config.domain.json file of a RiotWeb client
// Ok, try to get the config.domain.json file of a Web client
return runCatching {
executeRequest(null) {
authAPI.getRiotConfigDomain(domain)
authAPI.getWebClientConfigDomain(domain)
}
}
.map { riotConfig ->
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
.map { webClientConfig ->
onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
}
.fold(
{
@ -214,7 +228,7 @@ internal class DefaultAuthenticationService @Inject constructor(
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// Try with config.json
getRiotLoginFlowInternal(homeServerConnectionConfig)
getWebClientLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
@ -222,40 +236,24 @@ internal class DefaultAuthenticationService @Inject constructor(
)
}
private suspend fun getRiotLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
private suspend fun getWebClientLoginFlowInternal(homeServerConnectionConfig: HomeServerConnectionConfig): LoginFlowResult {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
// Ok, try to get the config.json file of a RiotWeb client
return runCatching {
executeRequest(null) {
authAPI.getRiotConfig()
// Ok, try to get the config.json file of a Web client
return executeRequest(null) {
authAPI.getWebClientConfig()
}
.let { webClientConfig ->
onWebClientConfigRetrieved(homeServerConnectionConfig, webClientConfig)
}
.map { riotConfig ->
onRiotConfigRetrieved(homeServerConnectionConfig, riotConfig)
}
.fold(
{
it
},
{
if (it is Failure.OtherServerError
&& it.httpCode == HttpsURLConnection.HTTP_NOT_FOUND /* 404 */) {
// Try with wellknown
getWellknownLoginFlowInternal(homeServerConnectionConfig)
} else {
throw it
}
}
)
}
private suspend fun onRiotConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, riotConfig: RiotConfig): LoginFlowResult {
val defaultHomeServerUrl = riotConfig.getPreferredHomeServerUrl()
private suspend fun onWebClientConfigRetrieved(homeServerConnectionConfig: HomeServerConnectionConfig, webClientConfig: WebClientConfig): LoginFlowResult {
val defaultHomeServerUrl = webClientConfig.getPreferredHomeServerUrl()
if (defaultHomeServerUrl?.isNotEmpty() == true) {
// Ok, good sign, we got a default hs url
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = Uri.parse(defaultHomeServerUrl)
homeServerUriBase = Uri.parse(defaultHomeServerUrl)
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
@ -275,15 +273,13 @@ internal class DefaultAuthenticationService @Inject constructor(
val domain = homeServerConnectionConfig.homeServerUri.host
?: throw Failure.OtherServerError("", HttpsURLConnection.HTTP_NOT_FOUND /* 404 */)
// Create a fake userId, for the getWellknown task
val fakeUserId = "@alice:$domain"
val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(fakeUserId, homeServerConnectionConfig))
val wellknownResult = getWellknownTask.execute(GetWellknownTask.Params(domain, homeServerConnectionConfig))
return when (wellknownResult) {
is WellknownResult.Prompt -> {
val newHomeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = Uri.parse(wellknownResult.homeServerUrl),
identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) }
homeServerUriBase = Uri.parse(wellknownResult.homeServerUrl),
identityServerUri = wellknownResult.identityServerUrl?.let { Uri.parse(it) } ?: homeServerConnectionConfig.identityServerUri
)
val newAuthAPI = buildAuthAPI(newHomeServerConnectionConfig)
@ -379,7 +375,14 @@ internal class DefaultAuthenticationService @Inject constructor(
override suspend fun getWellKnownData(matrixId: String,
homeServerConnectionConfig: HomeServerConnectionConfig?): WellknownResult {
return getWellknownTask.execute(GetWellknownTask.Params(matrixId, homeServerConnectionConfig))
if (!MatrixPatterns.isUserId(matrixId)) {
throw MatrixIdFailure.InvalidMatrixId
}
return getWellknownTask.execute(GetWellknownTask.Params(
domain = matrixId.getDomain(),
homeServerConnectionConfig = homeServerConnectionConfig)
)
}
override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
@ -390,7 +393,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUri.toString())
val retrofit = retrofitFactory.create(buildClient(homeServerConnectionConfig), homeServerConnectionConfig.homeServerUriBase.toString())
return retrofit.create(AuthAPI::class.java)
}

View File

@ -42,7 +42,7 @@ internal class DefaultIsValidClientServerApiTask @Inject constructor(
override suspend fun execute(params: IsValidClientServerApiTask.Params): Boolean {
val client = buildClient(params.homeServerConnectionConfig)
val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
val authAPI = retrofitFactory.create(client, homeServerUrl)
.create(AuthAPI::class.java)

View File

@ -56,7 +56,7 @@ internal class DefaultSessionCreator @Inject constructor(
tryOrNull {
isValidClientServerApiTask.execute(
IsValidClientServerApiTask.Params(
homeServerConnectionConfig.copy(homeServerUri = it)
homeServerConnectionConfig.copy(homeServerUriBase = it)
)
)
.also { Timber.d("Overriding homeserver url: $it") }
@ -66,7 +66,7 @@ internal class DefaultSessionCreator @Inject constructor(
val sessionParams = SessionParams(
credentials = credentials,
homeServerConnectionConfig = homeServerConnectionConfig.copy(
homeServerUri = overriddenUrl ?: homeServerConnectionConfig.homeServerUri,
homeServerUriBase = overriddenUrl ?: homeServerConnectionConfig.homeServerUriBase,
identityServerUri = credentials.discoveryInformation?.identityServer?.baseURL
// remove trailing "/"
?.trim { it == '/' }

View File

@ -20,7 +20,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
internal data class RiotConfig(
internal data class WebClientConfig(
/**
* This is now deprecated, but still used first, rather than value from "default_server_config"
*/
@ -28,7 +28,7 @@ internal data class RiotConfig(
val defaultHomeServerUrl: String?,
@Json(name = "default_server_config")
val defaultServerConfig: RiotConfigDefaultServerConfig?
val defaultServerConfig: WebClientConfigDefaultServerConfig?
) {
fun getPreferredHomeServerUrl(): String? {
return defaultHomeServerUrl
@ -38,13 +38,13 @@ internal data class RiotConfig(
}
@JsonClass(generateAdapter = true)
internal data class RiotConfigDefaultServerConfig(
internal data class WebClientConfigDefaultServerConfig(
@Json(name = "m.homeserver")
val homeServer: RiotConfigBaseConfig? = null
val homeServer: WebClientConfigBaseConfig? = null
)
@JsonClass(generateAdapter = true)
internal data class RiotConfigBaseConfig(
internal data class WebClientConfigBaseConfig(
@Json(name = "base_url")
val baseURL: String? = null
)

View File

@ -16,17 +16,19 @@
package org.matrix.android.sdk.internal.auth.db
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.auth.data.sessionId
import org.matrix.android.sdk.internal.di.MoshiProvider
import android.net.Uri
import io.realm.DynamicRealm
import io.realm.RealmMigration
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.auth.data.sessionId
import org.matrix.android.sdk.internal.di.MoshiProvider
import timber.log.Timber
internal object AuthRealmMigration : RealmMigration {
// Current schema version
const val SCHEMA_VERSION = 3L
const val SCHEMA_VERSION = 4L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.d("Migrating Auth Realm from $oldVersion to $newVersion")
@ -34,6 +36,7 @@ internal object AuthRealmMigration : RealmMigration {
if (oldVersion <= 0) migrateTo1(realm)
if (oldVersion <= 1) migrateTo2(realm)
if (oldVersion <= 2) migrateTo3(realm)
if (oldVersion <= 3) migrateTo4(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@ -81,4 +84,34 @@ internal object AuthRealmMigration : RealmMigration {
}
?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID)
}
private fun migrateTo4(realm: DynamicRealm) {
Timber.d("Step 3 -> 4")
Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value")
val adapter = MoshiProvider.providesMoshi()
.adapter(HomeServerConnectionConfig::class.java)
realm.schema.get("SessionParamsEntity")
?.transform {
val homeserverConnectionConfigJson = it.getString(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON)
val homeserverConnectionConfig = adapter
.fromJson(homeserverConnectionConfigJson)
val homeserverUrl = homeserverConnectionConfig?.homeServerUri?.toString()
// Special case for matrix.org. Old session may use "https://matrix.org", newer one may use
// "https://matrix-client.matrix.org". So fix that here
val alteredHomeserverConnectionConfig =
if (homeserverUrl == "https://matrix.org" || homeserverUrl == "https://matrix-client.matrix.org") {
homeserverConnectionConfig.copy(
homeServerUri = Uri.parse("https://matrix.org"),
homeServerUriBase = Uri.parse("https://matrix-client.matrix.org")
)
} else {
homeserverConnectionConfig
}
it.set(SessionParamsEntityFields.HOME_SERVER_CONNECTION_CONFIG_JSON, adapter.toJson(alteredHomeserverConnectionConfig))
}
}
}

View File

@ -50,7 +50,7 @@ internal class DefaultDirectLoginTask @Inject constructor(
override suspend fun execute(params: DirectLoginTask.Params): Session {
val client = buildClient(params.homeServerConnectionConfig)
val homeServerUrl = params.homeServerConnectionConfig.homeServerUri.toString()
val homeServerUrl = params.homeServerConnectionConfig.homeServerUriBase.toString()
val authAPI = retrofitFactory.create(client, homeServerUrl)
.create(AuthAPI::class.java)

View File

@ -112,7 +112,6 @@ internal abstract class CryptoModule {
@SessionScope
fun providesRealmConfiguration(@SessionFilesDirectory directory: File,
@UserMd5 userMd5: String,
realmCryptoStoreMigration: RealmCryptoStoreMigration,
realmKeysUtils: RealmKeysUtils): RealmConfiguration {
return RealmConfiguration.Builder()
.directory(directory)
@ -123,7 +122,7 @@ internal abstract class CryptoModule {
.modules(RealmCryptoStoreModule())
.allowWritesOnUiThread(true)
.schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
.migration(realmCryptoStoreMigration)
.migration(RealmCryptoStoreMigration)
.build()
}

View File

@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.crypto
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.auth.data.Credentials
@ -336,7 +337,12 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
downloadKeysForUsersTask.execute(params)
} catch (throwable: Throwable) {
Timber.e(throwable, "## CRYPTO | doKeyDownloadForUsers(): error")
if (throwable is CancellationException) {
// the crypto module is getting closed, so we cannot access the DB anymore
Timber.w("The crypto module is closed, ignoring this error")
} else {
onKeysDownloadFailed(filteredUsers)
}
throw throwable
}
Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users")

View File

@ -39,7 +39,9 @@ internal object MXEncryptedAttachments {
private const val SECRET_KEY_SPEC_ALGORITHM = "AES"
private const val MESSAGE_DIGEST_ALGORITHM = "SHA-256"
fun encrypt(clearStream: InputStream, mimetype: String?, outputFile: File, progress: ((current: Int, total: Int) -> Unit)): EncryptedFileInfo {
fun encrypt(clearStream: InputStream,
outputFile: File,
progress: ((current: Int, total: Int) -> Unit)): EncryptedFileInfo {
val t0 = System.currentTimeMillis()
val secureRandom = SecureRandom()
val initVectorBytes = ByteArray(16) { 0.toByte() }
@ -86,7 +88,6 @@ internal object MXEncryptedAttachments {
return EncryptedFileInfo(
url = null,
mimetype = mimetype,
key = EncryptedFileKey(
alg = "A256CTR",
ext = true,
@ -155,10 +156,9 @@ internal object MXEncryptedAttachments {
* Encrypt an attachment stream.
* DO NOT USE for big files, it will load all in memory
* @param attachmentStream the attachment stream. Will be closed after this method call.
* @param mimetype the mime type
* @return the encryption file info
*/
fun encryptAttachment(attachmentStream: InputStream, mimetype: String?): EncryptionResult {
fun encryptAttachment(attachmentStream: InputStream): EncryptionResult {
val t0 = System.currentTimeMillis()
val secureRandom = SecureRandom()
@ -207,7 +207,6 @@ internal object MXEncryptedAttachments {
return EncryptionResult(
encryptedFileInfo = EncryptedFileInfo(
url = null,
mimetype = mimetype,
key = EncryptedFileKey(
alg = "A256CTR",
ext = true,
@ -232,7 +231,9 @@ internal object MXEncryptedAttachments {
* @param outputStream the outputStream where the decrypted attachment will be write.
* @return true in case of success, false in case of error
*/
fun decryptAttachment(attachmentStream: InputStream?, elementToDecrypt: ElementToDecrypt?, outputStream: OutputStream): Boolean {
fun decryptAttachment(attachmentStream: InputStream?,
elementToDecrypt: ElementToDecrypt?,
outputStream: OutputStream): Boolean {
// sanity checks
if (null == attachmentStream || elementToDecrypt == null) {
Timber.e("## decryptAttachment() : null stream")

View File

@ -29,12 +29,6 @@ data class EncryptedFileInfo(
@Json(name = "url")
val url: String? = null,
/**
* Not documented
*/
@Json(name = "mimetype")
val mimetype: String? = null,
/**
* Required. A JSON Web Key object.
*/

View File

@ -475,7 +475,7 @@ internal interface IMXCryptoStore {
fun getGossipingEvents(): List<Event>
fun setDeviceKeysUploaded(uploaded: Boolean)
fun getDeviceKeysUploaded(): Boolean
fun areDeviceKeysUploaded(): Boolean
fun tidyUpDataBase()
fun logDbUsageInfo()
}

View File

@ -937,7 +937,7 @@ internal class RealmCryptoStore @Inject constructor(
}
}
override fun getDeviceKeysUploaded(): Boolean {
override fun areDeviceKeysUploaded(): Boolean {
return doWithRealm(realmConfiguration) {
it.where<CryptoMetadataEntity>().findFirst()?.deviceKeysSentToServer
} ?: false

View File

@ -18,6 +18,9 @@ package org.matrix.android.sdk.internal.crypto.store.db
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import io.realm.DynamicRealm
import io.realm.RealmMigration
import io.realm.RealmObjectSchema
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo
@ -35,29 +38,24 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntit
import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.TrustLevelEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.di.SerializeNulls
import io.realm.DynamicRealm
import io.realm.RealmMigration
import io.realm.RealmObjectSchema
import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessionInfoEntityFields
import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2
import timber.log.Timber
import javax.inject.Inject
import org.matrix.androidsdk.crypto.data.MXDeviceInfo as LegacyMXDeviceInfo
internal class RealmCryptoStoreMigration @Inject constructor(private val crossSigningKeysMapper: CrossSigningKeysMapper) : RealmMigration {
internal object RealmCryptoStoreMigration : RealmMigration {
companion object {
// 0, 1, 2: legacy Riot-Android
// 3: migrate to RiotX schema
// 4, 5, 6, 7, 8, 9: migrations from RiotX (which was previously 1, 2, 3, 4, 5, 6)
const val CRYPTO_STORE_SCHEMA_VERSION = 12L
}
private fun RealmObjectSchema.addFieldIfNotExists(fieldName: String, fieldType: Class<*>): RealmObjectSchema {
if (!hasField(fieldName)) {
@ -384,6 +382,8 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi
private fun migrateTo7(realm: DynamicRealm) {
Timber.d("Step 6 -> 7")
Timber.d("Updating KeyInfoEntity table")
val crossSigningKeysMapper = CrossSigningKeysMapper(MoshiProvider.providesMoshi())
val keyInfoEntities = realm.where("KeyInfoEntity").findAll()
try {
keyInfoEntities.forEach {

View File

@ -97,7 +97,7 @@ internal class DefaultInitializeCrossSigningTask @Inject constructor(
Timber.v("## CrossSigning - sskPublicKey:$sskPublicKey")
// Sign userSigningKey with master
// Sign selfSigningKey with master
val signedSSK = CryptoCrossSigningKey.Builder(userId, KeyUsage.SELF_SIGNING)
.key(sskPublicKey)
.build()

View File

@ -19,9 +19,10 @@ package org.matrix.android.sdk.internal.database
import io.realm.DynamicRealm
import io.realm.FieldAttribute
import io.realm.RealmMigration
import org.matrix.android.sdk.api.session.room.model.VersioningState
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
import org.matrix.android.sdk.api.session.room.model.VersioningState
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
@ -40,14 +41,12 @@ import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFie
import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFields
import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.query.process
import timber.log.Timber
import javax.inject.Inject
class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
internal object RealmSessionStoreMigration : RealmMigration {
companion object {
const val SESSION_STORE_SCHEMA_VERSION = 14L
}
const val SESSION_STORE_SCHEMA_VERSION = 16L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
@ -66,6 +65,8 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
if (oldVersion <= 11) migrateTo12(realm)
if (oldVersion <= 12) migrateTo13(realm)
if (oldVersion <= 13) migrateTo14(realm)
if (oldVersion <= 14) migrateTo15(realm)
if (oldVersion <= 15) migrateTo16(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@ -306,4 +307,27 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
roomAccountDataSchema.isEmbedded = true
}
private fun migrateTo15(realm: DynamicRealm) {
Timber.d("Step 14 -> 15")
// fix issue with flattenParentIds on DM that kept growing with duplicate
// so we reset it, will be updated next sync
realm.where("RoomSummaryEntity")
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships())
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
.findAll()
.onEach {
it.setString(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, null)
}
}
private fun migrateTo16(realm: DynamicRealm) {
Timber.d("Step 15 -> 16")
realm.schema.get("HomeServerCapabilitiesEntity")
?.addField(HomeServerCapabilitiesEntityFields.ROOM_VERSIONS_JSON, String::class.java)
?.transform { obj ->
// Schedule a refresh of the capabilities
obj.setLong(HomeServerCapabilitiesEntityFields.LAST_UPDATED_TIMESTAMP, 0)
}
}
}

View File

@ -43,7 +43,6 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
@SessionFilesDirectory val directory: File,
@SessionId val sessionId: String,
@UserMd5 val userMd5: String,
val migration: RealmSessionStoreMigration,
context: Context) {
// Keep legacy preferences name for compatibility reason
@ -72,7 +71,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
.allowWritesOnUiThread(true)
.modules(SessionRealmModule())
.schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION)
.migration(migration)
.migration(RealmSessionStoreMigration)
.build()
// Try creating a realm instance and if it succeeds we can clear the flag

View File

@ -16,8 +16,15 @@
package org.matrix.android.sdk.internal.database.mapper
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
import org.matrix.android.sdk.api.session.homeserver.RoomVersionCapabilities
import org.matrix.android.sdk.api.session.homeserver.RoomVersionInfo
import org.matrix.android.sdk.api.session.homeserver.RoomVersionStatus
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntity
import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.session.homeserver.RoomVersions
import org.matrix.android.sdk.internal.session.room.version.DefaultRoomVersionService
/**
* HomeServerCapabilitiesEntity -> HomeSeverCapabilities
@ -29,7 +36,30 @@ internal object HomeServerCapabilitiesMapper {
canChangePassword = entity.canChangePassword,
maxUploadFileSize = entity.maxUploadFileSize,
lastVersionIdentityServerSupported = entity.lastVersionIdentityServerSupported,
defaultIdentityServerUrl = entity.defaultIdentityServerUrl
defaultIdentityServerUrl = entity.defaultIdentityServerUrl,
roomVersions = mapRoomVersion(entity.roomVersionsJson)
)
}
private fun mapRoomVersion(roomVersionsJson: String?): RoomVersionCapabilities? {
roomVersionsJson ?: return null
return tryOrNull {
MoshiProvider.providesMoshi().adapter(RoomVersions::class.java).fromJson(roomVersionsJson)?.let {
RoomVersionCapabilities(
defaultRoomVersion = it.default ?: DefaultRoomVersionService.DEFAULT_ROOM_VERSION,
supportedVersion = it.available.entries.map { entry ->
RoomVersionInfo(
version = entry.key,
status = if (entry.value == "stable") {
RoomVersionStatus.STABLE
} else {
RoomVersionStatus.UNSTABLE
}
)
}
)
}
}
}
}

View File

@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
internal open class HomeServerCapabilitiesEntity(
var canChangePassword: Boolean = true,
var roomVersionsJson: String? = null,
var maxUploadFileSize: Long = HomeServerCapabilities.MAX_UPLOAD_FILE_SIZE_UNKNOWN,
var lastVersionIdentityServerSupported: Boolean = false,
var defaultIdentityServerUrl: String? = null,

View File

@ -20,7 +20,7 @@ import io.realm.RealmObject
import io.realm.annotations.Index
/**
* Clients can store custom config data for their account on their HomeServer.
* Clients can store custom config data for their account on their homeserver.
* This account data will be synced between different devices and can persist across installations on a particular device.
* Users may only view the account data for their own account.
* The account_data may be either global or scoped to a particular rooms.

View File

@ -37,7 +37,8 @@ internal abstract class FederationModule {
fun providesFederationAPI(@Unauthenticated okHttpClient: Lazy<OkHttpClient>,
sessionParams: SessionParams,
retrofitFactory: RetrofitFactory): FederationAPI {
return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrl).create(FederationAPI::class.java)
return retrofitFactory.create(okHttpClient, sessionParams.homeServerUrlBase)
.create(FederationAPI::class.java)
}
}

View File

@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.legacy.riot.HomeServerConnectionConfig as
internal class DefaultLegacySessionImporter @Inject constructor(
private val context: Context,
private val sessionParamsStore: SessionParamsStore,
private val realmCryptoStoreMigration: RealmCryptoStoreMigration,
private val realmKeysUtils: RealmKeysUtils
) : LegacySessionImporter {
@ -172,7 +171,7 @@ internal class DefaultLegacySessionImporter @Inject constructor(
.name("crypto_store.realm")
.modules(RealmCryptoStoreModule())
.schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
.migration(realmCryptoStoreMigration)
.migration(RealmCryptoStoreMigration)
.build()
Timber.d("Migration: copy DB to encrypted DB")

View File

@ -253,7 +253,7 @@ internal object CertUtil {
val list = ArrayList<ConnectionSpec>()
list.add(builder.build())
// TODO: we should display a warning if user enter an http url
if (hsConfig.allowHttpExtension || hsConfig.homeServerUri.toString().startsWith("http://")) {
if (hsConfig.allowHttpExtension || hsConfig.homeServerUriBase.toString().startsWith("http://")) {
list.add(ConnectionSpec.CLEARTEXT)
}
return list

View File

@ -29,10 +29,9 @@ internal class DefaultRawService @Inject constructor(
return getUrlTask.execute(GetUrlTask.Params(url, cacheStrategy))
}
override suspend fun getWellknown(userId: String): String {
val homeServerDomain = userId.substringAfter(":")
override suspend fun getWellknown(domain: String): String {
return getUrl(
"https://$homeServerDomain/.well-known/matrix/client",
"https://$domain/.well-known/matrix/client",
CacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
)
}

View File

@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificateWithProgress
import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor.Companion.DOWNLOAD_PROGRESS_INTERCEPTOR_HEADER
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.file.AtomicFileCreator
import org.matrix.android.sdk.internal.util.md5
import org.matrix.android.sdk.internal.util.writeToFile
import timber.log.Timber
@ -96,6 +97,9 @@ internal class DefaultFileService @Inject constructor(
}
}
var atomicFileDownload: AtomicFileCreator? = null
var atomicFileDecrypt: AtomicFileCreator? = null
if (existingDownload != null) {
// FIXME If the first downloader cancels then we'll unfortunately be cancelled too.
return existingDownload.await()
@ -131,8 +135,11 @@ internal class DefaultFileService @Inject constructor(
Timber.v("Response size ${response.body?.contentLength()} - Stream available: ${!source.exhausted()}")
// Write the file to cache (encrypted version if the file is encrypted)
writeToFile(source.inputStream(), cachedFiles.file)
// Write to a part file first, so if we abort before done, we don't have a broken cached file
val atomicFileCreator = AtomicFileCreator(cachedFiles.file).also { atomicFileDownload = it }
writeToFile(source.inputStream(), atomicFileCreator.partFile)
response.close()
atomicFileCreator.commit()
} else {
Timber.v("## FileService: cache hit for $url")
}
@ -145,8 +152,10 @@ internal class DefaultFileService @Inject constructor(
Timber.v("## FileService: decrypt file")
// Ensure the parent folder exists
cachedFiles.decryptedFile.parentFile?.mkdirs()
// Write to a part file first, so if we abort before done, we don't have a broken cached file
val atomicFileCreator = AtomicFileCreator(cachedFiles.decryptedFile).also { atomicFileDecrypt = it }
val decryptSuccess = cachedFiles.file.inputStream().use { inputStream ->
cachedFiles.decryptedFile.outputStream().buffered().use { outputStream ->
atomicFileCreator.partFile.outputStream().buffered().use { outputStream ->
MXEncryptedAttachments.decryptAttachment(
inputStream,
elementToDecrypt,
@ -154,6 +163,7 @@ internal class DefaultFileService @Inject constructor(
)
}
}
atomicFileCreator.commit()
if (!decryptSuccess) {
throw IllegalStateException("Decryption error")
}
@ -174,6 +184,11 @@ internal class DefaultFileService @Inject constructor(
}
toNotify?.completeWith(result)
result.onFailure {
atomicFileDownload?.cancel()
atomicFileDecrypt?.cancel()
}
return result.getOrThrow()
}

View File

@ -313,7 +313,7 @@ internal class DefaultSession @Inject constructor(
override fun getUiaSsoFallbackUrl(authenticationSessionId: String): String {
val hsBas = sessionParams.homeServerConnectionConfig
.homeServerUri
.homeServerUriBase
.toString()
.trim { it == '/' }
return buildString {

View File

@ -260,7 +260,7 @@ internal abstract class SessionModule {
sessionParams: SessionParams,
retrofitFactory: RetrofitFactory): Retrofit {
return retrofitFactory
.create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUri.toString())
.create(okHttpClient, sessionParams.homeServerConnectionConfig.homeServerUriBase.toString())
}
@JvmStatic

Some files were not shown because too many files have changed in this diff Show More