mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-22 09:04:33 +03:00
Merge 1.3.7
This commit is contained in:
commit
ec4923fbc8
428 changed files with 4873 additions and 3826 deletions
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
|
@ -18,6 +18,5 @@ updates:
|
||||||
open-pull-requests-limit: 200
|
open-pull-requests-limit: 200
|
||||||
reviewers:
|
reviewers:
|
||||||
- "bmarty"
|
- "bmarty"
|
||||||
### ignore:
|
ignore:
|
||||||
### - dependency-name: com.squareup.okhttp3:logging-interceptor
|
- dependency-name: com.google.zxing:core
|
||||||
### versions: "> 3.12.10"
|
|
||||||
|
|
36
CHANGES.md
36
CHANGES.md
|
@ -1,3 +1,39 @@
|
||||||
|
Changes in Element v1.3.7 (2021-11-04)
|
||||||
|
======================================
|
||||||
|
|
||||||
|
Features ✨
|
||||||
|
----------
|
||||||
|
- Adding the room name to the invitation notification (if the room summary is available) ([#582](https://github.com/vector-im/element-android/issues/582))
|
||||||
|
- Updating single sign on providers ordering to match priority/popularity ([#4277](https://github.com/vector-im/element-android/issues/4277))
|
||||||
|
|
||||||
|
Bugfixes 🐛
|
||||||
|
----------
|
||||||
|
- Stops showing a dedicated redacted event notification, the message notifications will update accordingly ([#1491](https://github.com/vector-im/element-android/issues/1491))
|
||||||
|
- Fixes marking individual notifications as read causing other notifications to be dismissed ([#3395](https://github.com/vector-im/element-android/issues/3395))
|
||||||
|
- Fixing missing send button in light mode dev tools - send * event ([#3674](https://github.com/vector-im/element-android/issues/3674))
|
||||||
|
- Fixing room search needing exact casing for non latin-1 character named rooms ([#3968](https://github.com/vector-im/element-android/issues/3968))
|
||||||
|
- Fixing call ringtones only playing once when the ringtone doesn't contain looping metadata (android 9.0 and above) ([#4047](https://github.com/vector-im/element-android/issues/4047))
|
||||||
|
- Tentatively fixing the doubled notifications by updating the group summary at specific points in the notification rendering cycle ([#4152](https://github.com/vector-im/element-android/issues/4152))
|
||||||
|
- Do not show shortcuts if a PIN code is set ([#4170](https://github.com/vector-im/element-android/issues/4170))
|
||||||
|
- Fixes being unable to join rooms by name ([#4255](https://github.com/vector-im/element-android/issues/4255))
|
||||||
|
- Fixing missing F-Droid notifications when in background due to background syncs not triggering ([#4298](https://github.com/vector-im/element-android/issues/4298))
|
||||||
|
- Fix video compression before upload ([#4353](https://github.com/vector-im/element-android/issues/4353))
|
||||||
|
- Fixing QR code crashes caused by a known issue in the zxing library for older versions of android by downgrading to 3.3.3 ([#4361](https://github.com/vector-im/element-android/issues/4361))
|
||||||
|
- Fixing timeline crash when rotating with the emoji window open ([#4365](https://github.com/vector-im/element-android/issues/4365))
|
||||||
|
- Fix handling of links coming from web instance reported as malformed by mistake ([#4369](https://github.com/vector-im/element-android/issues/4369))
|
||||||
|
|
||||||
|
SDK API changes ⚠️
|
||||||
|
------------------
|
||||||
|
- Add API `LoginWizard.loginCustom(data: JsonDict): Session` to be able to login to a homeserver using arbitrary request content ([#4266](https://github.com/vector-im/element-android/issues/4266))
|
||||||
|
- Add optional deviceId to the login API ([#4334](https://github.com/vector-im/element-android/issues/4334))
|
||||||
|
|
||||||
|
Other changes
|
||||||
|
-------------
|
||||||
|
- Migrate app DI framework to Hilt ([#3888](https://github.com/vector-im/element-android/issues/3888))
|
||||||
|
- Limit supported TLS versions and cipher suites ([#4192](https://github.com/vector-im/element-android/issues/4192))
|
||||||
|
- Fixed capitalisation of text on initial sync screen ([#4292](https://github.com/vector-im/element-android/issues/4292))
|
||||||
|
|
||||||
|
|
||||||
Changes in Element v1.3.6 (2021-10-26)
|
Changes in Element v1.3.6 (2021-10-26)
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ buildscript {
|
||||||
// https://developer.android.com/studio/releases/gradle-plugin
|
// https://developer.android.com/studio/releases/gradle-plugin
|
||||||
classpath libs.gradle.gradlePlugin
|
classpath libs.gradle.gradlePlugin
|
||||||
classpath libs.gradle.kotlinPlugin
|
classpath libs.gradle.kotlinPlugin
|
||||||
|
classpath libs.gradle.hiltPlugin
|
||||||
classpath 'com.google.gms:google-services:4.3.10'
|
classpath 'com.google.gms:google-services:4.3.10'
|
||||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
|
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3'
|
||||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.4'
|
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.4'
|
||||||
|
|
|
@ -11,7 +11,7 @@ def gradle = "7.0.3"
|
||||||
// Ref: https://kotlinlang.org/releases.html
|
// Ref: https://kotlinlang.org/releases.html
|
||||||
def kotlin = "1.5.31"
|
def kotlin = "1.5.31"
|
||||||
def kotlinCoroutines = "1.5.2"
|
def kotlinCoroutines = "1.5.2"
|
||||||
def dagger = "2.39.1"
|
def dagger = "2.40"
|
||||||
def retrofit = "2.9.0"
|
def retrofit = "2.9.0"
|
||||||
def arrow = "0.8.2"
|
def arrow = "0.8.2"
|
||||||
def markwon = "4.6.2"
|
def markwon = "4.6.2"
|
||||||
|
@ -34,7 +34,9 @@ def androidxTest = "1.4.0"
|
||||||
ext.libs = [
|
ext.libs = [
|
||||||
gradle : [
|
gradle : [
|
||||||
'gradlePlugin' : "com.android.tools.build:gradle:$gradle",
|
'gradlePlugin' : "com.android.tools.build:gradle:$gradle",
|
||||||
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
|
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin",
|
||||||
|
'hiltPlugin' : "com.google.dagger:hilt-android-gradle-plugin:$dagger"
|
||||||
|
|
||||||
],
|
],
|
||||||
jetbrains : [
|
jetbrains : [
|
||||||
'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines",
|
'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines",
|
||||||
|
@ -72,7 +74,9 @@ ext.libs = [
|
||||||
],
|
],
|
||||||
dagger : [
|
dagger : [
|
||||||
'dagger' : "com.google.dagger:dagger:$dagger",
|
'dagger' : "com.google.dagger:dagger:$dagger",
|
||||||
'daggerCompiler' : "com.google.dagger:dagger-compiler:$dagger"
|
'daggerCompiler' : "com.google.dagger:dagger-compiler:$dagger",
|
||||||
|
'hilt' : "com.google.dagger:hilt-android:$dagger",
|
||||||
|
'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger"
|
||||||
],
|
],
|
||||||
squareup : [
|
squareup : [
|
||||||
'moshi' : "com.squareup.moshi:moshi-adapters:$moshi",
|
'moshi' : "com.squareup.moshi:moshi-adapters:$moshi",
|
||||||
|
|
33
docs/hilt_migration.md
Normal file
33
docs/hilt_migration.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
Useful links:
|
||||||
|
- https://dagger.dev/hilt/migration-guide
|
||||||
|
- https://dagger.dev/hilt/quick-start
|
||||||
|
|
||||||
|
Hilt is built on top of Dagger 2 and simplify usage by removing needs to create components manually.
|
||||||
|
|
||||||
|
When you create a new feature, you should have the following:
|
||||||
|
|
||||||
|
Annotate your Activity with @AndroidEntryPoint
|
||||||
|
If you have a BottomSheetFragment => Annotate it with @AndroidEntryPoint
|
||||||
|
Otherwise => Add your Fragment to the FragmentModule
|
||||||
|
Add your ViewModel.Factory to the MavericksViewModelModule
|
||||||
|
Makes sure your ViewModel as the following code:
|
||||||
|
|
||||||
|
```
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory: MavericksAssistedViewModelFactory<MyViewModel, MyViewState> {
|
||||||
|
override fun create(initialState: MyViewState): MyViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MavericksViewModelFactory<MyViewModel, MyViewState> by hiltMavericksViewModelFactory()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Some remarks
|
||||||
|
|
||||||
|
@MavericksViewModelScope dependencies can't be injected inside Fragments/Activities
|
||||||
|
You can only inject @Singleton, @MavericksViewModelScope or unscoped dependencies inside Maverick ViewModels
|
||||||
|
You can access some specific dependencies from Singleton component by using
|
||||||
|
```
|
||||||
|
context.singletonEntryPoint()
|
||||||
|
```
|
||||||
|
Be aware that only the app has been migrated to Hilt and not the SDK.
|
||||||
|
|
2
fastlane/metadata/android/cs-CZ/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/cs-CZ/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Hlavní změny v této verzi: Přidání podpory přítomnosti pro místnost s přímými zprávami (poznámka: přítomnost je na matrix.org zakázána). Opět přidána podpora Android Auto.
|
||||||
|
Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/de-DE/changelogs/40103000.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/40103000.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Hauptänderungen: Organisiere deine Räume mit Spaces!
|
||||||
|
Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.0
|
2
fastlane/metadata/android/de-DE/changelogs/40103010.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/40103010.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Hauptänderungen: Organisiere deine Räume mit Spaces, Crash aus 1.3.0 gefixt.
|
||||||
|
Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.1
|
2
fastlane/metadata/android/de-DE/changelogs/40103020.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/40103020.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Hauptänderungen: Unterstützung für Android Auto, Viele Fehlerbehebungen
|
||||||
|
Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.2
|
2
fastlane/metadata/android/de-DE/changelogs/40103030.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/40103030.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Hauptänderungen: Bedingungen des Identitätsservers in Einstellungen anzeigen. Unterstützung für Android Auto temporär entfernt.
|
||||||
|
Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.3
|
4
fastlane/metadata/android/de-DE/changelogs/40103040.txt
Normal file
4
fastlane/metadata/android/de-DE/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
Hauptänderungen:
|
||||||
|
- Anwesenheiten in Direktnachrichten anzeigen (Momentan auf Matrix.org deaktiviert)
|
||||||
|
- Android Auto wird wieder unterstützt
|
||||||
|
Alle Änderungen: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
|
@ -37,3 +37,6 @@ Kurznachrichten, Sprach- und Videoanrufe, Dateifreigaben, Bildschirmübertragung
|
||||||
|
|
||||||
<b>Da Weitermachen, wo Sie aufgehört haben</b>
|
<b>Da Weitermachen, wo Sie aufgehört haben</b>
|
||||||
Bleiben Sie in Kontakt, egal wo Sie sind, mit vollständig synchronisiertem Nachrichtenverlauf quer über all Ihre Geräte und im Netz auf https://app.element.io
|
Bleiben Sie in Kontakt, egal wo Sie sind, mit vollständig synchronisiertem Nachrichtenverlauf quer über all Ihre Geräte und im Netz auf https://app.element.io
|
||||||
|
|
||||||
|
<b>Open source</b>
|
||||||
|
Element ist ein Open-Source-Projekt und wird auf GitHub gehostet. Solltest du Fehler in Element finden, melde diese bitte hier: https://github.com/vector-im/element-android
|
||||||
|
|
2
fastlane/metadata/android/en-US/changelogs/40103070.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/40103070.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Main changes in this version: Bug fixes mainly regarding the notifications.
|
||||||
|
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.3.7
|
2
fastlane/metadata/android/et/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/et/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Põhilised muutused selles versioonis: Lisasime otsevestlustele kasutaja võrguolekute toe (matrix.org puhul on välja lülitatud) ja uuesti lisasime Android Auto toe.
|
||||||
|
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/fa/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/fa/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
تغییرات اصلی در این نگارش: افزودن پشتیبانی حضور برای اتاق پیام خصوصی (توجه: حضور روی matrix.org از کار افتاده است). افزودن دوبارهٔ پشتیبانی اندروید خودرو.
|
||||||
|
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/fr-FR/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/fr-FR/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Principaux changements pour cette version : ajout du support pour les indicateurs de présence, dans les conversations privées (attention : les indicateurs de présence sont désactivés sur matrix.org). Réactivation de la prise en charge de Android Auto.
|
||||||
|
Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/hu-HU/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/hu-HU/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Fő változás ebben a verzióban: Állapot állítási lehetőség közvetlen beszélgetéseknél (megj.: a matrix.org-on az állapot jelzés ki van kapcsolva). Újra elérhető az Android Auto.
|
||||||
|
Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/id/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/id/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Perubahan utama di versi ini: Menambahkan dukungan presensi, untuk ruangan Pesan Langsung (diingat bahwa presensi dinonaktifkan di matrix.org). Menambahkan lagi dukungan Android Auto.
|
||||||
|
Changelog lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/it-IT/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/it-IT/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Modifiche principali in questa versione: aggiunto supporto alla presenza per messaggi diretti (nota: la presenza è disattivata su matrix.org). Aggiunto di nuovo il supporto ad Android Auto.
|
||||||
|
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/pt-BR/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/pt-BR/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Principais mudanças nesta versão: Adicionar suporte a Presença, para sala de Mensagem Direta (nota: presença está desabilitada em matrix.org). Adicionar de novo suporte a Android Auto.
|
||||||
|
Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/ru-RU/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/ru-RU/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Основные изменения в этой версии: Добавлена поддержка присутствия, для комнат личных сообщений (примечание: присутствие отключено на matrix.org). Снова добавлена поддержка Android Auto.
|
||||||
|
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/sq/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/sq/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Ndryshimet kryesore në këtë version: Shtim mbulimi për Prani, për dhomë Mesazh i Drejtpërdrejtë (shënim: në matrix.org prania është e çaktivizuar. Shtim sërish i mbulimit për Android Auto.
|
||||||
|
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/sv-SE/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/sv-SE/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Huvudsakliga ändringar i den här versionen: Lägg till närvarostöd för direktmeddelanden (obs: närvaro är inaktiverat på matrix.org). Lägg till stöd för Android Auto igen.
|
||||||
|
Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/uk/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/uk/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Основні зміни в цій версії: Додано підтримку присутності для кімнати особистих повідомлень (примітка: присутність вимкнено на matrix.org. Знову додано підтримку Android Auto.
|
||||||
|
Повний журнал змін: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/vi/changelogs/40100120.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100120.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: xem trước URL, bàn phím Emoji mới, các khả năng cài đặt phòng mới và tuyết cho Giáng Sinh!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.12
|
2
fastlane/metadata/android/vi/changelogs/40100130.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100130.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: xem trước URL, bàn phím Emoji mới, các khả năng cài đặt phòng mới và tuyết cho Giáng Sinh!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.13
|
2
fastlane/metadata/android/vi/changelogs/40100140.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100140.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: chỉnh sửa quyền phòng, chủ đề Sáng/Tối tự động, và một loạt các bản sửa lỗi.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.14
|
2
fastlane/metadata/android/vi/changelogs/40100150.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100150.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: hỗ trợ đăng nhập từ mạng xã hội.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.15
|
2
fastlane/metadata/android/vi/changelogs/40100160.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100160.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: hỗ trợ đăng nhập từ mạng xã hội.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.15 và https://github.com/vector-im/element-android/releases/tag/v1.0.16
|
2
fastlane/metadata/android/vi/changelogs/40100170.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40100170.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.0.17
|
2
fastlane/metadata/android/vi/changelogs/40101000.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101000.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cải tiến VoIP (các cuộc gọi thoại và video trong Tin nhắn Trực tiếp) và sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.0
|
2
fastlane/metadata/android/vi/changelogs/40101010.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101010.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cải thiện hiệu suất và sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.1
|
2
fastlane/metadata/android/vi/changelogs/40101020.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101020.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cải thiện hiệu suất và sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.2
|
2
fastlane/metadata/android/vi/changelogs/40101030.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101030.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cải thiện hiệu suất và sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.3
|
2
fastlane/metadata/android/vi/changelogs/40101040.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cải thiện hiệu suất và sửa lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.4
|
2
fastlane/metadata/android/vi/changelogs/40101050.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101050.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: sửa lỗi nhanh cho 1.1.4
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.5
|
2
fastlane/metadata/android/vi/changelogs/40101060.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101060.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: sửa lỗi nhanh cho 1.1.5
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.6
|
2
fastlane/metadata/android/vi/changelogs/40101070.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101070.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: hỗ trợ beta cho Space. Nén video trước khi gửi.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.7
|
2
fastlane/metadata/android/vi/changelogs/40101080.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101080.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Cải tiến cho Space.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.8
|
2
fastlane/metadata/android/vi/changelogs/40101090.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101090.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: thêm hỗ trợ cho mạng gitter.im.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.9
|
2
fastlane/metadata/android/vi/changelogs/40101100.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101100.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cập nhật chủ đề và phong cách và các tính năng mới cho Space.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.10
|
2
fastlane/metadata/android/vi/changelogs/40101110.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101110.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cập nhật chủ đề và phong cách và các tính năng mới cho Space (sửa lỗi cho 1.1.1.0)
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.11
|
2
fastlane/metadata/android/vi/changelogs/40101120.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101120.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: cập nhật chủ đề và phong cách và sửa lỗi sau khi gọi video
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.12
|
2
fastlane/metadata/android/vi/changelogs/40101130.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101130.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: chủ yếu là sự ổn định và cập nhật sửa lỗi.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.13
|
2
fastlane/metadata/android/vi/changelogs/40101140.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101140.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: sửa lỗi các tin nhắn mã hóa.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.14
|
2
fastlane/metadata/android/vi/changelogs/40101150.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101150.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: triển khai tin nhắn thoại trong cài đặt thí nghiệm.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.15
|
2
fastlane/metadata/android/vi/changelogs/40101160.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40101160.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Sửa lỗi gửi tin nhắn mã hóa khi có ai đó trong phòng đăng xuất.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.1.16
|
2
fastlane/metadata/android/vi/changelogs/40102000.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40102000.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Tin nhắn Thoại được bật mặc định.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.2.0
|
2
fastlane/metadata/android/vi/changelogs/40102010.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40102010.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Nhiều cải tiến trong VoIP và Space (vẫn đang trong beta).
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.2.1
|
2
fastlane/metadata/android/vi/changelogs/40103000.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40103000.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Sắp xếp các phòng của bạn bằng Space!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.0
|
2
fastlane/metadata/android/vi/changelogs/40103010.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40103010.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Sắp xếp các phòng của bạn bằng Space! V1.3.1 khắc phục sự cố có thể xảy ra ở v1.3.0
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.1
|
2
fastlane/metadata/android/vi/changelogs/40103020.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40103020.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Thêm hỗ trợ Android Auto. Sửa rất nhiều lỗi!
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.2
|
2
fastlane/metadata/android/vi/changelogs/40103030.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40103030.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Hiển thị (các) chính sách máy chủ xác thực trong phần cài đặt. Tạm thời bỏ hỗ trợ Android Auto.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.3
|
2
fastlane/metadata/android/vi/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/vi/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Những thay đổi chính trong phiên bản này: Thêm hỗ trợ hiển thị, cho phòng Tin nhắn Trực tiếp (lưu ý: hiển thị bị vô hiệu hóa trên matrix.org. Thêm hỗ trợ Android Auto trở lại.
|
||||||
|
Log thay đổi đầy đủ: https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
42
fastlane/metadata/android/vi/full_description.txt
Normal file
42
fastlane/metadata/android/vi/full_description.txt
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
Element vừa là một ứng dụng nhắn tin an toàn vừa là một ứng dụng cộng tác nhóm năng suất, lý tưởng cho các cuộc trò chuyện nhóm trong khi làm việc từ xa. Ứng dụng trò chuyện này sử dụng mã hóa đầu cuối để cung cấp tính năng hội nghị truyền hình, chia sẻ tệp và cuộc gọi thoại mạnh mẽ.
|
||||||
|
|
||||||
|
<b> Các tính năng của Element bao gồm: </b>
|
||||||
|
- Các công cụ giao tiếp trực tuyến tiên tiến
|
||||||
|
- Các tin nhắn được mã hóa hoàn toàn để cho phép liên lạc doanh nghiệp an toàn hơn, ngay cả đối với những người làm việc từ xa
|
||||||
|
- Trò chuyện phi tập trung dựa trên khung mã nguồn mở Matrix
|
||||||
|
- Chia sẻ tệp một cách an toàn với dữ liệu được mã hóa trong khi quản lý dự án
|
||||||
|
- Trò chuyện video với VoIP và chia sẻ màn hình
|
||||||
|
- Tích hợp dễ dàng với các công cụ cộng tác trực tuyến yêu thích của bạn, công cụ quản lý dự án, dịch vụ VoIP và các ứng dụng nhắn tin nhóm khác
|
||||||
|
|
||||||
|
Element hoàn toàn khác với các ứng dụng nhắn tin và cộng tác khác. Nó hoạt động trên Matrix, một mạng mở để nhắn tin bảo mật và giao tiếp phi tập trung. Nó cho phép tự lưu trữ để cung cấp cho người dùng quyền sở hữu và kiểm soát tối đa dữ liệu và tin nhắn của họ.
|
||||||
|
|
||||||
|
<b> Nhắn tin mã hóa và riêng tư </b>
|
||||||
|
Element bảo vệ bạn khỏi các quảng cáo không mong muốn, khai thác dữ liệu và khu vườn có tường bao quanh. Nó cũng bảo mật tất cả dữ liệu của bạn, video 1-1 và giao tiếp thoại thông qua mã hóa đầu cuối và xác minh thiết bị có chữ ký chéo.
|
||||||
|
|
||||||
|
Element cung cấp cho bạn quyền kiểm soát quyền riêng tư của mình đồng thời cho phép bạn giao tiếp an toàn với bất kỳ ai trên mạng Ma trận hoặc các công cụ cộng tác kinh doanh khác bằng cách tích hợp với các ứng dụng như Slack.
|
||||||
|
|
||||||
|
<b> Phần tử có thể được tự lưu trữ </b>
|
||||||
|
Để cho phép kiểm soát nhiều hơn dữ liệu nhạy cảm và các cuộc trò chuyện của bạn, Element có thể được tự host hoặc bạn có thể chọn bất kỳ host Matrix nào - tiêu chuẩn cho giao tiếp phân tán, mã nguồn mở. Element cung cấp cho bạn quyền riêng tư, tuân thủ bảo mật và tính linh hoạt trong tích hợp.
|
||||||
|
|
||||||
|
<b> Sở hữu dữ liệu của bạn </b>
|
||||||
|
Bạn quyết định nơi lưu giữ dữ liệu và tin nhắn của mình. Không có rủi ro khai thác dữ liệu hoặc truy cập từ bên thứ ba.
|
||||||
|
|
||||||
|
Element giúp bạn kiểm soát theo những cách khác nhau:
|
||||||
|
1. Nhận một tài khoản miễn phí trên máy chủ công cộng matrix.org do các nhà phát triển Matrix host hoặc chọn từ hàng nghìn máy chủ công cộng do các tình nguyện viên lưu trữ
|
||||||
|
2. Tự host tài khoản của bạn bằng cách chạy một máy chủ trên cơ sở hạ tầng CNTT của riêng bạn
|
||||||
|
3. Đăng ký tài khoản trên máy chủ tùy chỉnh bằng cách chỉ cần đăng ký nền tảng Element Matrix Services hosting
|
||||||
|
|
||||||
|
<b> Mở tin nhắn và cộng tác </b>
|
||||||
|
Bạn có thể trò chuyện với bất kỳ ai trên mạng Matrix, cho dù họ đang sử dụng Element, một ứng dụng Matrix khác hay ngay cả khi họ đang sử dụng một ứng dụng nhắn tin khác.
|
||||||
|
|
||||||
|
<b> Siêu bảo mật </b>
|
||||||
|
Mã hóa đầu-cuối thực (chỉ những người trong cuộc trò chuyện mới có thể giải mã tin nhắn) và xác minh thiết bị xác thực chéo.
|
||||||
|
|
||||||
|
<b> Giao tiếp và tích hợp hoàn chỉnh </b>
|
||||||
|
Nhắn tin, cuộc gọi thoại và video, chia sẻ tệp, chia sẻ màn hình và một loạt các tích hợp, bot và widget. Xây dựng phòng, cộng đồng, giữ liên lạc và hoàn thành công việc.
|
||||||
|
|
||||||
|
<b> Tiếp tục nơi bạn đã dừng lại </b>
|
||||||
|
Giữ liên lạc mọi lúc mọi nơi với lịch sử tin nhắn được đồng bộ hóa hoàn toàn trên tất cả các thiết bị của bạn và trên web tại https://app.element.io
|
||||||
|
|
||||||
|
<b> Mã nguồn mở </b>
|
||||||
|
Element Android là một dự án mã nguồn mở, được host bởi GitHub. Vui lòng báo cáo lỗi và / hoặc đóng góp vào sự phát triển của nó tại https://github.com/vector-im/element-android
|
2
fastlane/metadata/android/zh-CN/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/zh-CN/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
此版本主要变化:为 Direct Message 聊天室添加 Presence 支持 (注意:Presence 在matrix.org 上是禁用的。再次添加 Android Auto 支持。
|
||||||
|
完整更新日志:https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
2
fastlane/metadata/android/zh-TW/changelogs/40103040.txt
Normal file
2
fastlane/metadata/android/zh-TW/changelogs/40103040.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
此版本中的主要變動:為直接訊息聊天室新增 Presence 支援(請注意:此功能在 matrix.org 上停用)。加回 Android Auto 支援。
|
||||||
|
完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.3.4
|
|
@ -31,7 +31,7 @@ android {
|
||||||
// that the app's state is completely cleared between tests.
|
// that the app's state is completely cleared between tests.
|
||||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||||
|
|
||||||
buildConfigField "String", "SDK_VERSION", "\"1.3.6\""
|
buildConfigField "String", "SDK_VERSION", "\"1.3.7\""
|
||||||
|
|
||||||
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
|
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
|
||||||
resValue "string", "git_sdk_revision", "\"${gitRevision()}\""
|
resValue "string", "git_sdk_revision", "\"${gitRevision()}\""
|
||||||
|
@ -156,7 +156,7 @@ dependencies {
|
||||||
implementation libs.apache.commonsImaging
|
implementation libs.apache.commonsImaging
|
||||||
|
|
||||||
// Phone number https://github.com/google/libphonenumber
|
// Phone number https://github.com/google/libphonenumber
|
||||||
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.35'
|
implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.36'
|
||||||
|
|
||||||
testImplementation libs.tests.junit
|
testImplementation libs.tests.junit
|
||||||
testImplementation 'org.robolectric:robolectric:4.6.1'
|
testImplementation 'org.robolectric:robolectric:4.6.1'
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.api
|
package org.matrix.android.sdk.api
|
||||||
|
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
|
||||||
import java.net.Proxy
|
import java.net.Proxy
|
||||||
|
|
||||||
|
@ -44,6 +45,10 @@ data class MatrixConfiguration(
|
||||||
* You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port).
|
* You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port).
|
||||||
*/
|
*/
|
||||||
val proxy: Proxy? = null,
|
val proxy: Proxy? = null,
|
||||||
|
/**
|
||||||
|
* TLS versions and cipher suites limitation for unauthenticated requests
|
||||||
|
*/
|
||||||
|
val connectionSpec: ConnectionSpec = ConnectionSpec.RESTRICTED_TLS,
|
||||||
/**
|
/**
|
||||||
* True to advertise support for call transfers to other parties on Matrix calls.
|
* True to advertise support for call transfers to other parties on Matrix calls.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -105,9 +105,15 @@ interface AuthenticationService {
|
||||||
/**
|
/**
|
||||||
* Authenticate with a matrixId and a password
|
* Authenticate with a matrixId and a password
|
||||||
* Usually call this after a successful call to getWellKnownData()
|
* Usually call this after a successful call to getWellKnownData()
|
||||||
|
* @param homeServerConnectionConfig the information about the homeserver and other configuration
|
||||||
|
* @param matrixId the matrixId of the user
|
||||||
|
* @param password the password of the account
|
||||||
|
* @param initialDeviceName the initial device name
|
||||||
|
* @param deviceId the device id, optional. If not provided or null, the server will generate one.
|
||||||
*/
|
*/
|
||||||
suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
matrixId: String,
|
matrixId: String,
|
||||||
password: String,
|
password: String,
|
||||||
initialDeviceName: String): Session
|
initialDeviceName: String,
|
||||||
|
deviceId: String? = null): Session
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.auth.data
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import okhttp3.CipherSuite
|
import okhttp3.CipherSuite
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
import okhttp3.TlsVersion
|
import okhttp3.TlsVersion
|
||||||
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder
|
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder
|
||||||
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
|
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
|
||||||
|
@ -191,32 +192,25 @@ data class HomeServerConnectionConfig(
|
||||||
/**
|
/**
|
||||||
* Convenient method to limit the TLS versions and cipher suites for this Builder
|
* Convenient method to limit the TLS versions and cipher suites for this Builder
|
||||||
* Ref:
|
* Ref:
|
||||||
* - https://www.ssi.gouv.fr/uploads/2017/02/security-recommendations-for-tls_v1.1.pdf
|
* - https://www.ssi.gouv.fr/uploads/2017/07/anssi-guide-recommandations_de_securite_relatives_a_tls-v1.2.pdf
|
||||||
* - https://developer.android.com/reference/javax/net/ssl/SSLEngine
|
* - https://developer.android.com/reference/javax/net/ssl/SSLEngine
|
||||||
*
|
*
|
||||||
* @param tlsLimitations true to use Tls limitations
|
* @param tlsLimitations true to use Tls limitations
|
||||||
* @param enableCompatibilityMode set to true for Android < 20
|
* @param enableCompatibilityMode set to true for Android < 20
|
||||||
* @return this builder
|
* @return this builder
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("TLS versions and cipher suites are limited by default")
|
||||||
fun withTlsLimitations(tlsLimitations: Boolean, enableCompatibilityMode: Boolean): Builder {
|
fun withTlsLimitations(tlsLimitations: Boolean, enableCompatibilityMode: Boolean): Builder {
|
||||||
if (tlsLimitations) {
|
if (tlsLimitations) {
|
||||||
withShouldAcceptTlsExtensions(false)
|
withShouldAcceptTlsExtensions(false)
|
||||||
|
|
||||||
// Tls versions
|
// TlS versions
|
||||||
addAcceptedTlsVersion(TlsVersion.TLS_1_2)
|
ConnectionSpec.RESTRICTED_TLS.tlsVersions?.let { this.tlsVersions.addAll(it) }
|
||||||
addAcceptedTlsVersion(TlsVersion.TLS_1_3)
|
|
||||||
|
|
||||||
forceUsageOfTlsVersions(enableCompatibilityMode)
|
forceUsageOfTlsVersions(enableCompatibilityMode)
|
||||||
|
|
||||||
// Cipher suites
|
// Cipher suites
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
|
ConnectionSpec.RESTRICTED_TLS.cipherSuites?.let { this.tlsCipherSuites.addAll(it) }
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256)
|
|
||||||
addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256)
|
|
||||||
|
|
||||||
if (enableCompatibilityMode) {
|
if (enableCompatibilityMode) {
|
||||||
// Adopt some preceding cipher suites for Android < 20 to be able to negotiate
|
// Adopt some preceding cipher suites for Android < 20 to be able to negotiate
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.api.auth.login
|
package org.matrix.android.sdk.api.auth.login
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of methods to be able to login to an existing account on a homeserver.
|
* Set of methods to be able to login to an existing account on a homeserver.
|
||||||
|
@ -34,12 +35,14 @@ interface LoginWizard {
|
||||||
*
|
*
|
||||||
* @param login the login field. Can be a user name, or a msisdn (email or phone number) associated to the account
|
* @param login the login field. Can be a user name, or a msisdn (email or phone number) associated to the account
|
||||||
* @param password the password of the account
|
* @param password the password of the account
|
||||||
* @param deviceName the initial device name
|
* @param initialDeviceName the initial device name
|
||||||
|
* @param deviceId the device id, optional. If not provided or null, the server will generate one.
|
||||||
* @return a [Session] if the login is successful
|
* @return a [Session] if the login is successful
|
||||||
*/
|
*/
|
||||||
suspend fun login(login: String,
|
suspend fun login(login: String,
|
||||||
password: String,
|
password: String,
|
||||||
deviceName: String): Session
|
initialDeviceName: String,
|
||||||
|
deviceId: String? = null): Session
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange a login token to an access token.
|
* Exchange a login token to an access token.
|
||||||
|
@ -49,6 +52,12 @@ interface LoginWizard {
|
||||||
*/
|
*/
|
||||||
suspend fun loginWithToken(loginToken: String): Session
|
suspend fun loginWithToken(loginToken: String): Session
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login to the homeserver by sending a custom JsonDict.
|
||||||
|
* The data should contain at least one entry "type" with a String value.
|
||||||
|
*/
|
||||||
|
suspend fun loginCustom(data: JsonDict): Session
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the homeserver to reset the user password. The password will not be reset until
|
* Ask the homeserver to reset the user password. The password will not be reset until
|
||||||
* [resetPasswordMailConfirmed] is successfully called.
|
* [resetPasswordMailConfirmed] is successfully called.
|
||||||
|
|
|
@ -19,17 +19,41 @@ package org.matrix.android.sdk.api.query
|
||||||
/**
|
/**
|
||||||
* Basic query language. All these cases are mutually exclusive.
|
* Basic query language. All these cases are mutually exclusive.
|
||||||
*/
|
*/
|
||||||
sealed class QueryStringValue {
|
sealed interface QueryStringValue {
|
||||||
object NoCondition : QueryStringValue()
|
sealed interface ContentQueryStringValue : QueryStringValue {
|
||||||
object IsNull : QueryStringValue()
|
val string: String
|
||||||
object IsNotNull : QueryStringValue()
|
val case: Case
|
||||||
object IsEmpty : QueryStringValue()
|
}
|
||||||
object IsNotEmpty : QueryStringValue()
|
|
||||||
data class Equals(val string: String, val case: Case = Case.SENSITIVE) : QueryStringValue()
|
object NoCondition : QueryStringValue
|
||||||
data class Contains(val string: String, val case: Case = Case.SENSITIVE) : QueryStringValue()
|
object IsNull : QueryStringValue
|
||||||
|
object IsNotNull : QueryStringValue
|
||||||
|
object IsEmpty : QueryStringValue
|
||||||
|
object IsNotEmpty : QueryStringValue
|
||||||
|
|
||||||
|
data class Equals(override val string: String, override val case: Case = Case.SENSITIVE) : ContentQueryStringValue
|
||||||
|
data class Contains(override val string: String, override val case: Case = Case.SENSITIVE) : ContentQueryStringValue
|
||||||
|
|
||||||
enum class Case {
|
enum class Case {
|
||||||
|
/**
|
||||||
|
* Match query sensitive to case
|
||||||
|
*/
|
||||||
SENSITIVE,
|
SENSITIVE,
|
||||||
INSENSITIVE
|
|
||||||
|
/**
|
||||||
|
* Match query insensitive to case, this only works for Latin-1 character sets
|
||||||
|
*/
|
||||||
|
INSENSITIVE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match query with input normalized (case insensitive)
|
||||||
|
* Works around Realms inability to sort or filter by case for non Latin-1 character sets
|
||||||
|
* Expects the target field to contain normalized data
|
||||||
|
*
|
||||||
|
* @see org.matrix.android.sdk.internal.util.Normalizer.normalize
|
||||||
|
*/
|
||||||
|
NORMALIZED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun QueryStringValue.isNormalized() = this is QueryStringValue.ContentQueryStringValue && case == QueryStringValue.Case.NORMALIZED
|
||||||
|
|
|
@ -120,9 +120,11 @@ interface Session :
|
||||||
fun requireBackgroundSync()
|
fun requireBackgroundSync()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launches infinite periodic background syncs
|
* Launches infinite self rescheduling background syncs via the WorkManager
|
||||||
* This does not work in doze mode :/
|
*
|
||||||
* If battery optimization is on it can work in app standby but that's all :/
|
* While dozing, syncs will only occur during maintenance windows
|
||||||
|
* For reliability it's recommended to also start a long running foreground service
|
||||||
|
* along with disabling battery optimizations
|
||||||
*/
|
*/
|
||||||
fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long)
|
fun startAutomaticBackgroundSync(timeOutInSeconds: Long, repeatDelayInSeconds: Long)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ import org.json.JSONObject
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
import org.matrix.android.sdk.api.session.room.model.message.MessageType
|
||||||
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
|
||||||
|
@ -310,3 +312,6 @@ fun Event.isEdition(): Boolean {
|
||||||
fun Event.getPresenceContent(): PresenceContent? {
|
fun Event.getPresenceContent(): PresenceContent? {
|
||||||
return content.toModel<PresenceContent>()
|
return content.toModel<PresenceContent>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Event.isInvitation(): Boolean = type == EventType.STATE_ROOM_MEMBER &&
|
||||||
|
content?.toModel<RoomMemberContent>()?.membership == Membership.INVITE
|
||||||
|
|
|
@ -94,13 +94,15 @@ interface RoomService {
|
||||||
* Get a snapshot list of room summaries.
|
* Get a snapshot list of room summaries.
|
||||||
* @return the immutable list of [RoomSummary]
|
* @return the immutable list of [RoomSummary]
|
||||||
*/
|
*/
|
||||||
fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary>
|
fun getRoomSummaries(queryParams: RoomSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): List<RoomSummary>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a live list of room summaries. This list is refreshed as soon as the data changes.
|
* Get a live list of room summaries. This list is refreshed as soon as the data changes.
|
||||||
* @return the [LiveData] of List[RoomSummary]
|
* @return the [LiveData] of List[RoomSummary]
|
||||||
*/
|
*/
|
||||||
fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>>
|
fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): LiveData<List<RoomSummary>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a snapshot list of Breadcrumbs
|
* Get a snapshot list of Breadcrumbs
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.space
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult
|
import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult
|
||||||
|
@ -74,9 +75,11 @@ interface SpaceService {
|
||||||
* Get a live list of space summaries. This list is refreshed as soon as the data changes.
|
* Get a live list of space summaries. This list is refreshed as soon as the data changes.
|
||||||
* @return the [LiveData] of List[SpaceSummary]
|
* @return the [LiveData] of List[SpaceSummary]
|
||||||
*/
|
*/
|
||||||
fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData<List<RoomSummary>>
|
fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData<List<RoomSummary>>
|
||||||
|
|
||||||
fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List<RoomSummary>
|
fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): List<RoomSummary>
|
||||||
|
|
||||||
suspend fun joinSpace(spaceIdOrAlias: String,
|
suspend fun joinSpace(spaceIdOrAlias: String,
|
||||||
reason: String? = null,
|
reason: String? = null,
|
||||||
|
|
|
@ -121,6 +121,10 @@ internal interface AuthAPI {
|
||||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
|
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
|
||||||
suspend fun login(@Body loginParams: TokenLoginParams): Credentials
|
suspend fun login(@Body loginParams: TokenLoginParams): Credentials
|
||||||
|
|
||||||
|
@Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000")
|
||||||
|
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
|
||||||
|
suspend fun login(@Body loginParams: JsonDict): Credentials
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the homeserver to reset the password associated with the provided email.
|
* Ask the homeserver to reset the password associated with the provided email.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -388,8 +388,15 @@ internal class DefaultAuthenticationService @Inject constructor(
|
||||||
override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
override suspend fun directAuthentication(homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
matrixId: String,
|
matrixId: String,
|
||||||
password: String,
|
password: String,
|
||||||
initialDeviceName: String): Session {
|
initialDeviceName: String,
|
||||||
return directLoginTask.execute(DirectLoginTask.Params(homeServerConnectionConfig, matrixId, password, initialDeviceName))
|
deviceId: String?): Session {
|
||||||
|
return directLoginTask.execute(DirectLoginTask.Params(
|
||||||
|
homeServerConnectionConfig = homeServerConnectionConfig,
|
||||||
|
userId = matrixId,
|
||||||
|
password = password,
|
||||||
|
deviceName = initialDeviceName,
|
||||||
|
deviceId = deviceId
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI {
|
||||||
|
|
|
@ -49,51 +49,54 @@ internal data class PasswordLoginParams(
|
||||||
|
|
||||||
fun userIdentifier(user: String,
|
fun userIdentifier(user: String,
|
||||||
password: String,
|
password: String,
|
||||||
deviceDisplayName: String? = null,
|
deviceDisplayName: String?,
|
||||||
deviceId: String? = null): PasswordLoginParams {
|
deviceId: String?): PasswordLoginParams {
|
||||||
return PasswordLoginParams(
|
return PasswordLoginParams(
|
||||||
mapOf(
|
identifier = mapOf(
|
||||||
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_USER,
|
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_USER,
|
||||||
IDENTIFIER_KEY_USER to user
|
IDENTIFIER_KEY_USER to user
|
||||||
),
|
),
|
||||||
password,
|
password = password,
|
||||||
LoginFlowTypes.PASSWORD,
|
type = LoginFlowTypes.PASSWORD,
|
||||||
deviceDisplayName,
|
deviceDisplayName = deviceDisplayName,
|
||||||
deviceId)
|
deviceId = deviceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun thirdPartyIdentifier(medium: String,
|
fun thirdPartyIdentifier(medium: String,
|
||||||
address: String,
|
address: String,
|
||||||
password: String,
|
password: String,
|
||||||
deviceDisplayName: String? = null,
|
deviceDisplayName: String?,
|
||||||
deviceId: String? = null): PasswordLoginParams {
|
deviceId: String?): PasswordLoginParams {
|
||||||
return PasswordLoginParams(
|
return PasswordLoginParams(
|
||||||
mapOf(
|
identifier = mapOf(
|
||||||
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_THIRD_PARTY,
|
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_THIRD_PARTY,
|
||||||
IDENTIFIER_KEY_MEDIUM to medium,
|
IDENTIFIER_KEY_MEDIUM to medium,
|
||||||
IDENTIFIER_KEY_ADDRESS to address
|
IDENTIFIER_KEY_ADDRESS to address
|
||||||
),
|
),
|
||||||
password,
|
password = password,
|
||||||
LoginFlowTypes.PASSWORD,
|
type = LoginFlowTypes.PASSWORD,
|
||||||
deviceDisplayName,
|
deviceDisplayName = deviceDisplayName,
|
||||||
deviceId)
|
deviceId = deviceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun phoneIdentifier(country: String,
|
fun phoneIdentifier(country: String,
|
||||||
phone: String,
|
phone: String,
|
||||||
password: String,
|
password: String,
|
||||||
deviceDisplayName: String? = null,
|
deviceDisplayName: String?,
|
||||||
deviceId: String? = null): PasswordLoginParams {
|
deviceId: String?): PasswordLoginParams {
|
||||||
return PasswordLoginParams(
|
return PasswordLoginParams(
|
||||||
mapOf(
|
identifier = mapOf(
|
||||||
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_PHONE,
|
IDENTIFIER_KEY_TYPE to IDENTIFIER_KEY_TYPE_PHONE,
|
||||||
IDENTIFIER_KEY_COUNTRY to country,
|
IDENTIFIER_KEY_COUNTRY to country,
|
||||||
IDENTIFIER_KEY_PHONE to phone
|
IDENTIFIER_KEY_PHONE to phone
|
||||||
),
|
),
|
||||||
password,
|
password = password,
|
||||||
LoginFlowTypes.PASSWORD,
|
type = LoginFlowTypes.PASSWORD,
|
||||||
deviceDisplayName,
|
deviceDisplayName = deviceDisplayName,
|
||||||
deviceId)
|
deviceId = deviceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.matrix.android.sdk.api.auth.login.LoginProfileInfo
|
||||||
import org.matrix.android.sdk.api.auth.login.LoginWizard
|
import org.matrix.android.sdk.api.auth.login.LoginWizard
|
||||||
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
|
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
import org.matrix.android.sdk.api.util.JsonDict
|
||||||
import org.matrix.android.sdk.internal.auth.AuthAPI
|
import org.matrix.android.sdk.internal.auth.AuthAPI
|
||||||
import org.matrix.android.sdk.internal.auth.PendingSessionStore
|
import org.matrix.android.sdk.internal.auth.PendingSessionStore
|
||||||
import org.matrix.android.sdk.internal.auth.SessionCreator
|
import org.matrix.android.sdk.internal.auth.SessionCreator
|
||||||
|
@ -52,11 +53,23 @@ internal class DefaultLoginWizard(
|
||||||
|
|
||||||
override suspend fun login(login: String,
|
override suspend fun login(login: String,
|
||||||
password: String,
|
password: String,
|
||||||
deviceName: String): Session {
|
initialDeviceName: String,
|
||||||
|
deviceId: String?): Session {
|
||||||
val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
|
val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
|
||||||
PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, deviceName)
|
PasswordLoginParams.thirdPartyIdentifier(
|
||||||
|
medium = ThreePidMedium.EMAIL,
|
||||||
|
address = login,
|
||||||
|
password = password,
|
||||||
|
deviceDisplayName = initialDeviceName,
|
||||||
|
deviceId = deviceId
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
PasswordLoginParams.userIdentifier(login, password, deviceName)
|
PasswordLoginParams.userIdentifier(
|
||||||
|
user = login,
|
||||||
|
password = password,
|
||||||
|
deviceDisplayName = initialDeviceName,
|
||||||
|
deviceId = deviceId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val credentials = executeRequest(null) {
|
val credentials = executeRequest(null) {
|
||||||
authAPI.login(loginParams)
|
authAPI.login(loginParams)
|
||||||
|
@ -79,6 +92,14 @@ internal class DefaultLoginWizard(
|
||||||
return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
|
return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun loginCustom(data: JsonDict): Session {
|
||||||
|
val credentials = executeRequest(null) {
|
||||||
|
authAPI.login(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionCreator.createSession(credentials, pendingSessionData.homeServerConnectionConfig)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun resetPassword(email: String, newPassword: String) {
|
override suspend fun resetPassword(email: String, newPassword: String) {
|
||||||
val param = RegisterAddThreePidTask.Params(
|
val param = RegisterAddThreePidTask.Params(
|
||||||
RegisterThreePid.Email(email),
|
RegisterThreePid.Email(email),
|
||||||
|
|
|
@ -37,7 +37,8 @@ internal interface DirectLoginTask : Task<DirectLoginTask.Params, Session> {
|
||||||
val homeServerConnectionConfig: HomeServerConnectionConfig,
|
val homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||||
val userId: String,
|
val userId: String,
|
||||||
val password: String,
|
val password: String,
|
||||||
val deviceName: String
|
val deviceName: String,
|
||||||
|
val deviceId: String?
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +56,12 @@ internal class DefaultDirectLoginTask @Inject constructor(
|
||||||
val authAPI = retrofitFactory.create(client, homeServerUrl)
|
val authAPI = retrofitFactory.create(client, homeServerUrl)
|
||||||
.create(AuthAPI::class.java)
|
.create(AuthAPI::class.java)
|
||||||
|
|
||||||
val loginParams = PasswordLoginParams.userIdentifier(params.userId, params.password, params.deviceName)
|
val loginParams = PasswordLoginParams.userIdentifier(
|
||||||
|
user = params.userId,
|
||||||
|
password = params.password,
|
||||||
|
deviceDisplayName = params.deviceName,
|
||||||
|
deviceId = params.deviceId
|
||||||
|
)
|
||||||
|
|
||||||
val credentials = try {
|
val credentials = try {
|
||||||
executeRequest(null) {
|
executeRequest(null) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ internal interface SendEventTask : Task<SendEventTask.Params, String> {
|
||||||
|
|
||||||
internal class DefaultSendEventTask @Inject constructor(
|
internal class DefaultSendEventTask @Inject constructor(
|
||||||
private val localEchoRepository: LocalEchoRepository,
|
private val localEchoRepository: LocalEchoRepository,
|
||||||
private val encryptEventTask: DefaultEncryptEventTask,
|
private val encryptEventTask: EncryptEventTask,
|
||||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||||
private val roomAPI: RoomAPI,
|
private val roomAPI: RoomAPI,
|
||||||
private val globalErrorReceiver: GlobalErrorReceiver) : SendEventTask {
|
private val globalErrorReceiver: GlobalErrorReceiver) : SendEventTask {
|
||||||
|
|
|
@ -34,7 +34,7 @@ internal interface SendVerificationMessageTask : Task<SendVerificationMessageTas
|
||||||
|
|
||||||
internal class DefaultSendVerificationMessageTask @Inject constructor(
|
internal class DefaultSendVerificationMessageTask @Inject constructor(
|
||||||
private val localEchoRepository: LocalEchoRepository,
|
private val localEchoRepository: LocalEchoRepository,
|
||||||
private val encryptEventTask: DefaultEncryptEventTask,
|
private val encryptEventTask: EncryptEventTask,
|
||||||
private val roomAPI: RoomAPI,
|
private val roomAPI: RoomAPI,
|
||||||
private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
|
private val cryptoSessionInfoProvider: CryptoSessionInfoProvider,
|
||||||
private val globalErrorReceiver: GlobalErrorReceiver) : SendVerificationMessageTask {
|
private val globalErrorReceiver: GlobalErrorReceiver) : SendVerificationMessageTask {
|
||||||
|
|
|
@ -45,11 +45,24 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntityFields
|
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.MoshiProvider
|
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
|
import org.matrix.android.sdk.internal.util.Normalizer
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal object RealmSessionStoreMigration : RealmMigration {
|
internal class RealmSessionStoreMigration @Inject constructor(
|
||||||
|
private val normalizer: Normalizer
|
||||||
|
) : RealmMigration {
|
||||||
|
|
||||||
const val SESSION_STORE_SCHEMA_VERSION = 18L
|
companion object {
|
||||||
|
const val SESSION_STORE_SCHEMA_VERSION = 19L
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces all RealmSessionStoreMigration instances to be equal
|
||||||
|
* Avoids Realm throwing when multiple instances of the migration are set
|
||||||
|
*/
|
||||||
|
override fun equals(other: Any?) = other is RealmSessionStoreMigration
|
||||||
|
override fun hashCode() = 1000
|
||||||
|
|
||||||
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
||||||
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
|
Timber.v("Migrating Realm Session from $oldVersion to $newVersion")
|
||||||
|
@ -72,6 +85,7 @@ internal object RealmSessionStoreMigration : RealmMigration {
|
||||||
if (oldVersion <= 15) migrateTo16(realm)
|
if (oldVersion <= 15) migrateTo16(realm)
|
||||||
if (oldVersion <= 16) migrateTo17(realm)
|
if (oldVersion <= 16) migrateTo17(realm)
|
||||||
if (oldVersion <= 17) migrateTo18(realm)
|
if (oldVersion <= 17) migrateTo18(realm)
|
||||||
|
if (oldVersion <= 18) migrateTo19(realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun migrateTo1(realm: DynamicRealm) {
|
private fun migrateTo1(realm: DynamicRealm) {
|
||||||
|
@ -364,4 +378,16 @@ internal object RealmSessionStoreMigration : RealmMigration {
|
||||||
realm.schema.get("RoomMemberSummaryEntity")
|
realm.schema.get("RoomMemberSummaryEntity")
|
||||||
?.addRealmObjectField(RoomMemberSummaryEntityFields.USER_PRESENCE_ENTITY.`$`, userPresenceEntity)
|
?.addRealmObjectField(RoomMemberSummaryEntityFields.USER_PRESENCE_ENTITY.`$`, userPresenceEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun migrateTo19(realm: DynamicRealm) {
|
||||||
|
Timber.d("Step 18 -> 19")
|
||||||
|
realm.schema.get("RoomSummaryEntity")
|
||||||
|
?.addField(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, String::class.java)
|
||||||
|
?.transform {
|
||||||
|
it.getString(RoomSummaryEntityFields.DISPLAY_NAME)?.let { displayName ->
|
||||||
|
val normalised = normalizer.normalize(displayName)
|
||||||
|
it.set(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, normalised)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ private const val REALM_NAME = "disk_store.realm"
|
||||||
*/
|
*/
|
||||||
internal class SessionRealmConfigurationFactory @Inject constructor(
|
internal class SessionRealmConfigurationFactory @Inject constructor(
|
||||||
private val realmKeysUtils: RealmKeysUtils,
|
private val realmKeysUtils: RealmKeysUtils,
|
||||||
|
private val realmSessionStoreMigration: RealmSessionStoreMigration,
|
||||||
@SessionFilesDirectory val directory: File,
|
@SessionFilesDirectory val directory: File,
|
||||||
@SessionId val sessionId: String,
|
@SessionId val sessionId: String,
|
||||||
@UserMd5 val userMd5: String,
|
@UserMd5 val userMd5: String,
|
||||||
|
@ -71,7 +72,7 @@ internal class SessionRealmConfigurationFactory @Inject constructor(
|
||||||
.allowWritesOnUiThread(true)
|
.allowWritesOnUiThread(true)
|
||||||
.modules(SessionRealmModule())
|
.modules(SessionRealmModule())
|
||||||
.schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION)
|
.schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION)
|
||||||
.migration(RealmSessionStoreMigration)
|
.migration(realmSessionStoreMigration)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// Try creating a realm instance and if it succeeds we can clear the flag
|
// Try creating a realm instance and if it succeeds we can clear the flag
|
||||||
|
|
|
@ -21,13 +21,13 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
|
import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo
|
||||||
import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo
|
import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo
|
||||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
||||||
|
import org.matrix.android.sdk.api.session.typing.TypingUsersTracker
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.presence.toUserPresence
|
import org.matrix.android.sdk.internal.database.model.presence.toUserPresence
|
||||||
import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class RoomSummaryMapper @Inject constructor(private val timelineEventMapper: TimelineEventMapper,
|
internal class RoomSummaryMapper @Inject constructor(private val timelineEventMapper: TimelineEventMapper,
|
||||||
private val typingUsersTracker: DefaultTypingUsersTracker) {
|
private val typingUsersTracker: TypingUsersTracker) {
|
||||||
|
|
||||||
fun map(roomSummaryEntity: RoomSummaryEntity): RoomSummary {
|
fun map(roomSummaryEntity: RoomSummaryEntity): RoomSummary {
|
||||||
val tags = roomSummaryEntity.tags().map {
|
val tags = roomSummaryEntity.tags().map {
|
||||||
|
@ -42,7 +42,7 @@ internal class RoomSummaryMapper @Inject constructor(private val timelineEventMa
|
||||||
|
|
||||||
return RoomSummary(
|
return RoomSummary(
|
||||||
roomId = roomSummaryEntity.roomId,
|
roomId = roomSummaryEntity.roomId,
|
||||||
displayName = roomSummaryEntity.displayName ?: "",
|
displayName = roomSummaryEntity.displayName() ?: "",
|
||||||
name = roomSummaryEntity.name ?: "",
|
name = roomSummaryEntity.name ?: "",
|
||||||
topic = roomSummaryEntity.topic ?: "",
|
topic = roomSummaryEntity.topic ?: "",
|
||||||
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
|
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.model.VersioningState
|
import org.matrix.android.sdk.api.session.room.model.VersioningState
|
||||||
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
import org.matrix.android.sdk.api.session.room.model.tag.RoomTag
|
||||||
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity
|
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity
|
||||||
|
import org.matrix.android.sdk.internal.session.room.membership.RoomName
|
||||||
|
|
||||||
internal open class RoomSummaryEntity(
|
internal open class RoomSummaryEntity(
|
||||||
@PrimaryKey var roomId: String = "",
|
@PrimaryKey var roomId: String = "",
|
||||||
|
@ -36,10 +37,24 @@ internal open class RoomSummaryEntity(
|
||||||
var children: RealmList<SpaceChildSummaryEntity> = RealmList()
|
var children: RealmList<SpaceChildSummaryEntity> = RealmList()
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
var displayName: String? = ""
|
private var displayName: String? = ""
|
||||||
set(value) {
|
|
||||||
if (value != field) field = value
|
fun displayName() = displayName
|
||||||
|
|
||||||
|
fun setDisplayName(roomName: RoomName) {
|
||||||
|
if (roomName.name != displayName) {
|
||||||
|
displayName = roomName.name
|
||||||
|
normalizedDisplayName = roomName.normalizedName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Workaround for Realm only supporting Latin-1 character sets when sorting
|
||||||
|
* or filtering by case
|
||||||
|
* See https://github.com/realm/realm-core/issues/777
|
||||||
|
*/
|
||||||
|
private var normalizedDisplayName: String? = ""
|
||||||
|
|
||||||
var avatarUrl: String? = ""
|
var avatarUrl: String? = ""
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value != field) field = value
|
if (value != field) field = value
|
||||||
|
@ -284,5 +299,6 @@ internal open class RoomSummaryEntity(
|
||||||
roomEncryptionTrustLevelStr = value?.name
|
roomEncryptionTrustLevelStr = value?.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object
|
companion object
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.facebook.stetho.okhttp3.StethoInterceptor
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import org.matrix.android.sdk.BuildConfig
|
import org.matrix.android.sdk.BuildConfig
|
||||||
|
@ -29,6 +30,7 @@ import org.matrix.android.sdk.internal.network.TimeOutInterceptor
|
||||||
import org.matrix.android.sdk.internal.network.UserAgentInterceptor
|
import org.matrix.android.sdk.internal.network.UserAgentInterceptor
|
||||||
import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor
|
import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor
|
||||||
import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger
|
import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger
|
||||||
|
import java.util.Collections
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
|
@ -66,6 +68,8 @@ internal object NetworkModule {
|
||||||
httpLoggingInterceptor: HttpLoggingInterceptor,
|
httpLoggingInterceptor: HttpLoggingInterceptor,
|
||||||
curlLoggingInterceptor: CurlLoggingInterceptor,
|
curlLoggingInterceptor: CurlLoggingInterceptor,
|
||||||
apiInterceptor: ApiInterceptor): OkHttpClient {
|
apiInterceptor: ApiInterceptor): OkHttpClient {
|
||||||
|
val spec = ConnectionSpec.Builder(matrixConfiguration.connectionSpec).build()
|
||||||
|
|
||||||
return OkHttpClient.Builder()
|
return OkHttpClient.Builder()
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
.readTimeout(60, TimeUnit.SECONDS)
|
.readTimeout(60, TimeUnit.SECONDS)
|
||||||
|
@ -87,6 +91,7 @@ internal object NetworkModule {
|
||||||
proxy(it)
|
proxy(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.connectionSpecs(Collections.singletonList(spec))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,15 +177,13 @@ internal object CertUtil {
|
||||||
|
|
||||||
val trustPinned = arrayOf<TrustManager>(PinnedTrustManagerProvider.provide(hsConfig.allowedFingerprints, defaultTrustManager))
|
val trustPinned = arrayOf<TrustManager>(PinnedTrustManagerProvider.provide(hsConfig.allowedFingerprints, defaultTrustManager))
|
||||||
|
|
||||||
val sslSocketFactory: SSLSocketFactory
|
val sslSocketFactory = if (hsConfig.forceUsageTlsVersions && !hsConfig.tlsVersions.isNullOrEmpty()) {
|
||||||
|
|
||||||
if (hsConfig.forceUsageTlsVersions && hsConfig.tlsVersions != null) {
|
|
||||||
// Force usage of accepted Tls Versions for Android < 20
|
// Force usage of accepted Tls Versions for Android < 20
|
||||||
sslSocketFactory = TLSSocketFactory(trustPinned, hsConfig.tlsVersions)
|
TLSSocketFactory(trustPinned, hsConfig.tlsVersions)
|
||||||
} else {
|
} else {
|
||||||
val sslContext = SSLContext.getInstance("TLS")
|
val sslContext = SSLContext.getInstance("TLS")
|
||||||
sslContext.init(null, trustPinned, java.security.SecureRandom())
|
sslContext.init(null, trustPinned, java.security.SecureRandom())
|
||||||
sslSocketFactory = sslContext.socketFactory
|
sslContext.socketFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
return PinnedSSLSocketFactory(sslSocketFactory, defaultTrustManager!!)
|
return PinnedSSLSocketFactory(sslSocketFactory, defaultTrustManager!!)
|
||||||
|
@ -237,14 +235,14 @@ internal object CertUtil {
|
||||||
* @return a list of accepted TLS specifications.
|
* @return a list of accepted TLS specifications.
|
||||||
*/
|
*/
|
||||||
fun newConnectionSpecs(hsConfig: HomeServerConnectionConfig): List<ConnectionSpec> {
|
fun newConnectionSpecs(hsConfig: HomeServerConnectionConfig): List<ConnectionSpec> {
|
||||||
val builder = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
val builder = ConnectionSpec.Builder(ConnectionSpec.RESTRICTED_TLS)
|
||||||
val tlsVersions = hsConfig.tlsVersions
|
val tlsVersions = hsConfig.tlsVersions
|
||||||
if (null != tlsVersions && tlsVersions.isNotEmpty()) {
|
if (!tlsVersions.isNullOrEmpty()) {
|
||||||
builder.tlsVersions(*tlsVersions.toTypedArray())
|
builder.tlsVersions(*tlsVersions.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
val tlsCipherSuites = hsConfig.tlsCipherSuites
|
val tlsCipherSuites = hsConfig.tlsCipherSuites
|
||||||
if (null != tlsCipherSuites && tlsCipherSuites.isNotEmpty()) {
|
if (!tlsCipherSuites.isNullOrEmpty()) {
|
||||||
builder.cipherSuites(*tlsCipherSuites.toTypedArray())
|
builder.cipherSuites(*tlsCipherSuites.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,24 +20,41 @@ import io.realm.Case
|
||||||
import io.realm.RealmObject
|
import io.realm.RealmObject
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import timber.log.Timber
|
import org.matrix.android.sdk.api.query.QueryStringValue.ContentQueryStringValue
|
||||||
|
import org.matrix.android.sdk.internal.util.Normalizer
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
fun <T : RealmObject> RealmQuery<T>.process(field: String, queryStringValue: QueryStringValue): RealmQuery<T> {
|
class QueryStringValueProcessor @Inject constructor(
|
||||||
when (queryStringValue) {
|
private val normalizer: Normalizer
|
||||||
is QueryStringValue.NoCondition -> Timber.v("No condition to process")
|
) {
|
||||||
is QueryStringValue.IsNotNull -> isNotNull(field)
|
|
||||||
is QueryStringValue.IsNull -> isNull(field)
|
fun <T : RealmObject> RealmQuery<T>.process(field: String, queryStringValue: QueryStringValue): RealmQuery<T> {
|
||||||
is QueryStringValue.IsEmpty -> isEmpty(field)
|
return when (queryStringValue) {
|
||||||
is QueryStringValue.IsNotEmpty -> isNotEmpty(field)
|
is QueryStringValue.NoCondition -> this
|
||||||
is QueryStringValue.Equals -> equalTo(field, queryStringValue.string, queryStringValue.case.toRealmCase())
|
is QueryStringValue.IsNotNull -> isNotNull(field)
|
||||||
is QueryStringValue.Contains -> contains(field, queryStringValue.string, queryStringValue.case.toRealmCase())
|
is QueryStringValue.IsNull -> isNull(field)
|
||||||
|
is QueryStringValue.IsEmpty -> isEmpty(field)
|
||||||
|
is QueryStringValue.IsNotEmpty -> isNotEmpty(field)
|
||||||
|
is ContentQueryStringValue -> when (queryStringValue) {
|
||||||
|
is QueryStringValue.Equals -> equalTo(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
|
||||||
|
is QueryStringValue.Contains -> contains(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ContentQueryStringValue.toRealmValue(): String {
|
||||||
|
return when (case) {
|
||||||
|
QueryStringValue.Case.NORMALIZED -> normalizer.normalize(string)
|
||||||
|
QueryStringValue.Case.SENSITIVE,
|
||||||
|
QueryStringValue.Case.INSENSITIVE -> string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun QueryStringValue.Case.toRealmCase(): Case {
|
private fun QueryStringValue.Case.toRealmCase(): Case {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
QueryStringValue.Case.INSENSITIVE -> Case.INSENSITIVE
|
QueryStringValue.Case.INSENSITIVE -> Case.INSENSITIVE
|
||||||
QueryStringValue.Case.SENSITIVE -> Case.SENSITIVE
|
QueryStringValue.Case.SENSITIVE,
|
||||||
|
QueryStringValue.Case.NORMALIZED -> Case.SENSITIVE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.matrix.android.sdk.api.session.file.ContentDownloadStateTracker
|
||||||
import org.matrix.android.sdk.api.session.file.FileService
|
import org.matrix.android.sdk.api.session.file.FileService
|
||||||
import org.matrix.android.sdk.api.session.group.GroupService
|
import org.matrix.android.sdk.api.session.group.GroupService
|
||||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||||
|
import org.matrix.android.sdk.api.session.identity.IdentityService
|
||||||
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
import org.matrix.android.sdk.api.session.initsync.SyncStatusService
|
||||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||||
import org.matrix.android.sdk.api.session.media.MediaService
|
import org.matrix.android.sdk.api.session.media.MediaService
|
||||||
|
@ -72,7 +73,6 @@ import org.matrix.android.sdk.internal.di.SessionId
|
||||||
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate
|
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate
|
||||||
import org.matrix.android.sdk.internal.di.WorkManagerProvider
|
import org.matrix.android.sdk.internal.di.WorkManagerProvider
|
||||||
import org.matrix.android.sdk.internal.network.GlobalErrorHandler
|
import org.matrix.android.sdk.internal.network.GlobalErrorHandler
|
||||||
import org.matrix.android.sdk.internal.session.identity.DefaultIdentityService
|
|
||||||
import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
|
import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
|
||||||
import org.matrix.android.sdk.internal.session.sync.job.SyncThread
|
import org.matrix.android.sdk.internal.session.sync.job.SyncThread
|
||||||
import org.matrix.android.sdk.internal.session.sync.job.SyncWorker
|
import org.matrix.android.sdk.internal.session.sync.job.SyncWorker
|
||||||
|
@ -124,7 +124,7 @@ internal class DefaultSession @Inject constructor(
|
||||||
private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>,
|
private val _sharedSecretStorageService: Lazy<SharedSecretStorageService>,
|
||||||
private val accountService: Lazy<AccountService>,
|
private val accountService: Lazy<AccountService>,
|
||||||
private val eventService: Lazy<EventService>,
|
private val eventService: Lazy<EventService>,
|
||||||
private val defaultIdentityService: DefaultIdentityService,
|
private val identityService: IdentityService,
|
||||||
private val integrationManagerService: IntegrationManagerService,
|
private val integrationManagerService: IntegrationManagerService,
|
||||||
private val thirdPartyService: Lazy<ThirdPartyService>,
|
private val thirdPartyService: Lazy<ThirdPartyService>,
|
||||||
private val callSignalingService: Lazy<CallSignalingService>,
|
private val callSignalingService: Lazy<CallSignalingService>,
|
||||||
|
@ -275,7 +275,7 @@ internal class DefaultSession @Inject constructor(
|
||||||
|
|
||||||
override fun cryptoService(): CryptoService = cryptoService.get()
|
override fun cryptoService(): CryptoService = cryptoService.get()
|
||||||
|
|
||||||
override fun identityService() = defaultIdentityService
|
override fun identityService() = identityService
|
||||||
|
|
||||||
override fun fileService(): FileService = defaultFileService.get()
|
override fun fileService(): FileService = defaultFileService.get()
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ internal abstract class SessionModule {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Provides
|
@Provides
|
||||||
@SessionFilesDirectory
|
@SessionFilesDirectory
|
||||||
|
@SessionScope
|
||||||
fun providesFilesDir(@UserMd5 userMd5: String,
|
fun providesFilesDir(@UserMd5 userMd5: String,
|
||||||
@SessionId sessionId: String,
|
@SessionId sessionId: String,
|
||||||
context: Context): File {
|
context: Context): File {
|
||||||
|
|
|
@ -35,12 +35,12 @@ import org.matrix.android.sdk.api.failure.Failure
|
||||||
import org.matrix.android.sdk.api.failure.MatrixError
|
import org.matrix.android.sdk.api.failure.MatrixError
|
||||||
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
import org.matrix.android.sdk.api.session.content.ContentUrlResolver
|
||||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilities
|
||||||
|
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||||
import org.matrix.android.sdk.internal.di.Authenticated
|
import org.matrix.android.sdk.internal.di.Authenticated
|
||||||
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
|
||||||
import org.matrix.android.sdk.internal.network.ProgressRequestBody
|
import org.matrix.android.sdk.internal.network.ProgressRequestBody
|
||||||
import org.matrix.android.sdk.internal.network.awaitResponse
|
import org.matrix.android.sdk.internal.network.awaitResponse
|
||||||
import org.matrix.android.sdk.internal.network.toFailure
|
import org.matrix.android.sdk.internal.network.toFailure
|
||||||
import org.matrix.android.sdk.internal.session.homeserver.DefaultHomeServerCapabilitiesService
|
|
||||||
import org.matrix.android.sdk.internal.util.TemporaryFileCreator
|
import org.matrix.android.sdk.internal.util.TemporaryFileCreator
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
|
@ -50,7 +50,7 @@ import javax.inject.Inject
|
||||||
internal class FileUploader @Inject constructor(
|
internal class FileUploader @Inject constructor(
|
||||||
@Authenticated private val okHttpClient: OkHttpClient,
|
@Authenticated private val okHttpClient: OkHttpClient,
|
||||||
private val globalErrorReceiver: GlobalErrorReceiver,
|
private val globalErrorReceiver: GlobalErrorReceiver,
|
||||||
private val homeServerCapabilitiesService: DefaultHomeServerCapabilitiesService,
|
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val temporaryFileCreator: TemporaryFileCreator,
|
private val temporaryFileCreator: TemporaryFileCreator,
|
||||||
contentUrlResolver: ContentUrlResolver,
|
contentUrlResolver: ContentUrlResolver,
|
||||||
|
|
|
@ -214,8 +214,11 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
||||||
.also { filesToDelete.add(it) }
|
.also { filesToDelete.add(it) }
|
||||||
}
|
}
|
||||||
VideoCompressionResult.CompressionNotNeeded,
|
VideoCompressionResult.CompressionNotNeeded,
|
||||||
VideoCompressionResult.CompressionCancelled,
|
VideoCompressionResult.CompressionCancelled -> {
|
||||||
|
workingFile
|
||||||
|
}
|
||||||
is VideoCompressionResult.CompressionFailed -> {
|
is VideoCompressionResult.CompressionFailed -> {
|
||||||
|
Timber.e(videoCompressionResult.failure, "Video compression failed")
|
||||||
workingFile
|
workingFile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.content
|
||||||
|
|
||||||
import com.otaliastudios.transcoder.Transcoder
|
import com.otaliastudios.transcoder.Transcoder
|
||||||
import com.otaliastudios.transcoder.TranscoderListener
|
import com.otaliastudios.transcoder.TranscoderListener
|
||||||
|
import com.otaliastudios.transcoder.source.FilePathDataSource
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -43,7 +44,16 @@ internal class VideoCompressor @Inject constructor(
|
||||||
var result: Int = -1
|
var result: Int = -1
|
||||||
var failure: Throwable? = null
|
var failure: Throwable? = null
|
||||||
Transcoder.into(destinationFile.path)
|
Transcoder.into(destinationFile.path)
|
||||||
.addDataSource(videoFile.path)
|
.addDataSource(object : FilePathDataSource(videoFile.path) {
|
||||||
|
// https://github.com/natario1/Transcoder/issues/154
|
||||||
|
@Suppress("SENSELESS_COMPARISON") // Source is annotated as @NonNull, but can actually be null...
|
||||||
|
override fun isInitialized(): Boolean {
|
||||||
|
if (source == null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return super.isInitialized()
|
||||||
|
}
|
||||||
|
})
|
||||||
.setListener(object : TranscoderListener {
|
.setListener(object : TranscoderListener {
|
||||||
override fun onTranscodeProgress(progress: Double) {
|
override fun onTranscodeProgress(progress: Double) {
|
||||||
Timber.d("Compressing: $progress%")
|
Timber.d("Compressing: $progress%")
|
||||||
|
|
|
@ -30,12 +30,16 @@ import org.matrix.android.sdk.internal.database.model.GroupSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.GroupSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.query.QueryStringValueProcessor
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class DefaultGroupService @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
internal class DefaultGroupService @Inject constructor(
|
||||||
private val groupFactory: GroupFactory) : GroupService {
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val groupFactory: GroupFactory,
|
||||||
|
private val queryStringValueProcessor: QueryStringValueProcessor,
|
||||||
|
) : GroupService {
|
||||||
|
|
||||||
override fun getGroup(groupId: String): Group? {
|
override fun getGroup(groupId: String): Group? {
|
||||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||||
|
@ -67,8 +71,10 @@ internal class DefaultGroupService @Inject constructor(@SessionDatabase private
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun groupSummariesQuery(realm: Realm, queryParams: GroupSummaryQueryParams): RealmQuery<GroupSummaryEntity> {
|
private fun groupSummariesQuery(realm: Realm, queryParams: GroupSummaryQueryParams): RealmQuery<GroupSummaryEntity> {
|
||||||
return GroupSummaryEntity.where(realm)
|
return with(queryStringValueProcessor) {
|
||||||
.process(GroupSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
GroupSummaryEntity.where(realm)
|
||||||
.process(GroupSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
.process(GroupSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
|
.process(GroupSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ internal class DefaultIdentityService @Inject constructor(
|
||||||
private val identityApiProvider: IdentityApiProvider,
|
private val identityApiProvider: IdentityApiProvider,
|
||||||
private val accountDataDataSource: UserAccountDataDataSource,
|
private val accountDataDataSource: UserAccountDataDataSource,
|
||||||
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
|
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
|
||||||
private val sign3pidInvitationTask: DefaultSign3pidInvitationTask,
|
private val sign3pidInvitationTask: Sign3pidInvitationTask,
|
||||||
private val sessionParams: SessionParams
|
private val sessionParams: SessionParams
|
||||||
) : IdentityService, SessionLifecycleObserver {
|
) : IdentityService, SessionLifecycleObserver {
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
import org.matrix.android.sdk.api.session.identity.IdentityService
|
||||||
import org.matrix.android.sdk.internal.database.RealmKeysUtils
|
import org.matrix.android.sdk.internal.database.RealmKeysUtils
|
||||||
import org.matrix.android.sdk.internal.di.AuthenticatedIdentity
|
import org.matrix.android.sdk.internal.di.AuthenticatedIdentity
|
||||||
import org.matrix.android.sdk.internal.di.IdentityDatabase
|
import org.matrix.android.sdk.internal.di.IdentityDatabase
|
||||||
|
@ -75,6 +76,9 @@ internal abstract class IdentityModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindIdentityService(service: DefaultIdentityService): IdentityService
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@AuthenticatedIdentity
|
@AuthenticatedIdentity
|
||||||
abstract fun bindAccessTokenProvider(provider: IdentityAccessTokenProvider): AccessTokenProvider
|
abstract fun bindAccessTokenProvider(provider: IdentityAccessTokenProvider): AccessTokenProvider
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.notification
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
import org.matrix.android.sdk.api.pushrules.rest.PushRule
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.isInvitation
|
||||||
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse
|
import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
import org.matrix.android.sdk.internal.task.Task
|
import org.matrix.android.sdk.internal.task.Task
|
||||||
|
@ -48,14 +49,18 @@ internal class DefaultProcessEventForPushTask @Inject constructor(
|
||||||
}
|
}
|
||||||
val newJoinEvents = params.syncResponse.join
|
val newJoinEvents = params.syncResponse.join
|
||||||
.mapNotNull { (key, value) ->
|
.mapNotNull { (key, value) ->
|
||||||
value.timeline?.events?.map { it.copy(roomId = key) }
|
value.timeline?.events?.mapNotNull {
|
||||||
|
it.takeIf { !it.isInvitation() }?.copy(roomId = key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.flatten()
|
.flatten()
|
||||||
|
|
||||||
val inviteEvents = params.syncResponse.invite
|
val inviteEvents = params.syncResponse.invite
|
||||||
.mapNotNull { (key, value) ->
|
.mapNotNull { (key, value) ->
|
||||||
value.inviteState?.events?.map { it.copy(roomId = key) }
|
value.inviteState?.events?.map { it.copy(roomId = key) }
|
||||||
}
|
}
|
||||||
.flatten()
|
.flatten()
|
||||||
|
|
||||||
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
val allEvents = (newJoinEvents + inviteEvents).filter { event ->
|
||||||
when (event.type) {
|
when (event.type) {
|
||||||
EventType.MESSAGE,
|
EventType.MESSAGE,
|
||||||
|
|
|
@ -85,12 +85,14 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
return roomSummaryDataSource.getRoomSummary(roomIdOrAlias)
|
return roomSummaryDataSource.getRoomSummary(roomIdOrAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
|
override fun getRoomSummaries(queryParams: RoomSummaryQueryParams,
|
||||||
return roomSummaryDataSource.getRoomSummaries(queryParams)
|
sortOrder: RoomSortOrder): List<RoomSummary> {
|
||||||
|
return roomSummaryDataSource.getRoomSummaries(queryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
|
override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
||||||
return roomSummaryDataSource.getRoomSummariesLive(queryParams)
|
sortOrder: RoomSortOrder): LiveData<List<RoomSummary>> {
|
||||||
|
return roomSummaryDataSource.getRoomSummariesLive(queryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
override fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
|
import org.matrix.android.sdk.internal.query.QueryStringValueProcessor
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.admin.MembershipAdminTask
|
import org.matrix.android.sdk.internal.session.room.membership.admin.MembershipAdminTask
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.joining.InviteTask
|
import org.matrix.android.sdk.internal.session.room.membership.joining.InviteTask
|
||||||
|
@ -51,7 +52,8 @@ internal class DefaultMembershipService @AssistedInject constructor(
|
||||||
private val leaveRoomTask: LeaveRoomTask,
|
private val leaveRoomTask: LeaveRoomTask,
|
||||||
private val membershipAdminTask: MembershipAdminTask,
|
private val membershipAdminTask: MembershipAdminTask,
|
||||||
@UserId
|
@UserId
|
||||||
private val userId: String
|
private val userId: String,
|
||||||
|
private val queryStringValueProcessor: QueryStringValueProcessor
|
||||||
) : MembershipService {
|
) : MembershipService {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
@ -94,15 +96,17 @@ internal class DefaultMembershipService @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun roomMembersQuery(realm: Realm, queryParams: RoomMemberQueryParams): RealmQuery<RoomMemberSummaryEntity> {
|
private fun roomMembersQuery(realm: Realm, queryParams: RoomMemberQueryParams): RealmQuery<RoomMemberSummaryEntity> {
|
||||||
return RoomMemberHelper(realm, roomId).queryRoomMembersEvent()
|
return with(queryStringValueProcessor) {
|
||||||
.process(RoomMemberSummaryEntityFields.USER_ID, queryParams.userId)
|
RoomMemberHelper(realm, roomId).queryRoomMembersEvent()
|
||||||
.process(RoomMemberSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
.process(RoomMemberSummaryEntityFields.USER_ID, queryParams.userId)
|
||||||
.process(RoomMemberSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
.process(RoomMemberSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
.apply {
|
.process(RoomMemberSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
if (queryParams.excludeSelf) {
|
.apply {
|
||||||
notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId)
|
if (queryParams.excludeSelf) {
|
||||||
|
notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNumberOfJoinedMembers(): Int {
|
override fun getNumberOfJoinedMembers(): Int {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.matrix.android.sdk.internal.database.query.getOrNull
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.UserId
|
import org.matrix.android.sdk.internal.di.UserId
|
||||||
import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver
|
import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver
|
||||||
|
import org.matrix.android.sdk.internal.util.Normalizer
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +43,7 @@ import javax.inject.Inject
|
||||||
internal class RoomDisplayNameResolver @Inject constructor(
|
internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
matrixConfiguration: MatrixConfiguration,
|
matrixConfiguration: MatrixConfiguration,
|
||||||
private val displayNameResolver: DisplayNameResolver,
|
private val displayNameResolver: DisplayNameResolver,
|
||||||
|
private val normalizer: Normalizer,
|
||||||
@UserId private val userId: String
|
@UserId private val userId: String
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -54,7 +56,7 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
* @param roomId: the roomId to resolve the name of.
|
* @param roomId: the roomId to resolve the name of.
|
||||||
* @return the room display name
|
* @return the room display name
|
||||||
*/
|
*/
|
||||||
fun resolve(realm: Realm, roomId: String): String {
|
fun resolve(realm: Realm, roomId: String): RoomName {
|
||||||
// this algorithm is the one defined in
|
// this algorithm is the one defined in
|
||||||
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
|
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
|
||||||
// calculateRoomName(room, userId)
|
// calculateRoomName(room, userId)
|
||||||
|
@ -66,12 +68,12 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root
|
val roomName = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_NAME, stateKey = "")?.root
|
||||||
name = ContentMapper.map(roomName?.content).toModel<RoomNameContent>()?.name
|
name = ContentMapper.map(roomName?.content).toModel<RoomNameContent>()?.name
|
||||||
if (!name.isNullOrEmpty()) {
|
if (!name.isNullOrEmpty()) {
|
||||||
return name
|
return name.toRoomName()
|
||||||
}
|
}
|
||||||
val canonicalAlias = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root
|
val canonicalAlias = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_CANONICAL_ALIAS, stateKey = "")?.root
|
||||||
name = ContentMapper.map(canonicalAlias?.content).toModel<RoomCanonicalAliasContent>()?.canonicalAlias
|
name = ContentMapper.map(canonicalAlias?.content).toModel<RoomCanonicalAliasContent>()?.canonicalAlias
|
||||||
if (!name.isNullOrEmpty()) {
|
if (!name.isNullOrEmpty()) {
|
||||||
return name
|
return name.toRoomName()
|
||||||
}
|
}
|
||||||
|
|
||||||
val roomMembers = RoomMemberHelper(realm, roomId)
|
val roomMembers = RoomMemberHelper(realm, roomId)
|
||||||
|
@ -152,7 +154,7 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return name ?: roomId
|
return (name ?: roomId).toRoomName()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See [org.matrix.android.sdk.api.session.room.sender.SenderInfo.disambiguatedDisplayName] */
|
/** See [org.matrix.android.sdk.api.session.room.sender.SenderInfo.disambiguatedDisplayName] */
|
||||||
|
@ -165,4 +167,8 @@ internal class RoomDisplayNameResolver @Inject constructor(
|
||||||
"${roomMemberSummary.displayName} (${roomMemberSummary.userId})"
|
"${roomMemberSummary.displayName} (${roomMemberSummary.userId})"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.toRoomName() = RoomName(this, normalizedName = normalizer.normalize(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal data class RoomName(val name: String, val normalizedName: String)
|
||||||
|
|
|
@ -31,11 +31,15 @@ import org.matrix.android.sdk.internal.database.mapper.asDomain
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.query.QueryStringValueProcessor
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class StateEventDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
internal class StateEventDataSource @Inject constructor(
|
||||||
private val realmSessionProvider: RealmSessionProvider) {
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
|
private val queryStringValueProcessor: QueryStringValueProcessor
|
||||||
|
) {
|
||||||
|
|
||||||
fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStringValue): Event? {
|
fun getStateEvent(roomId: String, eventType: String, stateKey: QueryStringValue): Event? {
|
||||||
return realmSessionProvider.withRealm { realm ->
|
return realmSessionProvider.withRealm { realm ->
|
||||||
|
@ -78,13 +82,15 @@ internal class StateEventDataSource @Inject constructor(@SessionDatabase private
|
||||||
eventTypes: Set<String>,
|
eventTypes: Set<String>,
|
||||||
stateKey: QueryStringValue
|
stateKey: QueryStringValue
|
||||||
): RealmQuery<CurrentStateEventEntity> {
|
): RealmQuery<CurrentStateEventEntity> {
|
||||||
return realm.where<CurrentStateEventEntity>()
|
return with(queryStringValueProcessor) {
|
||||||
.equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId)
|
realm.where<CurrentStateEventEntity>()
|
||||||
.apply {
|
.equalTo(CurrentStateEventEntityFields.ROOM_ID, roomId)
|
||||||
if (eventTypes.isNotEmpty()) {
|
.apply {
|
||||||
`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
|
if (eventTypes.isNotEmpty()) {
|
||||||
|
`in`(CurrentStateEventEntityFields.TYPE, eventTypes.toTypedArray())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.process(CurrentStateEventEntityFields.STATE_KEY, stateKey)
|
||||||
.process(CurrentStateEventEntityFields.STATE_KEY, stateKey)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ import androidx.paging.PagedList
|
||||||
import com.zhuinden.monarchy.Monarchy
|
import com.zhuinden.monarchy.Monarchy
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
import io.realm.Sort
|
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
|
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
|
||||||
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||||
|
import org.matrix.android.sdk.api.query.isNormalized
|
||||||
import org.matrix.android.sdk.api.session.room.ResultBoundaries
|
import org.matrix.android.sdk.api.session.room.ResultBoundaries
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams
|
||||||
|
@ -48,12 +48,16 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.query.findByAlias
|
import org.matrix.android.sdk.internal.database.query.findByAlias
|
||||||
import org.matrix.android.sdk.internal.database.query.where
|
import org.matrix.android.sdk.internal.database.query.where
|
||||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||||
|
import org.matrix.android.sdk.internal.query.QueryStringValueProcessor
|
||||||
import org.matrix.android.sdk.internal.query.process
|
import org.matrix.android.sdk.internal.query.process
|
||||||
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase private val monarchy: Monarchy,
|
internal class RoomSummaryDataSource @Inject constructor(
|
||||||
private val roomSummaryMapper: RoomSummaryMapper) {
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val roomSummaryMapper: RoomSummaryMapper,
|
||||||
|
private val queryStringValueProcessor: QueryStringValueProcessor
|
||||||
|
) {
|
||||||
|
|
||||||
fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
|
fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
|
||||||
return monarchy
|
return monarchy
|
||||||
|
@ -80,25 +84,27 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
|
fun getRoomSummaries(queryParams: RoomSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): List<RoomSummary> {
|
||||||
return monarchy.fetchAllMappedSync(
|
return monarchy.fetchAllMappedSync(
|
||||||
{ roomSummariesQuery(it, queryParams) },
|
{ roomSummariesQuery(it, queryParams).process(sortOrder) },
|
||||||
{ roomSummaryMapper.map(it) }
|
{ roomSummaryMapper.map(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
|
fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams,
|
||||||
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData<List<RoomSummary>> {
|
||||||
return monarchy.findAllMappedWithChanges(
|
return monarchy.findAllMappedWithChanges(
|
||||||
{
|
{
|
||||||
roomSummariesQuery(it, queryParams)
|
roomSummariesQuery(it, queryParams).process(sortOrder)
|
||||||
.sort(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Sort.DESCENDING)
|
|
||||||
},
|
},
|
||||||
{ roomSummaryMapper.map(it) }
|
{ roomSummaryMapper.map(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData<List<RoomSummary>> {
|
fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams,
|
||||||
return getRoomSummariesLive(queryParams)
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData<List<RoomSummary>> {
|
||||||
|
return getRoomSummariesLive(queryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSpaceSummary(roomIdOrAlias: String): RoomSummary? {
|
fun getSpaceSummary(roomIdOrAlias: String): RoomSummary? {
|
||||||
|
@ -122,8 +128,9 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List<RoomSummary> {
|
fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams,
|
||||||
return getRoomSummaries(spaceSummaryQueryParams)
|
sortOrder: RoomSortOrder = RoomSortOrder.NONE): List<RoomSummary> {
|
||||||
|
return getRoomSummaries(spaceSummaryQueryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRootSpaceSummaries(): List<RoomSummary> {
|
fun getRootSpaceSummaries(): List<RoomSummary> {
|
||||||
|
@ -238,12 +245,20 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||||
val query = RoomSummaryEntity.where(realm)
|
val query = with(queryStringValueProcessor) {
|
||||||
query.process(RoomSummaryEntityFields.ROOM_ID, queryParams.roomId)
|
RoomSummaryEntity.where(realm)
|
||||||
query.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
.process(RoomSummaryEntityFields.ROOM_ID, queryParams.roomId)
|
||||||
query.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
|
.let {
|
||||||
query.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
if (queryParams.displayName.isNormalized()) {
|
||||||
query.equalTo(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, false)
|
it.process(RoomSummaryEntityFields.NORMALIZED_DISPLAY_NAME, queryParams.displayName)
|
||||||
|
} else {
|
||||||
|
it.process(RoomSummaryEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
|
||||||
|
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||||
|
.equalTo(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, false)
|
||||||
|
}
|
||||||
|
|
||||||
queryParams.roomCategoryFilter?.let {
|
queryParams.roomCategoryFilter?.let {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
|
|
@ -65,6 +65,7 @@ import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataD
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver
|
import org.matrix.android.sdk.internal.session.room.membership.RoomDisplayNameResolver
|
||||||
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper
|
||||||
import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo
|
import org.matrix.android.sdk.internal.session.room.relationship.RoomChildRelationInfo
|
||||||
|
import org.matrix.android.sdk.internal.util.Normalizer
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
@ -75,7 +76,8 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||||
private val roomAvatarResolver: RoomAvatarResolver,
|
private val roomAvatarResolver: RoomAvatarResolver,
|
||||||
private val eventDecryptor: EventDecryptor,
|
private val eventDecryptor: EventDecryptor,
|
||||||
private val crossSigningService: DefaultCrossSigningService,
|
private val crossSigningService: DefaultCrossSigningService,
|
||||||
private val roomAccountDataDataSource: RoomAccountDataDataSource) {
|
private val roomAccountDataDataSource: RoomAccountDataDataSource,
|
||||||
|
private val normalizer: Normalizer) {
|
||||||
|
|
||||||
fun update(realm: Realm,
|
fun update(realm: Realm,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
|
@ -136,7 +138,7 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||||
// avoid this call if we are sure there are unread events
|
// avoid this call if we are sure there are unread events
|
||||||
!isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId)
|
!isEventRead(realm.configuration, userId, roomId, latestPreviewableEvent?.eventId)
|
||||||
|
|
||||||
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(realm, roomId)
|
roomSummaryEntity.setDisplayName(roomDisplayNameResolver.resolve(realm, roomId))
|
||||||
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
|
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
|
||||||
roomSummaryEntity.name = ContentMapper.map(lastNameEvent?.content).toModel<RoomNameContent>()?.name
|
roomSummaryEntity.name = ContentMapper.map(lastNameEvent?.content).toModel<RoomNameContent>()?.name
|
||||||
roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel<RoomTopicContent>()?.topic
|
roomSummaryEntity.topic = ContentMapper.map(lastTopicEvent?.content).toModel<RoomTopicContent>()?.topic
|
||||||
|
|
|
@ -42,11 +42,12 @@ internal class DefaultSignInAgainTask @Inject constructor(
|
||||||
signOutAPI.loginAgain(
|
signOutAPI.loginAgain(
|
||||||
PasswordLoginParams.userIdentifier(
|
PasswordLoginParams.userIdentifier(
|
||||||
// Reuse the same userId
|
// Reuse the same userId
|
||||||
sessionParams.userId,
|
user = sessionParams.userId,
|
||||||
params.password,
|
password = params.password,
|
||||||
// The spec says the initial device name will be ignored
|
// The spec says the initial device name will be ignored
|
||||||
// https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login
|
// https://matrix.org/docs/spec/client_server/latest#post-matrix-client-r0-login
|
||||||
// but https://github.com/matrix-org/synapse/issues/6525
|
// but https://github.com/matrix-org/synapse/issues/6525
|
||||||
|
deviceDisplayName = null,
|
||||||
// Reuse the same deviceId
|
// Reuse the same deviceId
|
||||||
deviceId = sessionParams.deviceId
|
deviceId = sessionParams.deviceId
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
import org.matrix.android.sdk.api.session.room.model.GuestAccess
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
|
||||||
|
@ -94,12 +95,14 @@ internal class DefaultSpaceService @Inject constructor(
|
||||||
return spaceGetter.get(spaceId)
|
return spaceGetter.get(spaceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData<List<RoomSummary>> {
|
override fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams,
|
||||||
return roomSummaryDataSource.getSpaceSummariesLive(queryParams)
|
sortOrder: RoomSortOrder): LiveData<List<RoomSummary>> {
|
||||||
|
return roomSummaryDataSource.getSpaceSummariesLive(queryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List<RoomSummary> {
|
override fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams,
|
||||||
return roomSummaryDataSource.getSpaceSummaries(spaceSummaryQueryParams)
|
sortOrder: RoomSortOrder): List<RoomSummary> {
|
||||||
|
return roomSummaryDataSource.getSpaceSummaries(spaceSummaryQueryParams, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRootSpaceSummaries(): List<RoomSummary> {
|
override fun getRootSpaceSummaries(): List<RoomSummary> {
|
||||||
|
|
|
@ -39,8 +39,11 @@ internal class RoomSyncEphemeralTemporaryStoreFile @Inject constructor(
|
||||||
moshi: Moshi
|
moshi: Moshi
|
||||||
) : RoomSyncEphemeralTemporaryStore {
|
) : RoomSyncEphemeralTemporaryStore {
|
||||||
|
|
||||||
private val workingDir = File(fileDirectory, "rr")
|
private val workingDir: File by lazy {
|
||||||
.also { it.mkdirs() }
|
File(fileDirectory, "rr").also {
|
||||||
|
it.mkdirs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val roomSyncEphemeralAdapter = moshi.adapter(RoomSyncEphemeral::class.java)
|
private val roomSyncEphemeralAdapter = moshi.adapter(RoomSyncEphemeral::class.java)
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
|
||||||
roomSummaryEntity.directUserId = userId
|
roomSummaryEntity.directUserId = userId
|
||||||
// Also update the avatar and displayname, there is a specific treatment for DMs
|
// Also update the avatar and displayname, there is a specific treatment for DMs
|
||||||
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
|
roomSummaryEntity.avatarUrl = roomAvatarResolver.resolve(realm, roomId)
|
||||||
roomSummaryEntity.displayName = roomDisplayNameResolver.resolve(realm, roomId)
|
roomSummaryEntity.setDisplayName(roomDisplayNameResolver.resolve(realm, roomId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
|
||||||
it.directUserId = null
|
it.directUserId = null
|
||||||
// Also update the avatar and displayname, there was a specific treatment for DMs
|
// Also update the avatar and displayname, there was a specific treatment for DMs
|
||||||
it.avatarUrl = roomAvatarResolver.resolve(realm, it.roomId)
|
it.avatarUrl = roomAvatarResolver.resolve(realm, it.roomId)
|
||||||
it.displayName = roomDisplayNameResolver.resolve(realm, it.roomId)
|
it.setDisplayName(roomDisplayNameResolver.resolve(realm, it.roomId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue