diff --git a/AUTHORS.md b/AUTHORS.md
index 4fb5b8c994..ad20133d83 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -4,7 +4,7 @@ A full developer contributors list can be found [here](https://github.com/vector
Even if we try to be able to work on all the functionalities, we have more knowledge about what we have developed ourselves.
-## Benoit: Android team leader
+## [Benoit](https://github.com/bmarty): Android team leader
[@benoit.marty:matrix.org](https://matrix.to/#/@benoit.marty:matrix.org)
- Android team leader and project leader, Android developer, GitHub community manager.
@@ -12,7 +12,7 @@ Even if we try to be able to work on all the functionalities, we have more knowl
- Reviewing and polishing developed features, code quality manager, PRs reviewer, GitHub community manager.
- Release manager on the Play Store
-## François: Software architect
+## [Ganfra](https://github.com/ganfra) (aka François): Software architect
[@ganfra:matrix.org](https://matrix.to/#/@ganfra:matrix.org)
- Software architect, Android developer
@@ -20,12 +20,17 @@ Even if we try to be able to work on all the functionalities, we have more knowl
- Work mainly on the global architecture of the project.
- Specialist of the timeline, and lots of other features.
-## Valere: Product manager, Android developer
+## [Valere](https://github.com/BillCarsonFr): Product manager, Android developer
[@valere35:matrix.org](https://matrix.to/#/@valere35:matrix.org)
- Product manager, Android developer
- Specialist on the crypto implementation.
+## [Onuray](https://github.com/onurays): Android developer
+
+[@onurays:matrix.org](https://matrix.to/#/@onurays:matrix.org)
+- Android developer
+
# Other contributors
First of all, we thank all contributors who use Element and report problems on this GitHub project or via the integrated rageshake function.
@@ -34,7 +39,7 @@ We do not forget all translators, for their work of translating Element into man
Feel free to add your name below, when you contribute to the project!
-Name | Matrix ID | GitHub
---------|---------------------|--------------------------------------
-gjpower | @gjpower:matrix.org | [gjpower](https://github.com/gjpower)
-
+Name | Matrix ID | GitHub
+----------|-----------------------------|--------------------------------------
+gjpower | @gjpower:matrix.org | [gjpower](https://github.com/gjpower)
+TR_SLimey | @tr_slimey:an-atom-in.space | [TR-SLimey](https://github.com/TR-SLimey)
diff --git a/CHANGES.md b/CHANGES.md
index 8dceffbcf0..b031e626eb 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,45 @@
+Changes in Element 1.0.11 (2020-11-27)
+===================================================
+
+Features ✨:
+ - Create DMs with users by scanning their QR code (#2025)
+ - Add Invite friends quick invite actions (#2348)
+ - Add friend by scanning QR code, show your code to friends (#2025)
+
+Improvements 🙌:
+ - New room creation tile with quick action (#2346)
+ - Open an existing DM instead of creating a new one (#2319)
+ - Use RoomMember instead of User in the context of a Room.
+ - Ask for explicit user consent to send their contact details to the identity server (#2375)
+ - Handle events of type "m.room.server_acl" (#890)
+ - Room creation form: add advanced section to disable federation (#1314)
+ - Move "Enable Encryption" from room setting screen to room profile screen (#2394)
+ - Home empty screens quick design update (#2347)
+ - Improve Invite user screen (seamless search for matrix ID)
+
+Bugfix 🐛:
+ - Fix crash on AttachmentViewer (#2365)
+ - Exclude yourself when decorating rooms which are direct or don't have more than 2 users (#2370)
+ - F-Droid version: ensure timeout of sync request can be more than 60 seconds (#2169)
+ - Fix issue when restoring draft after sharing (#2287)
+ - Fix issue when updating the avatar of a room (new avatar vanishing)
+ - Discard change dialog displayed by mistake when avatar has been updated
+ - Try to fix cropped image in timeline (#2126)
+ - Registration: annoying error message scares every new user when they add an email (#2391)
+ - Fix jitsi integration for those with non-vanilla dialler frameworks
+ - Update profile has no effect if user is in zero rooms
+ - Fix issues with matrix.to deep linking (#2349)
+
+SDK API changes ⚠️:
+ - AccountService now exposes suspendable function instead of using MatrixCallback (#2354).
+ Note: We will incrementally migrate all the SDK API in a near future (#2449)
+
+Test:
+ - Add `allScreensTest` to cover all screens of the app
+
+Other changes:
+ - Upgrade Realm dependency to 10.0.0
+
Changes in Element 1.0.10 (2020-11-04)
===================================================
@@ -1008,5 +1050,8 @@ SDK API changes ⚠️:
Build 🧱:
-
+Test:
+ -
+
Other changes:
-
diff --git a/fastlane/metadata/android/ca/changelogs/40100100.txt b/fastlane/metadata/android/ca/changelogs/40100100.txt
new file mode 100644
index 0000000000..70b786d12e
--- /dev/null
+++ b/fastlane/metadata/android/ca/changelogs/40100100.txt
@@ -0,0 +1 @@
+// TODO
diff --git a/fastlane/metadata/android/ca/full_description.txt b/fastlane/metadata/android/ca/full_description.txt
new file mode 100644
index 0000000000..b45a5488ea
--- /dev/null
+++ b/fastlane/metadata/android/ca/full_description.txt
@@ -0,0 +1,30 @@
+Element és un nou tipus d'aplicació de missatgeria i col·laboració que:
+
+1. Et dóna a tu el control per preservar la teva privadesa
+2. Et permet comunicar-te amb qualsevol persona de la xarxa Matrix i, fins i tot més enllà gràcies a integracions amb altres aplicacions com Slack
+3. Et protegeix de la publicitat, l'obtenció no desitjada de dades i dels navegadors amb accés controlat
+4. T'assegura a tu mitjançant l'encriptació d'extrem a extrem i amb signatures creuades per verificar els altres
+
+Element és completament diferent a les altres aplicacions de missatgeria i col·laboració ja que és descentralitzat i de codi obert.
+
+Element et deixa triar l'allotjament perquè disposis de privadesa, propietat i control de les teves dades i converses. Et dóna accés a una xarxa oberta perquè no et quedis únicament parlant amb els usuaris d'Element.
+
+Element pot fer tot això ja que opera sobre Matrix - l'estàndard per a les comunicacions obertes i descentralitzades.
+
+Element et dóna el control perquè et deixa escollir qui vols que allotgi les teves converses. Des de l'aplicació d'Element, pots triar l'allotjament de diferents maneres:
+
+1. Crea un compte gratuït al servidor públic de matrix.org allotjat pels desenvolupadors de Matrix o tria'n un entre els milers de servidors públics creats per voluntaris
+2. Allotja tu mateix el teu compte en el teu propi servidor
+3. Registra el compte en un servidor personalitzat subscrivint-te a la plataforma d'Element Matrix Services (EMS)
+
+Per què escollir Element?
+
+PROPIETAT DE LES TEVES DADES: Tu decideixes a on desar les teves dades i missatges. Tu les controles i n'ets el propietari, no una mega-corporació que s'aprofita de les teves dades o les cedeix a tercers.
+
+MISSATGERIA I COL·LABORACIÓ OBERTA: Pots parlar amb qualsevol que estigui a la xarxa Matrix, ja sigui amb Element o amb qualsevol altre aplicació Matrix, fins i tot encara que utilitzin sistemes de missatgeria diferents com Slack, IRC o XMPP.
+
+SUPER-SEGUR: Encriptació d'extrem a extrem real (només qui està conversant pot desxifrar els missatges), i amb signatures creuades per a verificar els dispositius dels participants en les converses.
+
+COMUNICACIÓ COMPLETA: Missatgeria, veu i video-trucades, compartició de fitxers, compartició de pantalla i un munt d'integracions, bots i ginys. Crea sales, comunitats, mantén-te en contacte i enllesteix el que et proposes.
+
+A TOT ARREU: Mantingues el contacte des de qualsevol lloc on siguis, amb un historial de missatges totalment sincronitzat entre tots els teus dispositius i també a la web: https://app.element.io.
diff --git a/fastlane/metadata/android/ca/short_description.txt b/fastlane/metadata/android/ca/short_description.txt
new file mode 100644
index 0000000000..1e842ec64e
--- /dev/null
+++ b/fastlane/metadata/android/ca/short_description.txt
@@ -0,0 +1 @@
+Xat i VoIP segurs i descentralitzats. Protegeix les teves dades de tercers.
diff --git a/fastlane/metadata/android/ca/title.txt b/fastlane/metadata/android/ca/title.txt
new file mode 100644
index 0000000000..adc831006a
--- /dev/null
+++ b/fastlane/metadata/android/ca/title.txt
@@ -0,0 +1 @@
+Element (anteriorment Riot.im)
diff --git a/fastlane/metadata/android/de/changelogs/40100100.txt b/fastlane/metadata/android/de/changelogs/40100100.txt
new file mode 100644
index 0000000000..70b786d12e
--- /dev/null
+++ b/fastlane/metadata/android/de/changelogs/40100100.txt
@@ -0,0 +1 @@
+// TODO
diff --git a/fastlane/metadata/android/en-US/changelogs/40100110.txt b/fastlane/metadata/android/en-US/changelogs/40100110.txt
new file mode 100644
index 0000000000..e587003352
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/40100110.txt
@@ -0,0 +1,2 @@
+This new version mainly contains user interface and user experience improvements. Now you can invite friends, and create DM very fast by scanning QR codes.
+Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.0.11
\ No newline at end of file
diff --git a/fastlane/metadata/android/es/changelogs/40100100.txt b/fastlane/metadata/android/es/changelogs/40100100.txt
new file mode 100644
index 0000000000..70b786d12e
--- /dev/null
+++ b/fastlane/metadata/android/es/changelogs/40100100.txt
@@ -0,0 +1 @@
+// TODO
diff --git a/fastlane/metadata/android/es/full_description.txt b/fastlane/metadata/android/es/full_description.txt
index 860a1f19c3..8c9915a735 100644
--- a/fastlane/metadata/android/es/full_description.txt
+++ b/fastlane/metadata/android/es/full_description.txt
@@ -1,30 +1,30 @@
Element es un nuevo tipo de aplicación de mensajería y colaboración que:
-1. Le da el control para preservar su privacidad
-2. Le permite comunicarse con cualquier persona en la red Matrix e incluso más allá al integrarse con aplicaciones como Slack.
-3. Te protege de la publicidad, la minería de datos y los jardines vallados.
-4. Lo protege a través del cifrado de un extremo a otro, con firma cruzada para verificar a otros
+1. Te da el control para preservar su privacidad
+2. Te permite comunicarse con cualquier persona en la red Matrix e incluso más allá al integrarse con aplicaciones como Slack
+3. Te protege de la publicidad, la minería de datos y los jardines vallados
+4. Te protege a través de encriptación de Extremo-a-Extremo, con firma cruzada para verificar a otros
Element es completamente diferente de otras aplicaciones de mensajería y colaboración porque es descentralizado y de código abierto.
-Element le permite autohospedarse, o elegir un host, para que tenga privacidad, propiedad y control de sus datos y conversaciones. Te da acceso a una red abierta; para que no se quede atascado hablando solo con otros usuarios de Element. Y es muy seguro.
+Element te permite tener su propio servidor privado, o elegir uno público, para que tenga privacidad, posesión, y control de sus datos y conversaciones. Te da acceso a una red abierta; para que no se quede atrapado hablando solo con otros usuarios de Element. Y es muy seguro.
Element puede hacer todo esto porque opera en Matrix, el estándar para la comunicación abierta y descentralizada.
-Element te da el control permitiéndote elegir quién aloja tus conversaciones. Desde la aplicación Element, puede elegir hospedar de diferentes maneras:
+Element te da el control permitiéndote elegir quién aloja tus conversaciones. Desde la aplicación Element, puedes elegir hospedar de diferentes maneras:
-1. Obtenga una cuenta gratuita en el servidor público de matrix.org alojado por los desarrolladores de Matrix, o elija entre miles de servidores públicos alojados por voluntarios
-2. Autohospede su cuenta ejecutando un servidor en su propio hardware
-3. Regístrese para obtener una cuenta en un servidor personalizado simplemente suscribiéndose a la plataforma de alojamiento de Element Matrix Services
+1. Obtén una cuenta gratuita en el servidor público de matrix.org alojado por los desarrolladores de Matrix, o elije entre miles de servidores públicos alojados por voluntarios
+2. Autohospeda tu cuenta con un servidor en tu propio hardware
+3. Regístrate para obtener una cuenta en un servidor personalizado simplemente suscribiéndote a la plataforma de alojamiento de Element Matrix Services
¿Por qué elegir Element?
-POSEE SUS DATOS: Tú decides dónde guardar tus datos y mensajes. Usted es el propietario y lo controla, no algún MEGACORP que extraiga sus datos o dé acceso a terceros.
+TOMA POSESIÓN DE TUS DATOS: Tú decides dónde guardar tus datos y mensajes. Tú eres el propietario y quien lo controla, no alguna MEGACORP que extrae tu datos o da acceso a terceros.
-MENSAJERÍA ABIERTA Y COLABORACIÓN: Puede chatear con cualquier otra persona en la red de Matrix, ya sea que estén usando Element u otra aplicación de Matrix, e incluso si están usando un sistema de mensajería diferente como Slack, IRC o XMPP.
+MENSAJERÍA ABIERTA Y COLABORACIÓN: Puede chatear con cualquier otra persona en la red de Matrix, tanto si usan Element u otra aplicación de Matrix, e incluso si están usando un sistema de mensajería diferente como Slack, IRC o XMPP.
-SUPER SEGURO: Cifrado real de extremo a extremo (solo aquellos en la conversación pueden descifrar mensajes) y firma cruzada para verificar los dispositivos de los participantes de la conversación.
+SUPER SEGURO: Encriptación de Extremo-a-Extremo real (solo aquellos en la conversación pueden descifrar mensajes) y firma cruzada para verificar los dispositivos de los participantes de la conversación.
-COMUNICACIÓN COMPLETA: Mensajería, llamadas de voz y video, uso compartido de archivos, uso compartido de pantalla y un montón de integraciones, bots y widgets. Construya salas, comunidades, manténgase en contacto y haga las cosas.
+COMUNICACIÓN COMPLETA: Mensajería, llamadas de voz y video, uso compartido de archivos, uso compartido de pantalla y un montón de integraciones, bots y widgets. Crea salas, comunidades, mantente en contacto y organízate con eficacia.
-EN TODAS PARTES: Manténgase en contacto donde quiera que esté con un historial de mensajes totalmente sincronizado en todos sus dispositivos y en la web en https://app.element.io.
+EN TODAS PARTES: Mantente en contacto donde quiera que estés con un historial de mensajes totalmente sincronizado en todos sus dispositivos y en la web en https://app.element.io.
diff --git a/fastlane/metadata/android/es/short_description.txt b/fastlane/metadata/android/es/short_description.txt
index 0562213351..473228e0df 100644
--- a/fastlane/metadata/android/es/short_description.txt
+++ b/fastlane/metadata/android/es/short_description.txt
@@ -1 +1 @@
-Chat y VoIP descentralizados seguros. Mantenga sus datos a salvo de terceros.
+Chat y VoIP descentralizados y seguros. Mantén tus datos a salvo de terceros.
diff --git a/fastlane/metadata/android/es/title.txt b/fastlane/metadata/android/es/title.txt
index adc831006a..971e5cf146 100644
--- a/fastlane/metadata/android/es/title.txt
+++ b/fastlane/metadata/android/es/title.txt
@@ -1 +1 @@
-Element (anteriorment Riot.im)
+Element (previamente Riot.im)
diff --git a/fastlane/metadata/android/fa/changelogs/40100100.txt b/fastlane/metadata/android/fa/changelogs/40100100.txt
new file mode 100644
index 0000000000..6123bfc7fc
--- /dev/null
+++ b/fastlane/metadata/android/fa/changelogs/40100100.txt
@@ -0,0 +1 @@
+// برای انجام
diff --git a/fastlane/metadata/android/it/changelogs/40100100.txt b/fastlane/metadata/android/it/changelogs/40100100.txt
new file mode 100644
index 0000000000..0c7cc8cc6c
--- /dev/null
+++ b/fastlane/metadata/android/it/changelogs/40100100.txt
@@ -0,0 +1 @@
+// DA FARE
diff --git a/fastlane/metadata/android/nb/short_description.txt b/fastlane/metadata/android/nb/short_description.txt
new file mode 100644
index 0000000000..b7cad4c849
--- /dev/null
+++ b/fastlane/metadata/android/nb/short_description.txt
@@ -0,0 +1 @@
+Sikker desentralisert chat & VoIP. Beskytt dataene dine fra tredjeparter.
diff --git a/fastlane/metadata/android/nb/title.txt b/fastlane/metadata/android/nb/title.txt
new file mode 100644
index 0000000000..aacee5be54
--- /dev/null
+++ b/fastlane/metadata/android/nb/title.txt
@@ -0,0 +1 @@
+Element (tidligere Riot.im)
diff --git a/fastlane/metadata/android/pt_BR/changelogs/40100100.txt b/fastlane/metadata/android/pt_BR/changelogs/40100100.txt
new file mode 100644
index 0000000000..02cfd45a87
--- /dev/null
+++ b/fastlane/metadata/android/pt_BR/changelogs/40100100.txt
@@ -0,0 +1 @@
+// A FAZER
diff --git a/fastlane/metadata/android/sv/changelogs/40100100.txt b/fastlane/metadata/android/sv/changelogs/40100100.txt
new file mode 100644
index 0000000000..6da756aca9
--- /dev/null
+++ b/fastlane/metadata/android/sv/changelogs/40100100.txt
@@ -0,0 +1 @@
+// ATT GÖRA
diff --git a/fastlane/metadata/android/zh_Hant/changelogs/40100100.txt b/fastlane/metadata/android/zh_Hant/changelogs/40100100.txt
new file mode 100644
index 0000000000..3c21bcbeb6
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant/changelogs/40100100.txt
@@ -0,0 +1 @@
+// 待辦事項
diff --git a/fastlane/metadata/android/zh_Hant/full_description.txt b/fastlane/metadata/android/zh_Hant/full_description.txt
new file mode 100644
index 0000000000..2fdf6fa478
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant/full_description.txt
@@ -0,0 +1,30 @@
+Element 是一種新型態的即時通訊軟體與協作應用程式:
+
+1. 自己的隱私自己掌控
+2. 讓您與任何在 Matrix 網路中的人通訊,甚至可與如 Slack 等的應用程式整合
+3. 保護您免受廣告、資料採礦與圍牆花園的侵害
+4. 透過端到端加密保護您,並使用交叉簽章來驗證其他人
+
+Element 是去中心化且開放原始碼的應用程式,因此與其他即時通訊與協作軟體完全不同。
+
+Element 讓您可以自架(或是自行選擇服務提供者)所以您擁有您資料與對話的隱私、所有權與控制權。它讓您可以存取開放的網路;因此,您不僅可以與其他 Matrix 使用者聊天。而且非常安全。
+
+Element 能作到這些事情是因為它在 Matrix 上執行,這是一個開放的去中心化通訊的標準。
+
+Element 讓您選擇您要在哪裡託管您的對話來將控制權還給您。在 Element 應用程式中,您可以選擇其他方式來託管:
+
+1. 在由 Matrix 開發者架設的 matrix.org 公開伺服器上取得免費的帳號,或是從數千個由志願者所架設的公開伺服器中選擇
+2. 在您自己的硬體上自行架設伺服器並建立帳號
+3. 訂閱 Element Matrix 服務託管平台並在自訂伺服氣上註冊帳號
+
+為何選擇 Element?
+
+擁有您的資料:您決定您的資料與訊息要放在哪裡。您擁有並控制它,而非某些科技巨頭會挖掘您的資料並將其售予第三方。
+
+開放的即時通訊與協作:您可以與 Matrix 網路中的任何人聊天,不管他們是使用 Element 或其他 Matrix 應用程式都可以,或甚至是其他的訊息系統,如 Slack、IRC 或 XMPP 也都可以。
+
+超級安全:即時的端到端加密(僅有參與對話的人可以解密訊息),以及交叉簽章以驗證對話參與者的裝置。
+
+完整通訊:即時通訊、語音與視訊通話、檔案分享、畫面分享與超多的整合、機器人與小工具。建立聊天室、保持聯繫並完成工作。
+
+無論您身在何處:無論您身在何處,都可以透過 https://app.element.io 來在所有裝置與網路上保持訊息歷史同步。
diff --git a/fastlane/metadata/android/zh_Hant/short_description.txt b/fastlane/metadata/android/zh_Hant/short_description.txt
new file mode 100644
index 0000000000..23bb82c04e
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant/short_description.txt
@@ -0,0 +1 @@
+安全的去中心化聊天與 VoIP。確保您的資料不受第三方的影響。
diff --git a/fastlane/metadata/android/zh_Hant/title.txt b/fastlane/metadata/android/zh_Hant/title.txt
new file mode 100644
index 0000000000..3be2260b73
--- /dev/null
+++ b/fastlane/metadata/android/zh_Hant/title.txt
@@ -0,0 +1 @@
+Element(曾名為 Riot.im)
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 99d667ccdc..cdc95ef6eb 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionSha256Sum=0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
+distributionSha256Sum=22449f5231796abd892c98b2a07c9ceebe4688d192cd2d6763f8e3bf8acbedeb
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
index 03df708c0c..0e5b88adb2 100644
--- a/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
+++ b/matrix-sdk-android-rx/src/main/java/org/matrix/android/sdk/rx/RxSession.kt
@@ -35,6 +35,7 @@ import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.pushers.Pusher
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
+import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.sync.SyncState
@@ -92,6 +93,13 @@ class RxSession(private val session: Session) {
}
}
+ fun liveRoomMember(userId: String, roomId: String): Observable> {
+ return session.getRoomMemberLive(userId, roomId).asObservable()
+ .startWithCallable {
+ session.getRoomMember(userId, roomId).toOptional()
+ }
+ }
+
fun liveUsers(): Observable> {
return session.getUsersLive().asObservable()
}
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index e4a8b8884a..29c709844a 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath "io.realm:realm-gradle-plugin:6.1.0"
+ classpath "io.realm:realm-gradle-plugin:10.0.0"
}
}
@@ -149,7 +149,7 @@ dependencies {
implementation 'androidx.exifinterface:exifinterface:1.3.0'
// Database
- implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
+ implementation 'com.github.Zhuinden:realm-monarchy:0.7.1'
kapt 'dk.ilios:realmfieldnameshelper:1.1.1'
// Work
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt
index ec5477f976..103b638c39 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/ChangePasswordTest.kt
@@ -43,8 +43,8 @@ class ChangePasswordTest : InstrumentedTest {
val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = false))
// Change password
- commonTestHelper.doSync {
- session.changePassword(TestConstants.PASSWORD, NEW_PASSWORD, it)
+ commonTestHelper.runBlockingTest {
+ session.changePassword(TestConstants.PASSWORD, NEW_PASSWORD)
}
// Try to login with the previous password, it will fail
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
index a6fbfd9b7a..9996eef0a8 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/account/DeactivateAccountTest.kt
@@ -43,8 +43,8 @@ class DeactivateAccountTest : InstrumentedTest {
val session = commonTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(withInitialSync = false))
// Deactivate the account
- commonTestHelper.doSync {
- session.deactivateAccount(TestConstants.PASSWORD, false, it)
+ commonTestHelper.runBlockingTest {
+ session.deactivateAccount(TestConstants.PASSWORD, false)
}
// Try to login on the previous account, it will fail (M_USER_DEACTIVATED)
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
index cbe4cca8a3..0e7088a6a5 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CommonTestHelper.kt
@@ -40,6 +40,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
@@ -343,6 +344,14 @@ class CommonTestHelper(context: Context) {
await(latch, timeout)
}
+ fun runBlockingTest(timeout: Long = TestConstants.timeOutMillis, block: suspend () -> T): T {
+ return runBlocking {
+ withTimeout(timeout) {
+ block()
+ }
+ }
+ }
+
// Transform a method with a MatrixCallback to a synchronous method
inline fun doSync(timeout: Long? = TestConstants.timeOutMillis, block: (MatrixCallback) -> Unit): T {
val lock = CountDownLatch(1)
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt
index 1a9165ade4..cbb22daf0f 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt
@@ -68,8 +68,8 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
if (encryptedRoom) {
val room = aliceSession.getRoom(roomId)!!
- mTestHelper.doSync {
- room.enableEncryption(callback = it)
+ mTestHelper.runBlockingTest {
+ room.enableEncryption()
}
}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
index 75c7ad4d53..a81f503e77 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt
@@ -555,7 +555,7 @@ class SASTest : InstrumentedTest {
mTestHelper.waitWithLatch {
mTestHelper.retryPeriodicallyWithLatch(it) {
- val prAlicePOV = aliceVerificationService.getExistingVerificationRequest(bobSession.myUserId)?.firstOrNull()
+ val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull()
requestID = prAlicePOV?.transactionId
Log.v("TEST", "== alicePOV is $prAlicePOV")
prAlicePOV?.transactionId != null && prAlicePOV.localId == req.localId
@@ -566,7 +566,7 @@ class SASTest : InstrumentedTest {
mTestHelper.waitWithLatch {
mTestHelper.retryPeriodicallyWithLatch(it) {
- val prBobPOV = bobVerificationService.getExistingVerificationRequest(aliceSession.myUserId)?.firstOrNull()
+ val prBobPOV = bobVerificationService.getExistingVerificationRequests(aliceSession.myUserId).firstOrNull()
Log.v("TEST", "== prBobPOV is $prBobPOV")
prBobPOV?.transactionId == requestID
}
@@ -581,7 +581,7 @@ class SASTest : InstrumentedTest {
// wait for alice to get the ready
mTestHelper.waitWithLatch {
mTestHelper.retryPeriodicallyWithLatch(it) {
- val prAlicePOV = aliceVerificationService.getExistingVerificationRequest(bobSession.myUserId)?.firstOrNull()
+ val prAlicePOV = aliceVerificationService.getExistingVerificationRequests(bobSession.myUserId).firstOrNull()
Log.v("TEST", "== prAlicePOV is $prAlicePOV")
prAlicePOV?.transactionId == requestID && prAlicePOV?.isReady != null
}
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
index 7db159cd0b..ae300c936d 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/session/search/SearchMessagesTest.kt
@@ -71,38 +71,27 @@ class SearchMessagesTest : InstrumentedTest {
commonTestHelper.await(lock)
lock = CountDownLatch(1)
- aliceSession
- .searchService()
- .search(
- searchTerm = "lore",
- limit = 10,
- includeProfile = true,
- afterLimit = 0,
- beforeLimit = 10,
- orderByRecent = true,
- nextBatch = null,
- roomId = aliceRoomId,
- callback = object : MatrixCallback {
- override fun onSuccess(data: SearchResult) {
- super.onSuccess(data)
- assertTrue(data.results?.size == 2)
- assertTrue(
- data.results
- ?.all {
- (it.event.content?.get("body") as? String)?.startsWith(MESSAGE).orFalse()
- }.orFalse()
- )
- lock.countDown()
- }
-
- override fun onFailure(failure: Throwable) {
- super.onFailure(failure)
- fail(failure.localizedMessage)
- lock.countDown()
- }
- }
- )
- lock.await(TestConstants.timeOutMillis, TimeUnit.MILLISECONDS)
+ val data = commonTestHelper.runBlockingTest {
+ aliceSession
+ .searchService()
+ .search(
+ searchTerm = "lore",
+ limit = 10,
+ includeProfile = true,
+ afterLimit = 0,
+ beforeLimit = 10,
+ orderByRecent = true,
+ nextBatch = null,
+ roomId = aliceRoomId
+ )
+ }
+ assertTrue(data.results?.size == 2)
+ assertTrue(
+ data.results
+ ?.all {
+ (it.event.content?.get("body") as? String)?.startsWith(MESSAGE).orFalse()
+ }.orFalse()
+ )
aliceTimeline.removeAllListeners()
cryptoTestData.cleanUp(commonTestHelper)
diff --git a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
index 5c03e8a855..630f6f1e29 100644
--- a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
+++ b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt
@@ -66,9 +66,9 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
}
private fun logJson(formattedJson: String) {
- val arr = formattedJson.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
- for (s in arr) {
- Timber.v(s)
- }
+ formattedJson
+ .lines()
+ .dropLastWhile { it.isEmpty() }
+ .forEach { Timber.v(it) }
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
index 645fb55bb9..48705ee7b7 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/login/LoginWizard.kt
@@ -27,7 +27,7 @@ interface LoginWizard {
* @param password the password field
* @param deviceName the initial device name
* @param callback the matrix callback on which you'll receive the result of authentication.
- * @return return a [Cancelable]
+ * @return a [Cancelable]
*/
fun login(login: String,
password: String,
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/Strings.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/Strings.kt
index a17e65b8e0..e264843ea4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/Strings.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/Strings.kt
@@ -22,3 +22,8 @@ fun CharSequence.ensurePrefix(prefix: CharSequence): CharSequence {
else -> "$prefix$this"
}
}
+
+/**
+ * Append a new line and then the provided string
+ */
+fun StringBuilder.appendNl(str: String) = append("\n").append(str)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
index 880a7be9ac..4da1662681 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/pushrules/PushRuleService.kt
@@ -15,11 +15,9 @@
*/
package org.matrix.android.sdk.api.pushrules
-import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.pushrules.rest.PushRule
import org.matrix.android.sdk.api.pushrules.rest.RuleSet
import org.matrix.android.sdk.api.session.events.model.Event
-import org.matrix.android.sdk.api.util.Cancelable
interface PushRuleService {
/**
@@ -29,13 +27,13 @@ interface PushRuleService {
fun getPushRules(scope: String = RuleScope.GLOBAL): RuleSet
- fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback): Cancelable
+ suspend fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean)
- fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable
+ suspend fun addPushRule(kind: RuleKind, pushRule: PushRule)
- fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule, callback: MatrixCallback): Cancelable
+ suspend fun updatePushRuleActions(kind: RuleKind, oldPushRule: PushRule, newPushRule: PushRule)
- fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback): Cancelable
+ suspend fun removePushRule(kind: RuleKind, pushRule: PushRule)
fun addPushRuleListener(listener: PushRuleListener)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
index 4e24a17047..19549a338e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/raw/RawService.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.raw
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* Useful methods to fetch raw data from the server. The access token will not be used to fetched the data
*/
@@ -26,17 +23,15 @@ interface RawService {
/**
* Get a URL, either from cache or from the remote server, depending on the cache strategy
*/
- fun getUrl(url: String,
- rawCacheStrategy: RawCacheStrategy,
- matrixCallback: MatrixCallback): Cancelable
+ suspend fun getUrl(url: String, rawCacheStrategy: RawCacheStrategy): String
/**
* Specific case for the well-known file. Cache validity is 8 hours
*/
- fun getWellknown(userId: String, matrixCallback: MatrixCallback): Cancelable
+ suspend fun getWellknown(userId: String): String
/**
* Clear all the cache data
*/
- fun clearCache(matrixCallback: MatrixCallback): Cancelable
+ suspend fun clearCache()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
index b05f0036b2..8915202f35 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/account/AccountService.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.account
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* This interface defines methods to manage the account. It's implemented at the session level.
*/
@@ -28,7 +25,7 @@ interface AccountService {
* @param password Current password.
* @param newPassword New password
*/
- fun changePassword(password: String, newPassword: String, callback: MatrixCallback): Cancelable
+ suspend fun changePassword(password: String, newPassword: String)
/**
* Deactivate the account.
@@ -46,5 +43,5 @@ interface AccountService {
* @param eraseAllData set to true to forget all messages that have been sent. Warning: this will cause future users to see
* an incomplete view of conversations
*/
- fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback): Cancelable
+ suspend fun deactivateAccount(password: String, eraseAllData: Boolean)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
index 65c6a1f1f7..2413786ea9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationService.kt
@@ -41,7 +41,7 @@ interface VerificationService {
fun getExistingTransaction(otherUserId: String, tid: String): VerificationTransaction?
- fun getExistingVerificationRequest(otherUserId: String): List?
+ fun getExistingVerificationRequests(otherUserId: String): List
fun getExistingVerificationRequest(otherUserId: String, tid: String?): PendingVerificationRequest?
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
index 82dea81a5b..0a7f3ff09f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt
@@ -56,6 +56,7 @@ object EventType {
const val STATE_ROOM_RELATED_GROUPS = "m.room.related_groups"
const val STATE_ROOM_PINNED_EVENT = "m.room.pinned_events"
const val STATE_ROOM_ENCRYPTION = "m.room.encryption"
+ const val STATE_ROOM_SERVER_ACL = "m.room.server_acl"
// Call Events
const val CALL_INVITE = "m.call.invite"
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt
index a4186b5a32..25c69e5025 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/group/Group.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.group
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* This interface defines methods to interact within a group.
*/
@@ -28,8 +25,7 @@ interface Group {
/**
* This methods allows you to refresh data about this group. It will be reflected on the GroupSummary.
* The SDK also takes care of refreshing group data every hour.
- * @param callback : the matrix callback to be notified of success or failure
* @return a Cancelable to be able to cancel requests.
*/
- fun fetchGroupData(callback: MatrixCallback): Cancelable
+ suspend fun fetchGroupData()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
index 537104a084..aedb813735 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt
@@ -92,9 +92,29 @@ interface IdentityService {
/**
* Search MatrixId of users providing email and phone numbers
+ * Note the the user consent has to be set to true, or it will throw a UserConsentNotProvided failure
+ * Application has to explicitly ask for the user consent, and the answer can be stored using [setUserConsent]
+ * Please see https://support.google.com/googleplay/android-developer/answer/9888076?hl=en for more details.
*/
fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable
+ /**
+ * Return the current user consent for the current identity server, which has been stored using [setUserConsent].
+ * If [setUserConsent] has not been called, the returned value will be false.
+ * Note that if the identity server is changed, the user consent is reset to false.
+ * @return the value stored using [setUserConsent] or false if [setUserConsent] has never been called, or if the identity server
+ * has been changed
+ */
+ fun getUserConsent(): Boolean
+
+ /**
+ * Set the user consent to the provided value. Application MUST explicitly ask for the user consent to send their private data
+ * (email and phone numbers) to the identity server.
+ * Please see https://support.google.com/googleplay/android-developer/answer/9888076?hl=en for more details.
+ * @param newValue true if the user explicitly give their consent, false if the user wants to revoke their consent.
+ */
+ fun setUserConsent(newValue: Boolean)
+
/**
* Get the status of the current user's threePid
* A lookup will be performed, but also pending binding state will be restored
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityServiceError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityServiceError.kt
index 72bb72cc2c..42fdb97643 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityServiceError.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityServiceError.kt
@@ -24,6 +24,7 @@ sealed class IdentityServiceError : Failure.FeatureFailure() {
object NoIdentityServerConfigured : IdentityServiceError()
object TermsNotSignedException : IdentityServiceError()
object BulkLookupSha256NotSupported : IdentityServiceError()
+ object UserConsentNotProvided : IdentityServiceError()
object BindingError : IdentityServiceError()
object NoCurrentBindingError : IdentityServiceError()
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt
index 7f264c6228..5e9f3e1eb9 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/MatrixLinkify.kt
@@ -17,6 +17,7 @@
package org.matrix.android.sdk.api.session.permalinks
import android.text.Spannable
+import org.matrix.android.sdk.api.MatrixPatterns
/**
* MatrixLinkify take a piece of text and turns all of the
@@ -35,7 +36,7 @@ object MatrixLinkify {
* I disable it because it mess up with pills, and even with pills, it does not work correctly:
* The url is not correct. Ex: for @user:matrix.org, the url will be @user:matrix.org, instead of a matrix.to
*/
- /*
+
// sanity checks
if (spannable.isEmpty()) {
return false
@@ -48,14 +49,21 @@ object MatrixLinkify {
val startPos = match.range.first
if (startPos == 0 || text[startPos - 1] != '/') {
val endPos = match.range.last + 1
- val url = text.substring(match.range)
+ var url = text.substring(match.range)
+ if (MatrixPatterns.isUserId(url)
+ || MatrixPatterns.isRoomAlias(url)
+ || MatrixPatterns.isRoomId(url)
+ || MatrixPatterns.isGroupId(url)
+ || MatrixPatterns.isEventId(url)) {
+ url = PermalinkService.MATRIX_TO_URL_BASE + url
+ }
val span = MatrixPermalinkSpan(url, callback)
spannable.setSpan(span, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
}
}
}
return hasMatch
- */
- return false
+
+// return false
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
index dc47c81a5f..347a3bb531 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkParser.kt
@@ -44,13 +44,12 @@ object PermalinkParser {
if (fragment.isNullOrEmpty()) {
return PermalinkData.FallbackLink(uri)
}
- val indexOfQuery = fragment.indexOf("?")
- val safeFragment = if (indexOfQuery != -1) fragment.substring(0, indexOfQuery) else fragment
+ val safeFragment = fragment.substringBefore('?')
val viaQueryParameters = fragment.getViaParameters()
// we are limiting to 2 params
val params = safeFragment
- .split(MatrixPatterns.SEP_REGEX.toRegex())
+ .split(MatrixPatterns.SEP_REGEX)
.filter { it.isNotEmpty() }
.take(2)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
index b772225f51..f30037e5c2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.room
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
+import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.util.Cancelable
@@ -141,4 +142,20 @@ interface RoomService {
* - the power level of the users are not taken into account. Normally in a DM, the 2 members are admins of the room
*/
fun getExistingDirectRoomWithUser(otherUserId: String): String?
+
+ /**
+ * Get a room member for the tuple {userId,roomId}
+ * @param userId the userId to look for.
+ * @param roomId the roomId to look for.
+ * @return the room member or null
+ */
+ fun getRoomMember(userId: String, roomId: String): RoomMemberSummary?
+
+ /**
+ * Observe a live room member for the tuple {userId,roomId}
+ * @param userId the userId to look for.
+ * @param roomId the roomId to look for.
+ * @return a LiveData of the optional found room member
+ */
+ fun getRoomMemberLive(userId: String, roomId: String): LiveData>
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
index e7e6bacc22..1251fd9857 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt
@@ -16,7 +16,6 @@
package org.matrix.android.sdk.api.session.room.crypto
-import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
interface RoomCryptoService {
@@ -30,6 +29,5 @@ interface RoomCryptoService {
/**
* Enable encryption of the room
*/
- fun enableEncryption(algorithm: String = MXCRYPTO_ALGORITHM_MEGOLM,
- callback: MatrixCallback)
+ suspend fun enableEncryption(algorithm: String = MXCRYPTO_ALGORITHM_MEGOLM)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/failure/CreateRoomFailure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/failure/CreateRoomFailure.kt
index b0df2963f7..b4e2dc645c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/failure/CreateRoomFailure.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/failure/CreateRoomFailure.kt
@@ -22,4 +22,9 @@ import org.matrix.android.sdk.api.failure.MatrixError
sealed class CreateRoomFailure : Failure.FeatureFailure() {
object CreatedWithTimeout : CreateRoomFailure()
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
+ sealed class RoomAliasError : CreateRoomFailure() {
+ object AliasEmpty : RoomAliasError()
+ object AliasNotAvailable : RoomAliasError()
+ object AliasInvalid : RoomAliasError()
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomServerAclContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomServerAclContent.kt
new file mode 100644
index 0000000000..92078054b7
--- /dev/null
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomServerAclContent.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 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
+
+import com.squareup.moshi.Json
+import com.squareup.moshi.JsonClass
+
+/**
+ * Class representing the EventType.STATE_ROOM_SERVER_ACL state event content
+ * Ref: https://matrix.org/docs/spec/client_server/r0.6.1#m-room-server-acl
+ */
+@JsonClass(generateAdapter = true)
+data class RoomServerAclContent(
+ /**
+ * True to allow server names that are IP address literals. False to deny.
+ * Defaults to true if missing or otherwise not a boolean.
+ * This is strongly recommended to be set to false as servers running with IP literal names are strongly
+ * discouraged in order to require legitimate homeservers to be backed by a valid registered domain name.
+ */
+ @Json(name = "allow_ip_literals")
+ val allowIpLiterals: Boolean = true,
+
+ /**
+ * The server names to allow in the room, excluding any port information. Wildcards may be used to cover
+ * a wider range of hosts, where * matches zero or more characters and ? matches exactly one character.
+ *
+ * This defaults to an empty list when not provided, effectively disallowing every server.
+ */
+ @Json(name = "allow")
+ val allowList: List = emptyList(),
+
+ /**
+ * The server names to disallow in the room, excluding any port information. Wildcards may be used to cover
+ * a wider range of hosts, where * matches zero or more characters and ? matches exactly one character.
+ *
+ * This defaults to an empty list when not provided.
+ */
+ @Json(name = "deny")
+ val denyList: List = emptyList()
+
+) {
+ companion object {
+ const val ALL = "*"
+ }
+}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
index 892a865751..80e3741a0c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt
@@ -94,7 +94,22 @@ class CreateRoomParams {
* The server will clobber the following keys: creator.
* Future versions of the specification may allow the server to clobber other keys.
*/
- var creationContent: Any? = null
+ val creationContent = mutableMapOf()
+
+ /**
+ * Set to true to disable federation of this room.
+ * Default: false
+ */
+ var disableFederation = false
+ set(value) {
+ field = value
+ if (value) {
+ creationContent[CREATION_CONTENT_KEY_M_FEDERATE] = false
+ } else {
+ // This is the default value, we remove the field
+ creationContent.remove(CREATION_CONTENT_KEY_M_FEDERATE)
+ }
+ }
/**
* The power level content to override in the default power level event
@@ -120,4 +135,8 @@ class CreateRoomParams {
fun enableEncryption() {
algorithm = MXCRYPTO_ALGORITHM_MEGOLM
}
+
+ companion object {
+ private const val CREATION_CONTENT_KEY_M_FEDERATE = "m.federate"
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/notification/RoomPushRuleService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/notification/RoomPushRuleService.kt
index 32d6033578..eb822c68ac 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/notification/RoomPushRuleService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/notification/RoomPushRuleService.kt
@@ -17,12 +17,10 @@
package org.matrix.android.sdk.api.session.room.notification
import androidx.lifecycle.LiveData
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
interface RoomPushRuleService {
fun getLiveRoomNotificationState(): LiveData
- fun setRoomNotificationState(roomNotificationState: RoomNotificationState, matrixCallback: MatrixCallback): Cancelable
+ suspend fun setRoomNotificationState(roomNotificationState: RoomNotificationState)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt
index 0ccdfd1d3c..a444e2346e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/reporting/ReportingService.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.room.reporting
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* This interface defines methods to report content of an event.
*/
@@ -28,5 +25,5 @@ interface ReportingService {
* Report content
* Ref: https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-rooms-roomid-report-eventid
*/
- fun reportContent(eventId: String, score: Int, reason: String, callback: MatrixCallback): Cancelable
+ suspend fun reportContent(eventId: String, score: Int, reason: String)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/DraftService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/DraftService.kt
index 116a60e323..a9481d71a2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/DraftService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/DraftService.kt
@@ -17,8 +17,6 @@
package org.matrix.android.sdk.api.session.room.send
import androidx.lifecycle.LiveData
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.Optional
interface DraftService {
@@ -26,12 +24,12 @@ interface DraftService {
/**
* Save or update a draft to the room
*/
- fun saveDraft(draft: UserDraft, callback: MatrixCallback): Cancelable
+ suspend fun saveDraft(draft: UserDraft)
/**
* Delete the last draft, basically just after sending the message
*/
- fun deleteDraft(callback: MatrixCallback): Cancelable
+ suspend fun deleteDraft()
/**
* Return the current draft or null
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/tags/TagsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/tags/TagsService.kt
index 3278c640de..69fde61f90 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/tags/TagsService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/tags/TagsService.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.room.tags
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* This interface defines methods to handle tags of a room. It's implemented at the room level.
*/
@@ -26,10 +23,10 @@ interface TagsService {
/**
* Add a tag to a room
*/
- fun addTag(tag: String, order: Double?, callback: MatrixCallback): Cancelable
+ suspend fun addTag(tag: String, order: Double?)
/**
* Remove tag from a room
*/
- fun deleteTag(tag: String, callback: MatrixCallback): Cancelable
+ suspend fun deleteTag(tag: String)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/search/SearchService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/search/SearchService.kt
index ef2eec433f..bc1c9e5769 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/search/SearchService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/search/SearchService.kt
@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.search
-import org.matrix.android.sdk.api.MatrixCallback
-import org.matrix.android.sdk.api.util.Cancelable
-
/**
* This interface defines methods to search messages in rooms.
*/
@@ -35,15 +32,13 @@ interface SearchService {
* @param beforeLimit how many events before the result are returned.
* @param afterLimit how many events after the result are returned.
* @param includeProfile requests that the server returns the historic profile information for the users that sent the events that were returned.
- * @param callback Callback to get the search result
*/
- fun search(searchTerm: String,
- roomId: String,
- nextBatch: String?,
- orderByRecent: Boolean,
- limit: Int,
- beforeLimit: Int,
- afterLimit: Int,
- includeProfile: Boolean,
- callback: MatrixCallback): Cancelable
+ suspend fun search(searchTerm: String,
+ roomId: String,
+ nextBatch: String?,
+ orderByRecent: Boolean,
+ limit: Int,
+ beforeLimit: Int,
+ afterLimit: Int,
+ includeProfile: Boolean): SearchResult
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt
index 2cfc4b731f..ab85f979bf 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt
@@ -35,6 +35,11 @@ interface UserService {
*/
fun getUser(userId: String): User?
+ /**
+ * Try to resolve user from known users, or using profile api
+ */
+ fun resolveUser(userId: String, callback: MatrixCallback)
+
/**
* Search list of users on server directory.
* @param search the searched term
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
index a8580bab8e..a786ebd4b2 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoModule.kt
@@ -123,6 +123,7 @@ internal abstract class CryptoModule {
}
.name("crypto_store.realm")
.modules(RealmCryptoStoreModule())
+ .allowWritesOnUiThread(true)
.schemaVersion(RealmCryptoStoreMigration.CRYPTO_STORE_SCHEMA_VERSION)
.migration(realmCryptoStoreMigration)
.build()
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
index d3a3fd9fbd..ebd809f777 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt
@@ -767,9 +767,9 @@ internal class DefaultCryptoService @Inject constructor(
*/
private fun onRoomKeyEvent(event: Event) {
val roomKeyContent = event.getClearContent().toModel() ?: return
- Timber.v("## CRYPTO | GOSSIP onRoomKeyEvent() : type<${event.getClearType()}> , sessionId<${roomKeyContent.sessionId}>")
+ Timber.i("## CRYPTO | onRoomKeyEvent() from: ${event.senderId} type<${event.getClearType()}> , sessionId<${roomKeyContent.sessionId}>")
if (roomKeyContent.roomId.isNullOrEmpty() || roomKeyContent.algorithm.isNullOrEmpty()) {
- Timber.e("## CRYPTO | GOSSIP onRoomKeyEvent() : missing fields")
+ Timber.e("## CRYPTO | onRoomKeyEvent() : missing fields")
return
}
val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(roomKeyContent.roomId, roomKeyContent.algorithm)
@@ -782,20 +782,20 @@ internal class DefaultCryptoService @Inject constructor(
private fun onKeyWithHeldReceived(event: Event) {
val withHeldContent = event.getClearContent().toModel() ?: return Unit.also {
- Timber.e("## CRYPTO | Malformed onKeyWithHeldReceived() : missing fields")
+ Timber.i("## CRYPTO | Malformed onKeyWithHeldReceived() : missing fields")
}
- Timber.d("## CRYPTO | onKeyWithHeldReceived() received : content <$withHeldContent>")
+ Timber.i("## CRYPTO | onKeyWithHeldReceived() received from:${event.senderId}, content <$withHeldContent>")
val alg = roomDecryptorProvider.getOrCreateRoomDecryptor(withHeldContent.roomId, withHeldContent.algorithm)
if (alg is IMXWithHeldExtension) {
alg.onRoomKeyWithHeldEvent(withHeldContent)
} else {
- Timber.e("## CRYPTO | onKeyWithHeldReceived() : Unable to handle WithHeldContent for ${withHeldContent.algorithm}")
+ Timber.e("## CRYPTO | onKeyWithHeldReceived() from:${event.senderId}: Unable to handle WithHeldContent for ${withHeldContent.algorithm}")
return
}
}
private fun onSecretSendReceived(event: Event) {
- Timber.i("## CRYPTO | GOSSIP onSecretSend() : onSecretSendReceived ${event.content?.get("sender_key")}")
+ Timber.i("## CRYPTO | GOSSIP onSecretSend() from ${event.senderId} : onSecretSendReceived ${event.content?.get("sender_key")}")
if (!event.isEncrypted()) {
// secret send messages must be encrypted
Timber.e("## CRYPTO | GOSSIP onSecretSend() :Received unencrypted secret send event")
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
index 38488f1ca7..92b7728890 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt
@@ -119,7 +119,7 @@ internal class EventDecryptor @Inject constructor(
markOlmSessionForUnwedging(event.senderId ?: "", it)
}
?: run {
- Timber.v("## CRYPTO | markOlmSessionForUnwedging() : Failed to find sender crypto device")
+ Timber.i("## CRYPTO | internalDecryptEvent() : Failed to find sender crypto device for unwedging")
}
}
}
@@ -137,16 +137,18 @@ internal class EventDecryptor @Inject constructor(
val lastForcedDate = lastNewSessionForcedDates.getObject(senderId, deviceKey) ?: 0
val now = System.currentTimeMillis()
if (now - lastForcedDate < DefaultCryptoService.CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS) {
- Timber.d("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another")
+ Timber.w("## CRYPTO | markOlmSessionForUnwedging: New session already forced with device at $lastForcedDate. Not forcing another")
return
}
- Timber.d("## CRYPTO | markOlmSessionForUnwedging from $senderId:${deviceInfo.deviceId}")
+ Timber.i("## CRYPTO | markOlmSessionForUnwedging from $senderId:${deviceInfo.deviceId}")
lastNewSessionForcedDates.setObject(senderId, deviceKey, now)
// offload this from crypto thread (?)
cryptoCoroutineScope.launch(coroutineDispatchers.computation) {
- ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true)
+ val ensured = ensureOlmSessionsForDevicesAction.handle(mapOf(senderId to listOf(deviceInfo)), force = true)
+
+ Timber.i("## CRYPTO | markOlmSessionForUnwedging() : ensureOlmSessionsForDevicesAction isEmpty:${ensured.isEmpty}")
// Now send a blank message on that session so the other side knows about it.
// (The keyshare request is sent in the clear so that won't do)
@@ -159,10 +161,14 @@ internal class EventDecryptor @Inject constructor(
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
val sendToDeviceMap = MXUsersDevicesMap()
sendToDeviceMap.setObject(senderId, deviceInfo.deviceId, encodedPayload)
- Timber.v("## CRYPTO | markOlmSessionForUnwedging() : sending to $senderId:${deviceInfo.deviceId}")
+ Timber.i("## CRYPTO | markOlmSessionForUnwedging() : sending dummy to $senderId:${deviceInfo.deviceId}")
withContext(coroutineDispatchers.io) {
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
- sendToDeviceTask.execute(sendToDeviceParams)
+ try {
+ sendToDeviceTask.execute(sendToDeviceParams)
+ } catch (failure: Throwable) {
+ Timber.e(failure, "## CRYPTO | markOlmSessionForUnwedging() : failed to send dummy to $senderId:${deviceInfo.deviceId}")
+ }
}
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
index 97ae0b9d83..4f94a27bbd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt
@@ -54,6 +54,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
private val cryptoCoroutineScope: CoroutineScope) {
private val executor = Executors.newSingleThreadExecutor()
+
// list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations
// we received in the current sync.
private val receivedGossipingRequests = ArrayList()
@@ -103,11 +104,11 @@ internal class IncomingGossipingRequestManager @Inject constructor(
* @param event the announcement event.
*/
fun onGossipingRequestEvent(event: Event) {
- Timber.v("## CRYPTO | GOSSIP onGossipingRequestEvent type ${event.type} from user ${event.senderId}")
val roomKeyShare = event.getClearContent().toModel()
+ Timber.i("## CRYPTO | GOSSIP onGossipingRequestEvent received type ${event.type} from user:${event.senderId}, content:$roomKeyShare")
// val ageLocalTs = event.unsignedData?.age?.let { System.currentTimeMillis() - it }
when (roomKeyShare?.action) {
- GossipingToDeviceObject.ACTION_SHARE_REQUEST -> {
+ GossipingToDeviceObject.ACTION_SHARE_REQUEST -> {
if (event.getClearType() == EventType.REQUEST_SECRET) {
IncomingSecretShareRequest.fromEvent(event)?.let {
if (event.senderId == credentials.userId && it.deviceId == credentials.deviceId) {
@@ -324,7 +325,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
val isDeviceLocallyVerified = cryptoStore.getUserDevice(userId, deviceId)?.trustLevel?.isLocallyVerified()
when (secretName) {
- MASTER_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.master
+ MASTER_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.master
SELF_SIGNING_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.selfSigned
USER_SIGNING_KEY_SSSS_NAME -> cryptoStore.getCrossSigningPrivateKeys()?.user
KEYBACKUP_SECRET_SSSS_NAME -> cryptoStore.getKeyBackupRecoveryKeyInfo()?.recoveryKey
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt
index 1a4d1136c8..c952602d93 100755
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt
@@ -760,7 +760,7 @@ internal class MXOlmDevice @Inject constructor(
return session
}
} else {
- Timber.v("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
+ Timber.w("## getInboundGroupSession() : Cannot retrieve inbound group session $sessionId")
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID, MXCryptoError.UNKNOWN_INBOUND_SESSION_ID_REASON)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt
index f0a3413978..bcaa16f356 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt
@@ -100,7 +100,7 @@ internal class SendGossipWorker(context: Context,
requestId = params.requestId,
state = GossipingRequestState.FAILED_TO_ACCEPTED
)
- Timber.e("no session with this device, probably because there were no one-time keys.")
+ Timber.e("no session with this device $requestingDeviceId, probably because there were no one-time keys.")
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
index b05f2cd592..95b99c54e8 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt
@@ -69,7 +69,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(
//
// That should eventually resolve itself, but it's poor form.
- Timber.v("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim")
+ Timber.i("## CRYPTO | claimOneTimeKeysForUsersDevices() : $usersDevicesToClaim")
val claimParams = ClaimOneTimeKeysForUsersDeviceTask.Params(usersDevicesToClaim)
val oneTimeKeys = oneTimeKeysForUsersDeviceTask.execute(claimParams)
@@ -90,7 +90,7 @@ internal class EnsureOlmSessionsForDevicesAction @Inject constructor(
oneTimeKey = key
}
if (oneTimeKey == null) {
- Timber.v("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm
+ Timber.w("## CRYPTO | ensureOlmSessionsForDevices() : No one-time keys " + oneTimeKeyAlgorithm
+ " for device " + userId + " : " + deviceId)
continue
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
index e0116fae1c..787d16defc 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt
@@ -243,8 +243,7 @@ internal class MXMegolmDecryption(private val userId: String,
return
}
if (event.getClearType() == EventType.FORWARDED_ROOM_KEY) {
- Timber.v("## CRYPTO | onRoomKeyEvent(), forward adding key : roomId ${roomKeyContent.roomId}" +
- " sessionId ${roomKeyContent.sessionId} sessionKey ${roomKeyContent.sessionKey}")
+ Timber.i("## CRYPTO | onRoomKeyEvent(), forward adding key : ${roomKeyContent.roomId}|${roomKeyContent.sessionId}")
val forwardedRoomKeyContent = event.getClearContent().toModel()
?: return
@@ -273,9 +272,7 @@ internal class MXMegolmDecryption(private val userId: String,
keysClaimed["ed25519"] = forwardedRoomKeyContent.senderClaimedEd25519Key
} else {
- Timber.v("## CRYPTO | onRoomKeyEvent(), Adding key : roomId " + roomKeyContent.roomId + " sessionId " + roomKeyContent.sessionId
- + " sessionKey " + roomKeyContent.sessionKey) // from " + event);
-
+ Timber.i("## CRYPTO | onRoomKeyEvent(), Adding key : ${roomKeyContent.roomId}|${roomKeyContent.sessionId}")
if (null == senderKey) {
Timber.e("## onRoomKeyEvent() : key event has no sender key (not encrypted?)")
return
@@ -285,7 +282,7 @@ internal class MXMegolmDecryption(private val userId: String,
keysClaimed = event.getKeysClaimed().toMutableMap()
}
- Timber.e("## CRYPTO | onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
+ Timber.i("## CRYPTO | onRoomKeyEvent addInboundGroupSession ${roomKeyContent.sessionId}")
val added = olmDevice.addInboundGroupSession(roomKeyContent.sessionId,
roomKeyContent.sessionKey,
roomKeyContent.roomId,
@@ -349,10 +346,10 @@ internal class MXMegolmDecryption(private val userId: String,
if (olmSessionResult?.sessionId == null) {
// no session with this device, probably because there
// were no one-time keys.
+ Timber.e("no session with this device $deviceId, probably because there were no one-time keys.")
return@mapCatching
}
- Timber.v("## CRYPTO | shareKeysWithDevice() : sharing keys for session" +
- " ${body.senderKey}|${body.sessionId} with device $userId:$deviceId")
+ Timber.i("## CRYPTO | shareKeysWithDevice() : sharing session ${body.sessionId} with device $userId:$deviceId")
val payloadJson = mutableMapOf("type" to EventType.FORWARDED_ROOM_KEY)
runCatching { olmDevice.getInboundGroupSession(body.sessionId, body.senderKey, body.roomId) }
@@ -363,6 +360,7 @@ internal class MXMegolmDecryption(private val userId: String,
},
{
// TODO
+ Timber.e(it, "## CRYPTO | shareKeysWithDevice: failed to get session for request $body")
}
)
@@ -370,9 +368,13 @@ internal class MXMegolmDecryption(private val userId: String,
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
val sendToDeviceMap = MXUsersDevicesMap()
sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
- Timber.v("## CRYPTO | shareKeysWithDevice() : sending to $userId:$deviceId")
+ Timber.i("## CRYPTO | shareKeysWithDevice() : sending ${body.sessionId} to $userId:$deviceId")
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
- sendToDeviceTask.execute(sendToDeviceParams)
+ try {
+ sendToDeviceTask.execute(sendToDeviceParams)
+ } catch (failure: Throwable) {
+ Timber.e(failure, "## CRYPTO | shareKeysWithDevice() : Failed to send ${body.sessionId} to $userId:$deviceId")
+ }
}
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
index e55cf37118..fd431ce735 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt
@@ -217,8 +217,10 @@ internal class MXMegolmEncryption(
Timber.v("## CRYPTO | shareUserDevicesKey() : starts")
val results = ensureOlmSessionsForDevicesAction.handle(devicesByUser)
- Timber.v("## CRYPTO | shareUserDevicesKey() : ensureOlmSessionsForDevices succeeds after "
- + (System.currentTimeMillis() - t0) + " ms")
+ Timber.v(
+ """## CRYPTO | shareUserDevicesKey(): ensureOlmSessionsForDevices succeeds after ${System.currentTimeMillis() - t0} ms"""
+ .trimMargin()
+ )
val contentMap = MXUsersDevicesMap()
var haveTargets = false
val userIds = results.userIds
@@ -242,7 +244,7 @@ internal class MXMegolmEncryption(
continue
}
- Timber.v("## CRYPTO | shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
+ Timber.i("## CRYPTO | shareUserDevicesKey() : Sharing keys with device $userId:$deviceID")
contentMap.setObject(userId, deviceID, messageEncrypter.encryptMessage(payload, listOf(sessionResult.deviceInfo)))
haveTargets = true
}
@@ -270,21 +272,22 @@ internal class MXMegolmEncryption(
if (haveTargets) {
t0 = System.currentTimeMillis()
- Timber.v("## CRYPTO | shareUserDevicesKey() : has target")
+ Timber.i("## CRYPTO | shareUserDevicesKey() ${session.sessionId} : has target")
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, contentMap)
try {
sendToDeviceTask.execute(sendToDeviceParams)
- Timber.v("## CRYPTO | shareUserDevicesKey() : sendToDevice succeeds after ${System.currentTimeMillis() - t0} ms")
+ Timber.i("## CRYPTO | shareUserDevicesKey() : sendToDevice succeeds after ${System.currentTimeMillis() - t0} ms")
} catch (failure: Throwable) {
// What to do here...
Timber.e("## CRYPTO | shareUserDevicesKey() : Failed to share session <${session.sessionId}> with $devicesByUser ")
}
} else {
- Timber.v("## CRYPTO | shareUserDevicesKey() : no need to sharekey")
+ Timber.i("## CRYPTO | shareUserDevicesKey() : no need to sharekey")
}
}
private fun notifyKeyWithHeld(targets: List, sessionId: String, senderKey: String?, code: WithHeldCode) {
+ Timber.i("## CRYPTO | notifyKeyWithHeld() :sending withheld key for $targets session:$sessionId ")
val withHeldContent = RoomKeyWithHeldContent(
roomId = roomId,
senderKey = senderKey,
@@ -393,16 +396,16 @@ internal class MXMegolmEncryption(
userId: String,
deviceId: String,
senderKey: String): Boolean {
- Timber.d("[MXMegolmEncryption] reshareKey: $sessionId to $userId:$deviceId")
+ Timber.i("## Crypto process reshareKey for $sessionId to $userId:$deviceId")
val deviceInfo = cryptoStore.getUserDevice(userId, deviceId) ?: return false
- .also { Timber.w("Device not found") }
+ .also { Timber.w("## Crypto reshareKey: Device not found") }
// Get the chain index of the key we previously sent this device
val chainIndex = outboundSession?.sharedWithHelper?.wasSharedWith(userId, deviceId) ?: return false
.also {
// Send a room key with held
notifyKeyWithHeld(listOf(UserDevice(userId, deviceId)), sessionId, senderKey, WithHeldCode.UNAUTHORISED)
- Timber.w("[MXMegolmEncryption] reshareKey : ERROR : Never share megolm with this device")
+ Timber.w("## Crypto reshareKey: ERROR : Never share megolm with this device")
}
val devicesByUser = mapOf(userId to listOf(deviceInfo))
@@ -411,9 +414,11 @@ internal class MXMegolmEncryption(
olmSessionResult?.sessionId
?: // no session with this device, probably because there were no one-time keys.
// ensureOlmSessionsForDevicesAction has already done the logging, so just skip it.
- return false
+ return false.also {
+ Timber.w("## Crypto reshareKey: no session with this device, probably because there were no one-time keys")
+ }
- Timber.d("[MXMegolmEncryption] reshareKey: sharing keys for session $senderKey|$sessionId:$chainIndex with device $userId:$deviceId")
+ Timber.i("[MXMegolmEncryption] reshareKey: sharing keys for session $senderKey|$sessionId:$chainIndex with device $userId:$deviceId")
val payloadJson = mutableMapOf("type" to EventType.FORWARDED_ROOM_KEY)
@@ -425,6 +430,7 @@ internal class MXMegolmEncryption(
},
{
// TODO
+ Timber.e(it, "[MXMegolmEncryption] reshareKey: failed to get session $sessionId|$senderKey|$roomId")
}
)
@@ -432,13 +438,14 @@ internal class MXMegolmEncryption(
val encodedPayload = messageEncrypter.encryptMessage(payloadJson, listOf(deviceInfo))
val sendToDeviceMap = MXUsersDevicesMap()
sendToDeviceMap.setObject(userId, deviceId, encodedPayload)
- Timber.v("## CRYPTO | CRYPTO | reshareKey() : sending to $userId:$deviceId")
+ Timber.i("## CRYPTO | reshareKey() : sending session $sessionId to $userId:$deviceId")
val sendToDeviceParams = SendToDeviceTask.Params(EventType.ENCRYPTED, sendToDeviceMap)
return try {
sendToDeviceTask.execute(sendToDeviceParams)
+ Timber.i("## CRYPTO reshareKey() : successfully send <$sessionId> to $userId:$deviceId")
true
} catch (failure: Throwable) {
- Timber.e(failure, "## CRYPTO | CRYPTO | reshareKey() : fail to send <$sessionId> to $userId:$deviceId")
+ Timber.e(failure, "## CRYPTO reshareKey() : fail to send <$sessionId> to $userId:$deviceId")
false
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt
index 1871dba0e2..bcad448eb6 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt
@@ -38,7 +38,6 @@ import org.matrix.android.sdk.internal.task.TaskThread
import org.matrix.android.sdk.internal.task.configureWith
import org.matrix.android.sdk.internal.util.JsonCanonicalizer
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
-import org.matrix.android.sdk.internal.util.withoutPrefix
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
@@ -444,7 +443,7 @@ internal class DefaultCrossSigningService @Inject constructor(
} else {
// Maybe it's signed by a locally trusted device?
myMasterKey.signatures?.get(userId)?.forEach { (key, value) ->
- val potentialDeviceId = key.withoutPrefix("ed25519:")
+ val potentialDeviceId = key.removePrefix("ed25519:")
val potentialDevice = myDevices?.firstOrNull { it.deviceId == potentialDeviceId } // cryptoStore.getUserDevice(userId, potentialDeviceId)
if (potentialDevice != null && potentialDevice.isVerified) {
// Check signature validity?
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt
index f28fe7d642..665d770e7f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt
@@ -241,9 +241,9 @@ internal class UpdateTrustWorker(context: Context,
private fun computeRoomShield(activeMemberUserIds: List, roomSummaryEntity: RoomSummaryEntity): RoomEncryptionTrustLevel {
Timber.d("## CrossSigning - computeRoomShield ${roomSummaryEntity.roomId} -> $activeMemberUserIds")
// The set of “all users” depends on the type of room:
- // For regular / topic rooms, all users including yourself, are considered when decorating a room
+ // For regular / topic rooms which have more than 2 members (including yourself) are considered when decorating a room
// For 1:1 and group DM rooms, all other users (i.e. excluding yourself) are considered when decorating a room
- val listToCheck = if (roomSummaryEntity.isDirect) {
+ val listToCheck = if (roomSummaryEntity.isDirect || activeMemberUserIds.size <= 2) {
activeMemberUserIds.filter { it != myUserId }
} else {
activeMemberUserIds
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
index 72274aa70a..6b83c4f7d1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt
@@ -1679,27 +1679,24 @@ internal class RealmCryptoStore @Inject constructor(
// Only keep one week history
realm.where()
.lessThan(IncomingGossipingRequestEntityFields.LOCAL_CREATION_TIMESTAMP, prevWeekTs)
- .findAll().let {
- Timber.i("## Crypto Clean up ${it.size} IncomingGossipingRequestEntity")
- it.deleteAllFromRealm()
- }
+ .findAll()
+ .also { Timber.i("## Crypto Clean up ${it.size} IncomingGossipingRequestEntity") }
+ .deleteAllFromRealm()
// Clean the cancelled ones?
realm.where()
.equalTo(OutgoingGossipingRequestEntityFields.REQUEST_STATE_STR, OutgoingGossipingRequestState.CANCELLED.name)
.equalTo(OutgoingGossipingRequestEntityFields.TYPE_STR, GossipRequestType.KEY.name)
- .findAll().let {
- Timber.i("## Crypto Clean up ${it.size} OutgoingGossipingRequestEntity")
- it.deleteAllFromRealm()
- }
+ .findAll()
+ .also { Timber.i("## Crypto Clean up ${it.size} OutgoingGossipingRequestEntity") }
+ .deleteAllFromRealm()
// Only keep one week history
realm.where()
.lessThan(GossipingEventEntityFields.AGE_LOCAL_TS, prevWeekTs)
- .findAll().let {
- Timber.i("## Crypto Clean up ${it.size} GossipingEventEntityFields")
- it.deleteAllFromRealm()
- }
+ .findAll()
+ .also { Timber.i("## Crypto Clean up ${it.size} GossipingEventEntityFields") }
+ .deleteAllFromRealm()
// Can we do something for WithHeldSessionEntity?
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
index 7f02750359..a92f5c5bf1 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt
@@ -537,11 +537,10 @@ internal class DefaultVerificationService @Inject constructor(
// If there is a corresponding request, we can auto accept
// as we are the one requesting in first place (or we accepted the request)
// I need to check if the pending request was related to this device also
- val autoAccept = getExistingVerificationRequest(otherUserId)?.any {
+ val autoAccept = getExistingVerificationRequests(otherUserId).any {
it.transactionId == startReq.transactionId
&& (it.requestInfo?.fromDevice == this.deviceId || it.readyInfo?.fromDevice == this.deviceId)
}
- ?: false
val tx = DefaultIncomingSASDefaultVerificationTransaction(
// this,
setDeviceVerificationAction,
@@ -837,8 +836,8 @@ internal class DefaultVerificationService @Inject constructor(
// SAS do not care for now?
}
- // Now transactions are udated, let's also update Requests
- val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == doneReq.transactionId }
+ // Now transactions are updated, let's also update Requests
+ val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == doneReq.transactionId }
if (existingRequest == null) {
Timber.e("## SAS Received Done for unknown request txId:${doneReq.transactionId}")
return
@@ -892,7 +891,7 @@ internal class DefaultVerificationService @Inject constructor(
private fun handleReadyReceived(senderId: String,
readyReq: ValidVerificationInfoReady,
transportCreator: (DefaultVerificationTransaction) -> VerificationTransport) {
- val existingRequest = getExistingVerificationRequest(senderId)?.find { it.transactionId == readyReq.transactionId }
+ val existingRequest = getExistingVerificationRequests(senderId).find { it.transactionId == readyReq.transactionId }
if (existingRequest == null) {
Timber.e("## SAS Received Ready for unknown request txId:${readyReq.transactionId} fromDevice ${readyReq.fromDevice}")
return
@@ -1041,9 +1040,9 @@ internal class DefaultVerificationService @Inject constructor(
}
}
- override fun getExistingVerificationRequest(otherUserId: String): List? {
+ override fun getExistingVerificationRequests(otherUserId: String): List {
synchronized(lock = pendingRequests) {
- return pendingRequests[otherUserId]
+ return pendingRequests[otherUserId].orEmpty()
}
}
@@ -1205,7 +1204,7 @@ internal class DefaultVerificationService @Inject constructor(
Timber.i("## Requesting verification to user: $otherUserId with device list $otherDevices")
val targetDevices = otherDevices ?: cryptoStore.getUserDevices(otherUserId)
- ?.values?.map { it.deviceId } ?: emptyList()
+ ?.values?.map { it.deviceId }.orEmpty()
val requestsForUser = pendingRequests.getOrPut(otherUserId) { mutableListOf() }
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt
index cb254eac3c..22a190c68e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/SASDefaultVerificationTransaction.kt
@@ -28,7 +28,6 @@ import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager
import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.extensions.toUnsignedInt
-import org.matrix.android.sdk.internal.util.withoutPrefix
import org.matrix.olm.OlmSAS
import org.matrix.olm.OlmUtility
import timber.log.Timber
@@ -250,7 +249,7 @@ internal abstract class SASDefaultVerificationTransaction(
// cannot be empty because it has been validated
theirMacSafe.mac.keys.forEach {
- val keyIDNoPrefix = it.withoutPrefix("ed25519:")
+ val keyIDNoPrefix = it.removePrefix("ed25519:")
val otherDeviceKey = otherUserKnownDevices?.get(keyIDNoPrefix)?.fingerprint()
if (otherDeviceKey == null) {
Timber.w("## SAS Verification: Could not find device $keyIDNoPrefix to verify")
@@ -273,7 +272,7 @@ internal abstract class SASDefaultVerificationTransaction(
if (otherCrossSigningMasterKeyPublic != null) {
// Did the user signed his master key
theirMacSafe.mac.keys.forEach {
- val keyIDNoPrefix = it.withoutPrefix("ed25519:")
+ val keyIDNoPrefix = it.removePrefix("ed25519:")
if (keyIDNoPrefix == otherCrossSigningMasterKeyPublic) {
// Check the signature
val mac = macUsingAgreedMethod(otherCrossSigningMasterKeyPublic, baseInfo + it)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
index 6c430e8591..0e3a7a2c49 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmKeysUtils.kt
@@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database
import android.content.Context
import android.util.Base64
import androidx.core.content.edit
+import io.realm.Realm
import org.matrix.android.sdk.BuildConfig
import org.matrix.android.sdk.internal.session.securestorage.SecretStoringUtils
import io.realm.RealmConfiguration
@@ -46,7 +47,7 @@ internal class RealmKeysUtils @Inject constructor(context: Context,
private val sharedPreferences = context.getSharedPreferences("im.vector.matrix.android.keys", Context.MODE_PRIVATE)
private fun generateKeyForRealm(): ByteArray {
- val keyForRealm = ByteArray(RealmConfiguration.KEY_LENGTH)
+ val keyForRealm = ByteArray(Realm.ENCRYPTION_KEY_LENGTH)
rng.nextBytes(keyForRealm)
return keyForRealm
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
index 3324520d29..244fe3432a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt
@@ -69,6 +69,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
.apply {
realmKeysUtils.configureEncryption(this, SessionModule.getKeyAlias(userMd5))
}
+ .allowWritesOnUiThread(true)
.modules(SessionRealmModule())
.schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION)
.migration(migration)
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/TimeOutInterceptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/TimeOutInterceptor.kt
index 6c604f232f..724ec0dc7f 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/TimeOutInterceptor.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/TimeOutInterceptor.kt
@@ -52,5 +52,8 @@ internal class TimeOutInterceptor @Inject constructor() : Interceptor {
const val CONNECT_TIMEOUT = "CONNECT_TIMEOUT"
const val READ_TIMEOUT = "READ_TIMEOUT"
const val WRITE_TIMEOUT = "WRITE_TIMEOUT"
+
+ // 1 minute
+ const val DEFAULT_LONG_TIMEOUT: Long = 60_000
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
index be01366efa..3b0d7546e5 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/DefaultRawService.kt
@@ -16,45 +16,28 @@
package org.matrix.android.sdk.internal.raw
-import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.raw.RawCacheStrategy
import org.matrix.android.sdk.api.raw.RawService
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
import java.util.concurrent.TimeUnit
import javax.inject.Inject
internal class DefaultRawService @Inject constructor(
- private val taskExecutor: TaskExecutor,
private val getUrlTask: GetUrlTask,
private val cleanRawCacheTask: CleanRawCacheTask
) : RawService {
- override fun getUrl(url: String,
- rawCacheStrategy: RawCacheStrategy,
- matrixCallback: MatrixCallback): Cancelable {
- return getUrlTask
- .configureWith(GetUrlTask.Params(url, rawCacheStrategy)) {
- callback = matrixCallback
- }
- .executeBy(taskExecutor)
+ override suspend fun getUrl(url: String, rawCacheStrategy: RawCacheStrategy): String {
+ return getUrlTask.execute(GetUrlTask.Params(url, rawCacheStrategy))
}
- override fun getWellknown(userId: String,
- matrixCallback: MatrixCallback): Cancelable {
+ override suspend fun getWellknown(userId: String): String {
val homeServerDomain = userId.substringAfter(":")
return getUrl(
"https://$homeServerDomain/.well-known/matrix/client",
- RawCacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false),
- matrixCallback
+ RawCacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
)
}
- override fun clearCache(matrixCallback: MatrixCallback): Cancelable {
- return cleanRawCacheTask
- .configureWith(Unit) {
- callback = matrixCallback
- }
- .executeBy(taskExecutor)
+ override suspend fun clearCache() {
+ cleanRawCacheTask.execute(Unit)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
index 31a39d45e5..1165d2116b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/account/DefaultAccountService.kt
@@ -16,30 +16,17 @@
package org.matrix.android.sdk.internal.session.account
-import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.account.AccountService
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
import javax.inject.Inject
internal class DefaultAccountService @Inject constructor(private val changePasswordTask: ChangePasswordTask,
- private val deactivateAccountTask: DeactivateAccountTask,
- private val taskExecutor: TaskExecutor) : AccountService {
+ private val deactivateAccountTask: DeactivateAccountTask) : AccountService {
- override fun changePassword(password: String, newPassword: String, callback: MatrixCallback): Cancelable {
- return changePasswordTask
- .configureWith(ChangePasswordTask.Params(password, newPassword)) {
- this.callback = callback
- }
- .executeBy(taskExecutor)
+ override suspend fun changePassword(password: String, newPassword: String) {
+ changePasswordTask.execute(ChangePasswordTask.Params(password, newPassword))
}
- override fun deactivateAccount(password: String, eraseAllData: Boolean, callback: MatrixCallback): Cancelable {
- return deactivateAccountTask
- .configureWith(DeactivateAccountTask.Params(password, eraseAllData)) {
- this.callback = callback
- }
- .executeBy(taskExecutor)
+ override suspend fun deactivateAccount(password: String, eraseAllData: Boolean) {
+ deactivateAccountTask.execute(DeactivateAccountTask.Params(password, eraseAllData))
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt
index 01b57767b3..4f610fd81b 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/DefaultGroup.kt
@@ -16,20 +16,13 @@
package org.matrix.android.sdk.internal.session.group
-import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.group.Group
-import org.matrix.android.sdk.api.util.Cancelable
-import org.matrix.android.sdk.internal.task.TaskExecutor
-import org.matrix.android.sdk.internal.task.configureWith
internal class DefaultGroup(override val groupId: String,
- private val taskExecutor: TaskExecutor,
private val getGroupDataTask: GetGroupDataTask) : Group {
- override fun fetchGroupData(callback: MatrixCallback): Cancelable {
+ override suspend fun fetchGroupData() {
val params = GetGroupDataTask.Params.FetchWithIds(listOf(groupId))
- return getGroupDataTask.configureWith(params) {
- this.callback = callback
- }.executeBy(taskExecutor)
+ getGroupDataTask.execute(params)
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt
index 31450763d8..653d2a6933 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/group/GroupFactory.kt
@@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.group
import org.matrix.android.sdk.api.session.group.Group
import org.matrix.android.sdk.internal.session.SessionScope
-import org.matrix.android.sdk.internal.task.TaskExecutor
import javax.inject.Inject
internal interface GroupFactory {
@@ -26,14 +25,12 @@ internal interface GroupFactory {
}
@SessionScope
-internal class DefaultGroupFactory @Inject constructor(private val getGroupDataTask: GetGroupDataTask,
- private val taskExecutor: TaskExecutor) :
+internal class DefaultGroupFactory @Inject constructor(private val getGroupDataTask: GetGroupDataTask) :
GroupFactory {
override fun create(groupId: String): Group {
return DefaultGroup(
groupId = groupId,
- taskExecutor = taskExecutor,
getGroupDataTask = getGroupDataTask
)
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
index 20f8b7f868..c6fb34151c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt
@@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
import org.matrix.android.sdk.internal.util.ensureProtocol
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.extensions.orFalse
import timber.log.Timber
import javax.inject.Inject
import javax.net.ssl.HttpsURLConnection
@@ -243,7 +244,20 @@ internal class DefaultIdentityService @Inject constructor(
))
}
+ override fun getUserConsent(): Boolean {
+ return identityStore.getIdentityData()?.userConsent.orFalse()
+ }
+
+ override fun setUserConsent(newValue: Boolean) {
+ identityStore.setUserConsent(newValue)
+ }
+
override fun lookUp(threePids: List, callback: MatrixCallback>): Cancelable {
+ if (!getUserConsent()) {
+ callback.onFailure(IdentityServiceError.UserConsentNotProvided)
+ return NoOpCancellable
+ }
+
if (threePids.isEmpty()) {
callback.onSuccess(emptyList())
return NoOpCancellable
@@ -255,6 +269,9 @@ internal class DefaultIdentityService @Inject constructor(
}
override fun getShareStatus(threePids: List, callback: MatrixCallback