Merge branch 'develop' into feature/attachments

This commit is contained in:
ganfra 2019-10-11 17:05:03 +02:00
commit 13a5f784dc
962 changed files with 2313 additions and 3563 deletions

View File

@ -54,4 +54,13 @@ steps:
# Code quality # Code quality
- label: "Code quality" - label: "Code quality"
command: "./tools/check/check_code_quality.sh" command:
- "./tools/check/check_code_quality.sh"
- label: "ktlint"
command:
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint"
- "./ktlint --android --experimental -v"
plugins:
- docker#v3.1.0:
image: "openjdk"

32
.editorconfig Normal file
View File

@ -0,0 +1,32 @@
# For ktlint configuration. Ref: https://ktlint.github.io/
[*.{kt,kts}]
# possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely)
indent_size=unset
# true (recommended) / false
insert_final_newline=true
# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off"
# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide)
max_line_length=off
# Comma-separated list of rules to disable (Since 0.34.0)
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed
# by the ruleset identifier.
disabled_rules=no-wildcard-imports,no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation
# The following (so far identified) rules are kept:
# no-blank-line-before-rbrace
# final-newline
# no-consecutive-blank-lines
# comment-spacing
# filename
# comma-spacing
# paren-spacing
# op-spacing
# string-template
# no-unused-imports
# curly-spacing
# no-semi
# no-empty-class-body
# experimental:multiline-if-else
# experimental:no-empty-first-line-in-method-block

12
.gitignore vendored
View File

@ -1,14 +1,16 @@
*.iml *.iml
.gradle .gradle
/local.properties /local.properties
.idea/* # idea files: exclude everything except dictionnaries
/.idea/* .idea/caches
/.idea/libraries .idea/codeStyles
/.idea/modules.xml .idea/libraries
/.idea/workspace.xml .idea/*.xml
.DS_Store .DS_Store
/build /build
/captures /captures
.externalNativeBuild .externalNativeBuild
/tmp /tmp
ktlint

View File

@ -0,0 +1,19 @@
<component name="ProjectDictionaryState">
<dictionary name="bmarty">
<words>
<w>backstack</w>
<w>bytearray</w>
<w>ciphertext</w>
<w>decryptor</w>
<w>emoji</w>
<w>emojis</w>
<w>hmac</w>
<w>ktlint</w>
<w>linkified</w>
<w>linkify</w>
<w>megolm</w>
<w>pbkdf</w>
<w>pkcs</w>
</words>
</dictionary>
</component>

View File

@ -17,6 +17,8 @@ Bugfix:
- Fix opening a permalink: the targeted event is displayed twice (#556) - Fix opening a permalink: the targeted event is displayed twice (#556)
- Fix opening a permalink paginates all the history up to the last event (#282) - Fix opening a permalink paginates all the history up to the last event (#282)
- after login, the icon in the top left is a green 'A' for (all communities) rather than my avatar (#267) - after login, the icon in the top left is a green 'A' for (all communities) rather than my avatar (#267)
- Picture uploads are unreliable, pictures are shown in wrong aspect ratio on desktop client (#517)
- Invitation notifications are not dismissed automatically if room is joined from another client (#347)
Translations: Translations:
- -
@ -167,21 +169,21 @@ Mode details here: https://medium.com/@RiotChat/introducing-the-riotx-beta-for-a
Changes in RiotX 0.0.0 (2019-XX-XX) Changes in RiotX 0.0.0 (2019-XX-XX)
=================================================== ===================================================
Features: Features:
- -
Improvements: Improvements 🙌:
- -
Other changes: Other changes:
- -
Bugfix: Bugfix 🐛:
- -
Translations: Translations 🗣:
- -
Build: Build 🧱:
- -

View File

@ -42,6 +42,15 @@ Make sure the following commands execute without any error:
> ./tools/check/check_code_quality.sh > ./tools/check/check_code_quality.sh
> curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint
> ./ktlint --android -v
Note that you can run
> ./ktlint --android -v -F
For ktlint to fix some detected errors for you
> ./gradlew lintGplayRelease > ./gradlew lintGplayRelease
### Unit tests ### Unit tests

View File

@ -1,5 +1,3 @@
import javax.tools.JavaCompiler
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
@ -61,6 +59,11 @@ allprojects {
] ]
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
// Warnings are potential errors, so stop ignoring them
kotlinOptions.allWarningsAsErrors = true
}
afterEvaluate { afterEvaluate {
extensions.findByName("kapt")?.arguments { extensions.findByName("kapt")?.arguments {
arg("dagger.gradle.incremental", "enabled") arg("dagger.gradle.incremental", "enabled")

View File

@ -5,8 +5,6 @@ apply plugin: 'kotlin-kapt'
android { android {
compileSdkVersion 28 compileSdkVersion 28
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
@ -14,7 +12,6 @@ android {
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {

View File

@ -19,7 +19,6 @@ package im.vector.matrix.rx
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import io.reactivex.CompletableEmitter import io.reactivex.CompletableEmitter
import io.reactivex.SingleEmitter
internal class MatrixCallbackCompletable<T>(private val completableEmitter: CompletableEmitter) : MatrixCallback<T> { internal class MatrixCallbackCompletable<T>(private val completableEmitter: CompletableEmitter) : MatrixCallback<T> {

View File

@ -67,7 +67,6 @@ class RxRoom(private val room: Room) {
fun liveDrafts(): Observable<List<UserDraft>> { fun liveDrafts(): Observable<List<UserDraft>> {
return room.getDraftsLive().asObservable() return room.getDraftsLive().asObservable()
} }
} }
fun Room.rx(): RxRoom { fun Room.rx(): RxRoom {

View File

@ -71,7 +71,6 @@ class RxSession(private val session: Session) {
fun joinRoom(roomId: String, viaServers: List<String> = emptyList()): Single<Unit> = Single.create { fun joinRoom(roomId: String, viaServers: List<String> = emptyList()): Single<Unit> = Single.create {
session.joinRoom(roomId, viaServers, MatrixCallbackSingle(it)).toSingle(it) session.joinRoom(roomId, viaServers, MatrixCallbackSingle(it)).toSingle(it)
} }
} }
fun Session.rx(): RxSession { fun Session.rx(): RxSession {

View File

@ -118,6 +118,9 @@ dependencies {
implementation "ru.noties.markwon:core:$markwon_version" implementation "ru.noties.markwon:core:$markwon_version"
// Image
implementation 'androidx.exifinterface:exifinterface:1.0.0'
// Database // Database
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1' implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
kapt 'dk.ilios:realmfieldnameshelper:1.1.1' kapt 'dk.ilios:realmfieldnameshelper:1.1.1'

View File

@ -28,7 +28,6 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
internal class AuthenticatorTest : InstrumentedTest { internal class AuthenticatorTest : InstrumentedTest {
@ -50,7 +49,6 @@ internal class AuthenticatorTest : InstrumentedTest {
@UiThreadTest @UiThreadTest
@OkReplay(tape = "auth", mode = TapeMode.READ_WRITE) @OkReplay(tape = "auth", mode = TapeMode.READ_WRITE)
fun auth() { fun auth() {
} }
companion object { companion object {
@ -59,6 +57,4 @@ internal class AuthenticatorTest : InstrumentedTest {
val grantExternalStoragePermissionRule: GrantPermissionRule = val grantExternalStoragePermissionRule: GrantPermissionRule =
GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
} }
} }

View File

@ -62,8 +62,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}")) JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}"))
} }
/* ========================================================================================== /* ==========================================================================================
* Test from https://matrix.org/docs/spec/appendices.html#examples * Test from https://matrix.org/docs/spec/appendices.html#examples
* ========================================================================================== */ * ========================================================================================== */
@ -74,7 +72,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
JsonCanonicalizer.canonicalize("""{}""")) JsonCanonicalizer.canonicalize("""{}"""))
} }
@Test @Test
fun matrixOrg002Test() { fun matrixOrg002Test() {
assertEquals("""{"one":1,"two":"Two"}""", assertEquals("""{"one":1,"two":"Two"}""",
@ -84,7 +81,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
}""")) }"""))
} }
@Test @Test
fun matrixOrg003Test() { fun matrixOrg003Test() {
assertEquals("""{"a":"1","b":"2"}""", assertEquals("""{"a":"1","b":"2"}""",
@ -94,14 +90,12 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
}""")) }"""))
} }
@Test @Test
fun matrixOrg004Test() { fun matrixOrg004Test() {
assertEquals("""{"a":"1","b":"2"}""", assertEquals("""{"a":"1","b":"2"}""",
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}""")) JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}"""))
} }
@Test @Test
fun matrixOrg005Test() { fun matrixOrg005Test() {
assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""", assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
@ -126,7 +120,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
}""")) }"""))
} }
@Test @Test
fun matrixOrg006Test() { fun matrixOrg006Test() {
assertEquals("""{"a":"日本語"}""", assertEquals("""{"a":"日本語"}""",
@ -135,7 +128,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
}""")) }"""))
} }
@Test @Test
fun matrixOrg007Test() { fun matrixOrg007Test() {
assertEquals("""{"日":1,"本":2}""", assertEquals("""{"日":1,"本":2}""",
@ -145,7 +137,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
}""")) }"""))
} }
@Test @Test
fun matrixOrg008Test() { fun matrixOrg008Test() {
assertEquals("""{"a":"日"}""", assertEquals("""{"a":"日"}""",

View File

@ -35,7 +35,6 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
internal class ChunkEntityTest : InstrumentedTest { internal class ChunkEntityTest : InstrumentedTest {
@ -48,7 +47,6 @@ internal class ChunkEntityTest : InstrumentedTest {
monarchy = Monarchy.Builder().setRealmConfiguration(testConfig).build() monarchy = Monarchy.Builder().setRealmConfiguration(testConfig).build()
} }
@Test @Test
fun add_shouldAdd_whenNotAlreadyIncluded() { fun add_shouldAdd_whenNotAlreadyIncluded() {
monarchy.runTransactionSync { realm -> monarchy.runTransactionSync { realm ->
@ -194,5 +192,4 @@ internal class ChunkEntityTest : InstrumentedTest {
chunk1.nextToken shouldEqual nextToken chunk1.nextToken shouldEqual nextToken
} }
} }
} }

View File

@ -32,6 +32,4 @@ internal class FakeGetContextOfEventTask constructor(private val tokenChunkEvent
) )
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, PaginationDirection.BACKWARDS) return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, PaginationDirection.BACKWARDS)
} }
} }

View File

@ -28,6 +28,4 @@ internal class FakePaginationTask @Inject constructor(private val tokenChunkEven
val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong(System.currentTimeMillis()).toString(), fakeEvents) val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong(System.currentTimeMillis()).toString(), fakeEvents)
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, params.direction) return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, params.direction)
} }
} }

View File

@ -88,6 +88,4 @@ object RoomDataHelper {
roomEntity.addOrUpdate(chunkEntity) roomEntity.addOrUpdate(chunkEntity)
} }
} }
} }

View File

@ -81,6 +81,4 @@ internal class TimelineTest : InstrumentedTest {
// timelineEvents.size shouldEqual initialLoad + paginationCount // timelineEvents.size shouldEqual initialLoad + paginationCount
// timeline.dispose() // timeline.dispose()
// } // }
} }

View File

@ -51,7 +51,6 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
// Finally this is not a JSON string... // Finally this is not a JSON string...
Timber.e(e) Timber.e(e)
} }
} else if (message.startsWith("[")) { } else if (message.startsWith("[")) {
// JSON Array detected // JSON Array detected
try { try {
@ -61,7 +60,6 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
// Finally not JSON... // Finally not JSON...
Timber.e(e) Timber.e(e)
} }
} }
// Else not a json string to log // Else not a json string to log
} }

View File

@ -38,7 +38,6 @@ data class MatrixConfiguration(
interface Provider { interface Provider {
fun providesMatrixConfiguration(): MatrixConfiguration fun providesMatrixConfiguration(): MatrixConfiguration
} }
} }
/** /**
@ -98,5 +97,4 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
return BuildConfig.VERSION_NAME + " (" + BuildConfig.GIT_SDK_REVISION + ")" return BuildConfig.VERSION_NAME + " (" + BuildConfig.GIT_SDK_REVISION + ")"
} }
} }
} }

View File

@ -37,5 +37,4 @@ interface MatrixCallback<in T> {
fun onFailure(failure: Throwable) { fun onFailure(failure: Throwable) {
// no-op // no-op
} }
} }

View File

@ -16,7 +16,6 @@
package im.vector.matrix.android.api package im.vector.matrix.android.api
/** /**
* This class contains pattern to match the different Matrix ids * This class contains pattern to match the different Matrix ids
*/ */
@ -154,6 +153,5 @@ object MatrixPatterns {
return if (index == -1) { return if (index == -1) {
null null
} else matrixId.substring(index + 1) } else matrixId.substring(index + 1)
} }
} }

View File

@ -253,13 +253,5 @@ data class HomeServerConnectionConfig(
forceUsageTlsVersions forceUsageTlsVersions
) )
} }
} }
} }

View File

@ -29,7 +29,6 @@ fun MXDeviceInfo.getFingerprintHumanReadable() = fingerprint()
?.chunked(4) ?.chunked(4)
?.joinToString(separator = " ") ?.joinToString(separator = " ")
fun List<DeviceInfo>.sortByLastSeen() { fun List<DeviceInfo>.sortByLastSeen() {
Collections.sort(this, DatedObjectComparators.descComparator) Collections.sort(this, DatedObjectComparators.descComparator)
} }

View File

@ -42,5 +42,4 @@ sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
data class CryptoError(val error: MXCryptoError) : Failure(error) data class CryptoError(val error: MXCryptoError) : Failure(error)
abstract class FeatureFailure : Failure() abstract class FeatureFailure : Failure()
} }

View File

@ -33,7 +33,6 @@ data class MatrixError(
@Json(name = "limit_type") val limitType: String? = null, @Json(name = "limit_type") val limitType: String? = null,
@Json(name = "admin_contact") val adminUri: String? = null) { @Json(name = "admin_contact") val adminUri: String? = null) {
companion object { companion object {
const val FORBIDDEN = "M_FORBIDDEN" const val FORBIDDEN = "M_FORBIDDEN"
const val UNKNOWN = "M_UNKNOWN" const val UNKNOWN = "M_UNKNOWN"

View File

@ -51,5 +51,4 @@ object MatrixLinkify {
} }
return hasMatch return hasMatch
} }
} }

View File

@ -35,6 +35,4 @@ class MatrixPermalinkSpan(private val url: String,
override fun onClick(widget: View) { override fun onClick(widget: View) {
callback?.onUrlClicked(url) callback?.onUrlClicked(url)
} }
} }

View File

@ -33,5 +33,4 @@ sealed class PermalinkData {
data class GroupLink(val groupId: String) : PermalinkData() data class GroupLink(val groupId: String) : PermalinkData()
data class FallbackLink(val uri: Uri) : PermalinkData() data class FallbackLink(val uri: Uri) : PermalinkData()
} }

View File

@ -51,7 +51,6 @@ object PermalinkFactory {
return if (TextUtils.isEmpty(id)) { return if (TextUtils.isEmpty(id)) {
null null
} else MATRIX_TO_URL_BASE + escape(id) } else MATRIX_TO_URL_BASE + escape(id)
} }
/** /**
@ -78,10 +77,8 @@ object PermalinkFactory {
return if (isSupported) { return if (isSupported) {
url!!.substring(MATRIX_TO_URL_BASE.length) url!!.substring(MATRIX_TO_URL_BASE.length)
} else null } else null
} }
/** /**
* Escape '/' in id, because it is used as a separator * Escape '/' in id, because it is used as a separator
* *

View File

@ -72,5 +72,4 @@ object PermalinkParser {
else -> PermalinkData.FallbackLink(uri) else -> PermalinkData.FallbackLink(uri)
} }
} }
} }

View File

@ -18,7 +18,6 @@ package im.vector.matrix.android.api.pushrules
import im.vector.matrix.android.api.pushrules.rest.PushRule import im.vector.matrix.android.api.pushrules.rest.PushRule
import timber.log.Timber import timber.log.Timber
sealed class Action { sealed class Action {
object Notify : Action() object Notify : Action()
object DoNotNotify : Action() object DoNotNotify : Action()
@ -26,7 +25,6 @@ sealed class Action {
data class Highlight(val highlight: Boolean) : Action() data class Highlight(val highlight: Boolean) : Action()
} }
private const val ACTION_NOTIFY = "notify" private const val ACTION_NOTIFY = "notify"
private const val ACTION_DONT_NOTIFY = "dont_notify" private const val ACTION_DONT_NOTIFY = "dont_notify"
private const val ACTION_COALESCE = "coalesce" private const val ACTION_COALESCE = "coalesce"
@ -80,7 +78,6 @@ fun PushRule.getActions(): List<Action> {
} }
// When the value is not there, default sound (not specified by the spec) // When the value is not there, default sound (not specified by the spec)
?: Action.Sound(ACTION_OBJECT_VALUE_VALUE_DEFAULT) ?: Action.Sound(ACTION_OBJECT_VALUE_VALUE_DEFAULT)
} }
ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> { ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> {
(actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue -> (actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue ->
@ -104,7 +101,5 @@ fun PushRule.getActions(): List<Action> {
} }
} }
return result return result
} }

View File

@ -35,9 +35,7 @@ abstract class Condition(val kind: Kind) {
else -> UNRECOGNIZE else -> UNRECOGNIZE
} }
} }
} }
} }
abstract fun isSatisfied(conditionResolver: ConditionResolver): Boolean abstract fun isSatisfied(conditionResolver: ConditionResolver): Boolean

View File

@ -49,7 +49,6 @@ class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
return caseInsensitiveFind(displayName, message.body) return caseInsensitiveFind(displayName, message.body)
} }
companion object { companion object {
/** /**
* Returns whether a string contains an occurrence of another, as a standalone word, regardless of case. * Returns whether a string contains an occurrence of another, as a standalone word, regardless of case.

View File

@ -29,7 +29,6 @@ class EventMatchCondition(val key: String, val pattern: String) : Condition(Kind
return "'$key' Matches '$pattern'" return "'$key' Matches '$pattern'"
} }
fun isSatisfied(event: Event): Boolean { fun isSatisfied(event: Event): Boolean {
// TODO encrypted events? // TODO encrypted events?
val rawJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *> val rawJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *>
@ -47,10 +46,8 @@ class EventMatchCondition(val key: String, val pattern: String) : Condition(Kind
Timber.e(e, "Failed to evaluate push condition") Timber.e(e, "Failed to evaluate push condition")
return false return false
} }
} }
private fun extractField(jsonObject: Map<*, *>, fieldPath: String): String? { private fun extractField(jsonObject: Map<*, *>, fieldPath: String): String? {
val fieldParts = fieldPath.split(".") val fieldParts = fieldPath.split(".")
if (fieldParts.isEmpty()) return null if (fieldParts.isEmpty()) return null

View File

@ -42,6 +42,7 @@ interface PushRuleService {
interface PushRuleListener { interface PushRuleListener {
fun onMatchRule(event: Event, actions: List<Action>) fun onMatchRule(event: Event, actions: List<Action>)
fun onRoomJoined(roomId: String)
fun onRoomLeft(roomId: String) fun onRoomLeft(roomId: String)
fun onEventRedacted(redactedEventId: String) fun onEventRedacted(redactedEventId: String)
fun batchFinish() fun batchFinish()

View File

@ -62,6 +62,5 @@ class RoomMemberCountCondition(val iz: String) : Condition(Kind.room_member_coun
Timber.d(t) Timber.d(t)
} }
return null return null
} }
} }

View File

@ -18,7 +18,6 @@ package im.vector.matrix.android.api.pushrules
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.PowerLevels import im.vector.matrix.android.api.session.room.model.PowerLevels
class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.sender_notification_permission) { class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.sender_notification_permission) {
override fun isSatisfied(conditionResolver: ConditionResolver): Boolean { override fun isSatisfied(conditionResolver: ConditionResolver): Boolean {
@ -29,7 +28,6 @@ class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.se
return "User power level <$key>" return "User power level <$key>"
} }
fun isSatisfied(event: Event, powerLevels: PowerLevels): Boolean { fun isSatisfied(event: Event, powerLevels: PowerLevels): Boolean {
return event.senderId != null && powerLevels.getUserPowerLevel(event.senderId) >= powerLevels.notificationLevel(key) return event.senderId != null && powerLevels.getUserPowerLevel(event.senderId) >= powerLevels.notificationLevel(key)
} }

View File

@ -19,7 +19,6 @@ package im.vector.matrix.android.api.pushrules.rest
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true) @JsonClass(generateAdapter = true)
data class PushRule( data class PushRule(
/** /**
@ -47,4 +46,3 @@ data class PushRule(
*/ */
val pattern: String? = null val pattern: String? = null
) )

View File

@ -19,6 +19,7 @@ package im.vector.matrix.android.api.session
import androidx.annotation.MainThread import androidx.annotation.MainThread
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.auth.data.SessionParams import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.failure.ConsentNotGivenError
import im.vector.matrix.android.api.pushrules.PushRuleService import im.vector.matrix.android.api.pushrules.PushRuleService
import im.vector.matrix.android.api.session.cache.CacheService import im.vector.matrix.android.api.session.cache.CacheService
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
@ -67,7 +68,6 @@ interface Session :
val myUserId: String val myUserId: String
get() = sessionParams.credentials.userId get() = sessionParams.credentials.userId
/** /**
* This method allow to open a session. It does start some service on the background. * This method allow to open a session. It does start some service on the background.
*/ */
@ -140,6 +140,9 @@ interface Session :
*/ */
fun onInvalidToken() fun onInvalidToken()
/**
* A M_CONSENT_NOT_GIVEN error has been received from the homeserver
*/
fun onConsentNotGivenError(consentNotGivenError: ConsentNotGivenError)
} }
} }

View File

@ -27,5 +27,4 @@ interface CacheService {
* Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again * Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again
*/ */
fun clearCache(callback: MatrixCallback<Unit>) fun clearCache(callback: MatrixCallback<Unit>)
} }

View File

@ -17,6 +17,7 @@
package im.vector.matrix.android.api.session.content package im.vector.matrix.android.api.session.content
import android.os.Parcelable import android.os.Parcelable
import androidx.exifinterface.media.ExifInterface
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
@Parcelize @Parcelize
@ -26,6 +27,7 @@ data class ContentAttachmentData(
val date: Long = 0, val date: Long = 0,
val height: Long? = 0, val height: Long? = 0,
val width: Long? = 0, val width: Long? = 0,
val exifOrientation: Int = ExifInterface.ORIENTATION_UNDEFINED,
val name: String? = null, val name: String? = null,
val path: String, val path: String,
val mimeType: String, val mimeType: String,
@ -38,5 +40,4 @@ data class ContentAttachmentData(
AUDIO, AUDIO,
VIDEO VIDEO
} }
} }

View File

@ -112,5 +112,4 @@ interface CryptoService {
fun addNewSessionListener(newSessionListener: NewSessionListener) fun addNewSessionListener(newSessionListener: NewSessionListener)
fun removeSessionListener(listener: NewSessionListener) fun removeSessionListener(listener: NewSessionListener)
} }

View File

@ -210,5 +210,4 @@ interface KeysBackupService {
val isEnabled: Boolean val isEnabled: Boolean
val isStucked: Boolean val isStucked: Boolean
val state: KeysBackupState val state: KeysBackupState
} }

View File

@ -81,7 +81,6 @@ data class Event(
@Json(name = "redacts") val redacts: String? = null @Json(name = "redacts") val redacts: String? = null
) { ) {
@Transient @Transient
var mxDecryptionResult: OlmDecryptionResult? = null var mxDecryptionResult: OlmDecryptionResult? = null
@ -91,7 +90,6 @@ data class Event(
@Transient @Transient
var sendState: SendState = SendState.UNKNOWN var sendState: SendState = SendState.UNKNOWN
/** /**
* Check if event is a state event. * Check if event is a state event.
* @return true if event is state event. * @return true if event is state event.
@ -136,6 +134,7 @@ data class Event(
* @return the event content * @return the event content
*/ */
fun getClearContent(): Content? { fun getClearContent(): Content? {
@Suppress("UNCHECKED_CAST")
return mxDecryptionResult?.payload?.get("content") as? Content ?: content return mxDecryptionResult?.payload?.get("content") as? Content ?: content
} }
@ -194,10 +193,8 @@ data class Event(
result = 31 * result + sendState.hashCode() result = 31 * result + sendState.hashCode()
return result return result
} }
} }
fun Event.isTextMessage(): Boolean { fun Event.isTextMessage(): Boolean {
return getClearType() == EventType.MESSAGE return getClearType() == EventType.MESSAGE
&& when (getClearContent()?.toModel<MessageContent>()?.type) { && when (getClearContent()?.toModel<MessageContent>()?.type) {

View File

@ -16,7 +16,6 @@
package im.vector.matrix.android.api.session.events.model package im.vector.matrix.android.api.session.events.model
/** /**
* Constants defining known event types from Matrix specifications. * Constants defining known event types from Matrix specifications.
*/ */
@ -93,7 +92,6 @@ object EventType {
STATE_PINNED_EVENT STATE_PINNED_EVENT
) )
fun isStateEvent(type: String): Boolean { fun isStateEvent(type: String): Boolean {
return STATE_EVENTS.contains(type) return STATE_EVENTS.contains(type)
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.matrix.android.api.session.events.model package im.vector.matrix.android.api.session.events.model
/** /**
* Constants defining known event relation types from Matrix specifications * Constants defining known event relation types from Matrix specifications
*/ */
@ -27,5 +26,4 @@ object RelationType {
const val REPLACE = "m.replace" const val REPLACE = "m.replace"
/** Lets you define an event which references an existing event.*/ /** Lets you define an event which references an existing event.*/
const val REFERENCE = "m.reference" const val REFERENCE = "m.reference"
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.matrix.android.api.session.events.model package im.vector.matrix.android.api.session.events.model
interface UnsignedRelationInfo { interface UnsignedRelationInfo {
val limited : Boolean? val limited : Boolean?
val count: Int? val count: Int?

View File

@ -20,7 +20,6 @@ import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
import java.io.File import java.io.File
/** /**
* This interface defines methods to get files. * This interface defines methods to get files.
*/ */

View File

@ -19,7 +19,6 @@ package im.vector.matrix.android.api.session.group
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.group.model.GroupSummary
/** /**
* This interface defines methods to get groups. It's implemented at the session level. * This interface defines methods to get groups. It's implemented at the session level.
*/ */

View File

@ -25,5 +25,4 @@ interface HomeServerCapabilitiesService {
* Get the HomeServer capabilities * Get the HomeServer capabilities
*/ */
fun getHomeServerCapabilities(): HomeServerCapabilities fun getHomeServerCapabilities(): HomeServerCapabilities
} }

View File

@ -19,7 +19,6 @@ import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import java.util.UUID import java.util.UUID
interface PushersService { interface PushersService {
/** /**
@ -53,7 +52,6 @@ interface PushersService {
append: Boolean, append: Boolean,
withEventIdOnly: Boolean): UUID withEventIdOnly: Boolean): UUID
fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>) fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>)
companion object { companion object {

View File

@ -53,5 +53,4 @@ interface Room :
fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>> fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>>
fun roomSummary(): RoomSummary? fun roomSummary(): RoomSummary?
} }

View File

@ -42,5 +42,4 @@ interface RoomDirectoryService {
* Includes both the available protocols and all fields required for queries against each protocol. * Includes both the available protocols and all fields required for queries against each protocol.
*/ */
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
} }

View File

@ -53,5 +53,4 @@ interface RoomService {
* @return the [LiveData] of [RoomSummary] * @return the [LiveData] of [RoomSummary]
*/ */
fun liveRoomSummaries(): LiveData<List<RoomSummary>> fun liveRoomSummaries(): LiveData<List<RoomSummary>>
} }

View File

@ -21,5 +21,4 @@ import im.vector.matrix.android.api.failure.Failure
sealed class CreateRoomFailure : Failure.FeatureFailure() { sealed class CreateRoomFailure : Failure.FeatureFailure() {
object CreatedWithTimeout: CreateRoomFailure() object CreatedWithTimeout: CreateRoomFailure()
} }

View File

@ -21,5 +21,4 @@ import im.vector.matrix.android.api.failure.Failure
sealed class JoinRoomFailure : Failure.FeatureFailure() { sealed class JoinRoomFailure : Failure.FeatureFailure() {
object JoinedWithTimeout : JoinRoomFailure() object JoinedWithTimeout : JoinRoomFailure()
} }

View File

@ -64,5 +64,4 @@ interface MembershipService {
* Leave the room, or reject an invitation. * Leave the room, or reject an invitation.
*/ */
fun leave(callback: MatrixCallback<Unit>): Cancelable fun leave(callback: MatrixCallback<Unit>): Cancelable
} }

View File

@ -43,5 +43,4 @@ enum class Membership(val value: String) {
fun isLeft(): Boolean { fun isLeft(): Boolean {
return this == KNOCK || this == LEAVE || this == BAN return this == KNOCK || this == LEAVE || this == BAN
} }
} }

View File

@ -78,7 +78,6 @@ data class PowerLevels(
return if (!TextUtils.isEmpty(eventTypeString) && !TextUtils.isEmpty(userId)) { return if (!TextUtils.isEmpty(eventTypeString) && !TextUtils.isEmpty(userId)) {
getUserPowerLevel(userId) >= minimumPowerLevelForSendingEventAsMessage(eventTypeString) getUserPowerLevel(userId) >= minimumPowerLevelForSendingEventAsMessage(eventTypeString)
} else false } else false
} }
/** /**
@ -113,7 +112,6 @@ data class PowerLevels(
return events[eventTypeString] ?: stateDefault return events[eventTypeString] ?: stateDefault
} }
/** /**
* Get the notification level for a dedicated key. * Get the notification level for a dedicated key.
* *

View File

@ -48,4 +48,3 @@ data class RoomSummary(
val hasNewMessages: Boolean val hasNewMessages: Boolean
get() = notificationCount != 0 get() = notificationCount != 0
} }

View File

@ -31,5 +31,4 @@ data class CallAnswerContent(
@Json(name = "type") val type: String, @Json(name = "type") val type: String,
@Json(name = "sdp") val sdp: String @Json(name = "sdp") val sdp: String
) )
} }

View File

@ -32,5 +32,4 @@ data class CallCandidatesContent(
@Json(name = "sdpMLineIndex") val sdpMLineIndex: String, @Json(name = "sdpMLineIndex") val sdpMLineIndex: String,
@Json(name = "candidate") val candidate: String @Json(name = "candidate") val candidate: String
) )
} }

View File

@ -37,6 +37,5 @@ data class CallInviteContent(
} }
} }
fun isVideo(): Boolean = offer.sdp.contains(Offer.SDP_VIDEO) fun isVideo(): Boolean = offer.sdp.contains(Offer.SDP_VIDEO)
} }

View File

@ -28,5 +28,3 @@ data class RoomCreateContent(
@Json(name = "room_version") val roomVersion: String? = null, @Json(name = "room_version") val roomVersion: String? = null,
@Json(name = "predecessor") val predecessor: Predecessor? = null @Json(name = "predecessor") val predecessor: Predecessor? = null
) )

View File

@ -42,16 +42,6 @@ data class ImageInfo(
*/ */
@Json(name = "size") val size: Int = 0, @Json(name = "size") val size: Int = 0,
/**
* Not documented
*/
@Json(name = "rotation") val rotation: Int = 0,
/**
* Not documented
*/
@Json(name = "orientation") val orientation: Int = 0,
/** /**
* Metadata about the image referred to in thumbnail_url. * Metadata about the image referred to in thumbnail_url.
*/ */

View File

@ -19,7 +19,6 @@ package im.vector.matrix.android.api.session.room.model.message
import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
interface MessageContent { interface MessageContent {
val type: String val type: String
val body: String val body: String
@ -27,7 +26,6 @@ interface MessageContent {
val newContent: Content? val newContent: Content?
} }
fun MessageContent?.isReply(): Boolean { fun MessageContent?.isReply(): Boolean {
return this?.relatesTo?.inReplyTo?.eventId != null return this?.relatesTo?.inReplyTo?.eventId != null
} }

View File

@ -18,7 +18,6 @@ package im.vector.matrix.android.api.session.room.model.message
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
/** /**
* Interface for message which can contains an encrypted file * Interface for message which can contains an encrypted file
*/ */

View File

@ -48,7 +48,6 @@ import im.vector.matrix.android.api.util.Optional
*/ */
interface RelationService { interface RelationService {
/** /**
* Sends a reaction (emoji) to the targetedEvent. * Sends a reaction (emoji) to the targetedEvent.
* @param reaction the reaction (preferably emoji) * @param reaction the reaction (preferably emoji)
@ -57,7 +56,6 @@ interface RelationService {
fun sendReaction(reaction: String, fun sendReaction(reaction: String,
targetEventId: String): Cancelable targetEventId: String): Cancelable
/** /**
* Undo a reaction (emoji) to the targetedEvent. * Undo a reaction (emoji) to the targetedEvent.
* @param reaction the reaction (preferably emoji) * @param reaction the reaction (preferably emoji)
@ -68,7 +66,6 @@ interface RelationService {
targetEventId: String, targetEventId: String,
myUserId: String) // : Cancelable myUserId: String) // : Cancelable
/** /**
* Edit a text message body. Limited to "m.text" contentType * Edit a text message body. Limited to "m.text" contentType
* @param targetEventId The event to edit * @param targetEventId The event to edit
@ -81,7 +78,6 @@ interface RelationService {
newBodyAutoMarkdown: Boolean, newBodyAutoMarkdown: Boolean,
compatibilityBodyText: String = "* $newBodyText"): Cancelable compatibilityBodyText: String = "* $newBodyText"): Cancelable
/** /**
* Edit a reply. This is a special case because replies contains fallback text as a prefix. * Edit a reply. This is a special case because replies contains fallback text as a prefix.
* This method will take the new body (stripped from fallbacks) and re-add them before sending. * This method will take the new body (stripped from fallbacks) and re-add them before sending.
@ -100,7 +96,6 @@ interface RelationService {
*/ */
fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>) fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>)
/** /**
* Reply to an event in the timeline (must be in same room) * Reply to an event in the timeline (must be in same room)
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id350 * https://matrix.org/docs/spec/client_server/r0.4.0.html#id350
@ -113,6 +108,4 @@ interface RelationService {
autoMarkdown: Boolean = false): Cancelable? autoMarkdown: Boolean = false): Cancelable?
fun getEventSummaryLive(eventId: String): LiveData<Optional<EventAnnotationsSummary>> fun getEventSummaryLive(eventId: String): LiveData<Optional<EventAnnotationsSummary>>
} }

View File

@ -27,5 +27,4 @@ data class RoomTag(
val ROOM_TAG_NO_TAG = "m.recent" val ROOM_TAG_NO_TAG = "m.recent"
val ROOM_TAG_SERVER_NOTICE = "m.server_notice" val ROOM_TAG_SERVER_NOTICE = "m.server_notice"
} }
} }

View File

@ -51,5 +51,4 @@ data class RoomDirectoryData(
companion object { companion object {
const val DEFAULT_HOME_SERVER_NAME = "Matrix" const val DEFAULT_HOME_SERVER_NAME = "Matrix"
} }
} }

View File

@ -51,7 +51,6 @@ data class ThirdPartyProtocolInstance(
@Json(name = "instance_id") @Json(name = "instance_id")
var instanceId: String? = null, var instanceId: String? = null,
/** /**
* FIXDOC Not documented on matrix.org doc * FIXDOC Not documented on matrix.org doc
*/ */

View File

@ -35,5 +35,4 @@ interface DraftService {
* The draft list can contain one draft for {regular, reply, quote} and an arbitrary number of {edit} drafts * The draft list can contain one draft for {regular, reply, quote} and an arbitrary number of {edit} drafts
*/ */
fun getDraftsLive(): LiveData<List<UserDraft>> fun getDraftsLive(): LiveData<List<UserDraft>>
} }

View File

@ -22,7 +22,6 @@ import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
/** /**
* This interface defines methods to send events in a room. It's implemented at the room level. * This interface defines methods to send events in a room. It's implemented at the room level.
*/ */
@ -66,7 +65,6 @@ interface SendService {
*/ */
fun redactEvent(event: Event, reason: String?): Cancelable fun redactEvent(event: Event, reason: String?): Cancelable
/** /**
* Schedule this message to be resent * Schedule this message to be resent
* @param localEcho the unsent local echo * @param localEcho the unsent local echo
@ -79,7 +77,6 @@ interface SendService {
*/ */
fun resendMediaMessage(localEcho: TimelineEvent): Cancelable? fun resendMediaMessage(localEcho: TimelineEvent): Cancelable?
/** /**
* Remove this failed message from the timeline * Remove this failed message from the timeline
* @param localEcho the unsent local echo * @param localEcho the unsent local echo
@ -92,5 +89,4 @@ interface SendService {
* Resend all failed messages one by one (and keep order) * Resend all failed messages one by one (and keep order)
*/ */
fun resendAllFailedMessages() fun resendAllFailedMessages()
} }

View File

@ -16,7 +16,6 @@
package im.vector.matrix.android.api.session.room.send package im.vector.matrix.android.api.session.room.send
enum class SendState { enum class SendState {
UNKNOWN, UNKNOWN,
// the event has not been sent // the event has not been sent
@ -46,7 +45,4 @@ enum class SendState {
fun hasFailed() = HAS_FAILED_STATES.contains(this) fun hasFailed() = HAS_FAILED_STATES.contains(this)
fun isSending() = IS_SENDING_STATES.contains(this) fun isSending() = IS_SENDING_STATES.contains(this)
} }

View File

@ -27,5 +27,4 @@ interface StateService {
fun updateTopic(topic: String, callback: MatrixCallback<Unit>) fun updateTopic(topic: String, callback: MatrixCallback<Unit>)
fun getStateEvent(eventType: String): Event? fun getStateEvent(eventType: String): Event?
} }

View File

@ -50,7 +50,6 @@ interface Timeline {
*/ */
fun restartWithEventId(eventId: String?) fun restartWithEventId(eventId: String?)
/** /**
* Check if the timeline can be enriched by paginating. * Check if the timeline can be enriched by paginating.
* @param the direction to check in * @param the direction to check in
@ -58,7 +57,6 @@ interface Timeline {
*/ */
fun hasMoreToLoad(direction: Direction): Boolean fun hasMoreToLoad(direction: Direction): Boolean
/** /**
* This is the main method to enrich the timeline with new data. * This is the main method to enrich the timeline with new data.
* It will call the onUpdated method from [Listener] when the data will be processed. * It will call the onUpdated method from [Listener] when the data will be processed.
@ -97,7 +95,6 @@ interface Timeline {
*/ */
fun getFirstDisplayableEventId(eventId: String): String? fun getFirstDisplayableEventId(eventId: String): String?
interface Listener { interface Listener {
/** /**
* Call when the timeline has been updated through pagination or sync. * Call when the timeline has been updated through pagination or sync.
@ -119,5 +116,4 @@ interface Timeline {
*/ */
BACKWARDS BACKWARDS
} }
} }

View File

@ -88,7 +88,6 @@ data class TimelineEvent(
} }
} }
/** /**
* Tells if the event has been edited * Tells if the event has been edited
*/ */
@ -107,7 +106,6 @@ fun TimelineEvent.getEditedEventId(): String? {
fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel() fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel()
?: root.getClearContent().toModel() ?: root.getClearContent().toModel()
/** /**
* Get last Message body, after a possible edition * Get last Message body, after a possible edition
*/ */
@ -121,7 +119,6 @@ fun TimelineEvent.getLastMessageBody(): String? {
return null return null
} }
fun TimelineEvent.getTextEditableContent(): String? { fun TimelineEvent.getTextEditableContent(): String? {
val originalContent = root.getClearContent().toModel<MessageContent>() ?: return null val originalContent = root.getClearContent().toModel<MessageContent>() ?: return null
val isReply = originalContent.isReply() || root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId != null val isReply = originalContent.isReply() || root.content.toModel<EncryptedEventContent>()?.relatesTo?.inReplyTo?.eventId != null

View File

@ -33,9 +33,7 @@ interface TimelineService {
*/ */
fun createTimeline(eventId: String?, settings: TimelineSettings): Timeline fun createTimeline(eventId: String?, settings: TimelineSettings): Timeline
fun getTimeLineEvent(eventId: String): TimelineEvent? fun getTimeLineEvent(eventId: String): TimelineEvent?
fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>> fun getTimeLineEventLive(eventId: String): LiveData<Optional<TimelineEvent>>
} }

View File

@ -24,5 +24,4 @@ interface SecureStorageService {
fun securelyStoreObject(any: Any, keyAlias: String, outputStream: OutputStream) fun securelyStoreObject(any: Any, keyAlias: String, outputStream: OutputStream)
fun <T> loadSecureSecret(inputStream: InputStream, keyAlias: String): T? fun <T> loadSecureSecret(inputStream: InputStream, keyAlias: String): T?
} }

View File

@ -27,5 +27,4 @@ interface SignOutService {
* Sign out * Sign out
*/ */
fun signOut(callback: MatrixCallback<Unit>) fun signOut(callback: MatrixCallback<Unit>)
} }

View File

@ -64,5 +64,4 @@ interface UserService {
* @return a Livedata of users * @return a Livedata of users
*/ */
fun livePagedUsers(filter: String? = null): LiveData<PagedList<User>> fun livePagedUsers(filter: String? = null): LiveData<PagedList<User>>
} }

View File

@ -29,4 +29,3 @@ interface Cancelable {
// no-op // no-op
} }
} }

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.matrix.android.api.util package im.vector.matrix.android.api.util
object ContentUtils { object ContentUtils {
fun extractUsefulTextFromReply(repliedBody: String): String { fun extractUsefulTextFromReply(repliedBody: String): String {
val lines = repliedBody.lines() val lines = repliedBody.lines()
@ -39,9 +38,10 @@ object ContentUtils {
fun extractUsefulTextFromHtmlReply(repliedBody: String): String { fun extractUsefulTextFromHtmlReply(repliedBody: String): String {
if (repliedBody.startsWith("<mx-reply>")) { if (repliedBody.startsWith("<mx-reply>")) {
val closingTagIndex = repliedBody.lastIndexOf("</mx-reply>") val closingTagIndex = repliedBody.lastIndexOf("</mx-reply>")
if (closingTagIndex != -1) if (closingTagIndex != -1) {
return repliedBody.substring(closingTagIndex + "</mx-reply>".length).trim() return repliedBody.substring(closingTagIndex + "</mx-reply>".length).trim()
} }
}
return repliedBody return repliedBody
} }
} }

View File

@ -40,7 +40,6 @@ data class Optional<T : Any> constructor(private val value: T?) {
return Optional(value) return Optional(value)
} }
} }
} }
fun <T : Any> T?.toOptional() = Optional(this) fun <T : Any> T?.toOptional() = Optional(this)

View File

@ -47,5 +47,4 @@ internal interface AuthAPI {
@Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000") @Headers("CONNECT_TIMEOUT:60000", "READ_TIMEOUT:60000", "WRITE_TIMEOUT:60000")
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login") @POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "login")
fun login(@Body loginParams: PasswordLoginParams): Call<Credentials> fun login(@Body loginParams: PasswordLoginParams): Call<Credentials>
} }

View File

@ -55,11 +55,9 @@ internal abstract class AuthModule {
} }
} }
@Binds @Binds
abstract fun bindSessionParamsStore(sessionParamsStore: RealmSessionParamsStore): SessionParamsStore abstract fun bindSessionParamsStore(sessionParamsStore: RealmSessionParamsStore): SessionParamsStore
@Binds @Binds
abstract fun bindAuthenticator(authenticator: DefaultAuthenticator): Authenticator abstract fun bindAuthenticator(authenticator: DefaultAuthenticator): Authenticator
} }

View File

@ -98,7 +98,6 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, private suspend fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig,
login: String, login: String,
password: String) = withContext(coroutineDispatchers.io) { password: String) = withContext(coroutineDispatchers.io) {
val authAPI = buildAuthAPI(homeServerConnectionConfig) val authAPI = buildAuthAPI(homeServerConnectionConfig)
val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) { val loginParams = if (Patterns.EMAIL_ADDRESS.matcher(login).matches()) {
PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, "Mobile") PasswordLoginParams.thirdPartyIdentifier(ThreePidMedium.EMAIL, login, password, "Mobile")
@ -123,6 +122,4 @@ internal class DefaultAuthenticator @Inject constructor(@Unauthenticated
val retrofit = retrofitFactory.create(okHttpClient.get(), homeServerConnectionConfig.homeServerUri.toString()) val retrofit = retrofitFactory.create(okHttpClient.get(), homeServerConnectionConfig.homeServerUri.toString())
return retrofit.create(AuthAPI::class.java) return retrofit.create(AuthAPI::class.java)
} }
} }

View File

@ -26,7 +26,6 @@ internal data class PasswordLoginParams(@Json(name = "identifier") val identifie
@Json(name = "initial_device_display_name") val deviceDisplayName: String?, @Json(name = "initial_device_display_name") val deviceDisplayName: String?,
@Json(name = "device_id") val deviceId: String?) : LoginParams { @Json(name = "device_id") val deviceId: String?) : LoginParams {
companion object { companion object {
val IDENTIFIER_KEY_TYPE_USER = "m.id.user" val IDENTIFIER_KEY_TYPE_USER = "m.id.user"
@ -40,7 +39,6 @@ internal data class PasswordLoginParams(@Json(name = "identifier") val identifie
val IDENTIFIER_KEY_COUNTRY = "country" val IDENTIFIER_KEY_COUNTRY = "country"
val IDENTIFIER_KEY_NUMBER = "number" val IDENTIFIER_KEY_NUMBER = "number"
fun userIdentifier(user: String, fun userIdentifier(user: String,
password: String, password: String,
deviceDisplayName: String? = null, deviceDisplayName: String? = null,
@ -49,7 +47,6 @@ internal data class PasswordLoginParams(@Json(name = "identifier") val identifie
identifier[IDENTIFIER_KEY_TYPE] = IDENTIFIER_KEY_TYPE_USER identifier[IDENTIFIER_KEY_TYPE] = IDENTIFIER_KEY_TYPE_USER
identifier[IDENTIFIER_KEY_USER] = user identifier[IDENTIFIER_KEY_USER] = user
return PasswordLoginParams(identifier, password, LoginFlowTypes.PASSWORD, deviceDisplayName, deviceId) return PasswordLoginParams(identifier, password, LoginFlowTypes.PASSWORD, deviceDisplayName, deviceId)
} }
fun thirdPartyIdentifier(medium: String, fun thirdPartyIdentifier(medium: String,
@ -62,7 +59,6 @@ internal data class PasswordLoginParams(@Json(name = "identifier") val identifie
identifier[IDENTIFIER_KEY_MEDIUM] = medium identifier[IDENTIFIER_KEY_MEDIUM] = medium
identifier[IDENTIFIER_KEY_ADDRESS] = address identifier[IDENTIFIER_KEY_ADDRESS] = address
return PasswordLoginParams(identifier, password, LoginFlowTypes.PASSWORD, deviceDisplayName, deviceId) return PasswordLoginParams(identifier, password, LoginFlowTypes.PASSWORD, deviceDisplayName, deviceId)
} }
} }
} }

View File

@ -99,5 +99,4 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
realm.close() realm.close()
} }
} }
} }

View File

@ -50,6 +50,4 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
} }
return SessionParamsEntity(sessionParams.credentials.userId, credentialsJson, homeServerConnectionConfigJson) return SessionParamsEntity(sessionParams.credentials.userId, credentialsJson, homeServerConnectionConfigJson)
} }
} }

View File

@ -74,7 +74,6 @@ internal abstract class CryptoModule {
return RealmClearCacheTask(realmConfiguration) return RealmClearCacheTask(realmConfiguration)
} }
@JvmStatic @JvmStatic
@Provides @Provides
fun providesCryptoStore(@CryptoDatabase fun providesCryptoStore(@CryptoDatabase
@ -104,7 +103,6 @@ internal abstract class CryptoModule {
fun providesCryptoConfig(): MXCryptoConfig { fun providesCryptoConfig(): MXCryptoConfig {
return MXCryptoConfig() return MXCryptoConfig()
} }
} }
@Binds @Binds

View File

@ -31,9 +31,7 @@ import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.listeners.ProgressListener import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
import im.vector.matrix.android.api.session.events.model.Content import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
@ -289,24 +287,18 @@ internal class DefaultCryptoService @Inject constructor(
outgoingRoomKeyRequestManager.stop() outgoingRoomKeyRequestManager.stop()
} }
override fun isCryptoEnabled(): Boolean { // Aways enabled on RiotX
// TODO Check that this test is correct override fun isCryptoEnabled() = true
return olmDevice != null
}
/** /**
* @return the Keys backup Service * @return the Keys backup Service
*/ */
override fun getKeysBackupService(): KeysBackupService { override fun getKeysBackupService() = keysBackup
return keysBackup
}
/** /**
* @return the SasVerificationService * @return the SasVerificationService
*/ */
override fun getSasVerificationService(): SasVerificationService { override fun getSasVerificationService() = sasVerificationService
return sasVerificationService
}
/** /**
* A sync response has been received * A sync response has been received
@ -406,7 +398,6 @@ internal class DefaultCryptoService @Inject constructor(
} }
} }
callback?.onSuccess(Unit) callback?.onSuccess(Unit)
} }
@ -446,7 +437,7 @@ internal class DefaultCryptoService @Inject constructor(
val encryptingClass = MXCryptoAlgorithms.hasEncryptorClassForAlgorithm(algorithm) val encryptingClass = MXCryptoAlgorithms.hasEncryptorClassForAlgorithm(algorithm)
if (!encryptingClass) { if (!encryptingClass) {
Timber.e("## setEncryptionInRoom() : Unable to encrypt room ${roomId} with $algorithm") Timber.e("## setEncryptionInRoom() : Unable to encrypt room $roomId with $algorithm")
return false return false
} }
@ -714,7 +705,6 @@ internal class DefaultCryptoService @Inject constructor(
} else { } else {
RoomMembers(realm, roomId).getJoinedRoomMemberIds() RoomMembers(realm, roomId).getJoinedRoomMemberIds()
} }
} }
return userIds return userIds
} }
@ -761,7 +751,6 @@ internal class DefaultCryptoService @Inject constructor(
} }
} }
/** /**
* Upload my user's device keys. * Upload my user's device keys.
*/ */
@ -945,7 +934,6 @@ internal class DefaultCryptoService @Inject constructor(
cryptoStore.setRoomsListBlacklistUnverifiedDevices(roomIds) cryptoStore.setRoomsListBlacklistUnverifiedDevices(roomIds)
} }
/** /**
* Add this room to the ones which don't encrypt messages to unverified devices. * Add this room to the ones which don't encrypt messages to unverified devices.
* *

View File

@ -74,7 +74,6 @@ internal class DeviceListManager @Inject constructor(private val cryptoStore: IM
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## canRetryKeysDownload() failed") Timber.e(e, "## canRetryKeysDownload() failed")
} }
} }
return res return res

View File

@ -17,7 +17,6 @@
package im.vector.matrix.android.internal.crypto package im.vector.matrix.android.internal.crypto
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toModel import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody import im.vector.matrix.android.internal.crypto.model.rest.RoomKeyRequestBody
@ -77,4 +76,3 @@ open class IncomingRoomKeyRequest {
*/ */
constructor() constructor()
} }

View File

@ -35,7 +35,6 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
private val cryptoStore: IMXCryptoStore, private val cryptoStore: IMXCryptoStore,
private val roomDecryptorProvider: RoomDecryptorProvider) { private val roomDecryptorProvider: RoomDecryptorProvider) {
// list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations // list of IncomingRoomKeyRequests/IncomingRoomKeyRequestCancellations
// we received in the current sync. // we received in the current sync.
private val receivedRoomKeyRequests = ArrayList<IncomingRoomKeyRequest>() private val receivedRoomKeyRequests = ArrayList<IncomingRoomKeyRequest>()
@ -166,12 +165,10 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## onRoomKeyRequest() failed") Timber.e(e, "## onRoomKeyRequest() failed")
} }
} }
} }
} }
/** /**
* A room key request cancellation has been received. * A room key request cancellation has been received.
* *
@ -185,7 +182,6 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## onRoomKeyRequestCancellation() failed") Timber.e(e, "## onRoomKeyRequestCancellation() failed")
} }
} }
} }
} }
@ -201,5 +197,4 @@ internal class IncomingRoomKeyRequestManager @Inject constructor(
roomKeysRequestListeners.remove(listener) roomKeysRequestListeners.remove(listener)
} }
} }
} }

View File

@ -94,7 +94,6 @@ internal class MXOlmDevice @Inject constructor(
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "MXOlmDevice : cannot initialize olmAccount") Timber.e(e, "MXOlmDevice : cannot initialize olmAccount")
} }
} else { } else {
Timber.v("MXOlmDevice : use an existing account") Timber.v("MXOlmDevice : use an existing account")
} }
@ -217,7 +216,6 @@ internal class MXOlmDevice @Inject constructor(
Timber.v("## createOutboundSession() ; olmSession.sessionIdentifier: $sessionIdentifier") Timber.v("## createOutboundSession() ; olmSession.sessionIdentifier: $sessionIdentifier")
return sessionIdentifier return sessionIdentifier
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## createOutboundSession() failed") Timber.e(e, "## createOutboundSession() failed")
@ -236,7 +234,6 @@ internal class MXOlmDevice @Inject constructor(
* @return {{payload: string, session_id: string}} decrypted payload, and session id of new session. * @return {{payload: string, session_id: string}} decrypted payload, and session id of new session.
*/ */
fun createInboundSession(theirDeviceIdentityKey: String, messageType: Int, ciphertext: String): Map<String, String>? { fun createInboundSession(theirDeviceIdentityKey: String, messageType: Int, ciphertext: String): Map<String, String>? {
Timber.v("## createInboundSession() : theirIdentityKey: $theirDeviceIdentityKey") Timber.v("## createInboundSession() : theirIdentityKey: $theirDeviceIdentityKey")
var olmSession: OlmSession? = null var olmSession: OlmSession? = null
@ -250,7 +247,7 @@ internal class MXOlmDevice @Inject constructor(
return null return null
} }
Timber.v("## createInboundSession() : sessionId: " + olmSession.sessionIdentifier()) Timber.v("## createInboundSession() : sessionId: ${olmSession.sessionIdentifier()}")
try { try {
olmAccount!!.removeOneTimeKeys(olmSession) olmAccount!!.removeOneTimeKeys(olmSession)
@ -262,7 +259,7 @@ internal class MXOlmDevice @Inject constructor(
Timber.v("## createInboundSession() : ciphertext: $ciphertext") Timber.v("## createInboundSession() : ciphertext: $ciphertext")
try { try {
val sha256 = olmUtility!!.sha256(URLEncoder.encode(ciphertext, "utf-8")) val sha256 = olmUtility!!.sha256(URLEncoder.encode(ciphertext, "utf-8"))
Timber.v("## createInboundSession() :ciphertext: SHA256:" + sha256) Timber.v("## createInboundSession() :ciphertext: SHA256: $sha256")
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## createInboundSession() :ciphertext: cannot encode ciphertext") Timber.e(e, "## createInboundSession() :ciphertext: cannot encode ciphertext")
} }
@ -352,9 +349,8 @@ internal class MXOlmDevice @Inject constructor(
res["body"] = olmMessage.mCipherText res["body"] = olmMessage.mCipherText
res["type"] = olmMessage.mType res["type"] = olmMessage.mType
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## encryptMessage() : failed " + e.message) Timber.e(e, "## encryptMessage() : failed")
} }
} }
return res return res
@ -384,9 +380,8 @@ internal class MXOlmDevice @Inject constructor(
olmSessionWrapper.onMessageReceived() olmSessionWrapper.onMessageReceived()
store.storeSession(olmSessionWrapper, theirDeviceIdentityKey) store.storeSession(olmSessionWrapper, theirDeviceIdentityKey)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## decryptMessage() : decryptMessage failed " + e.message) Timber.e(e, "## decryptMessage() : decryptMessage failed")
} }
} }
return payloadString return payloadString
@ -410,7 +405,6 @@ internal class MXOlmDevice @Inject constructor(
return null != olmSessionWrapper && olmSessionWrapper.olmSession.matchesInboundSession(ciphertext) return null != olmSessionWrapper && olmSessionWrapper.olmSession.matchesInboundSession(ciphertext)
} }
// Outbound group session // Outbound group session
/** /**
@ -425,7 +419,7 @@ internal class MXOlmDevice @Inject constructor(
outboundGroupSessionStore[session.sessionIdentifier()] = session outboundGroupSessionStore[session.sessionIdentifier()] = session
return session.sessionIdentifier() return session.sessionIdentifier()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "createOutboundGroupSession " + e.message) Timber.e(e, "createOutboundGroupSession")
session?.releaseSession() session?.releaseSession()
} }
@ -444,9 +438,8 @@ internal class MXOlmDevice @Inject constructor(
try { try {
return outboundGroupSessionStore[sessionId]!!.sessionKey() return outboundGroupSessionStore[sessionId]!!.sessionKey()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## getSessionKey() : failed " + e.message) Timber.e(e, "## getSessionKey() : failed")
} }
} }
return null return null
} }
@ -475,9 +468,8 @@ internal class MXOlmDevice @Inject constructor(
try { try {
return outboundGroupSessionStore[sessionId]!!.encryptMessage(payloadString) return outboundGroupSessionStore[sessionId]!!.encryptMessage(payloadString)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "## encryptGroupMessage() : failed " + e.message) Timber.e(e, "## encryptGroupMessage() : failed")
} }
} }
return null return null
} }
@ -562,7 +554,6 @@ internal class MXOlmDevice @Inject constructor(
val sessions = ArrayList<OlmInboundGroupSessionWrapper>(megolmSessionsData.size) val sessions = ArrayList<OlmInboundGroupSessionWrapper>(megolmSessionsData.size)
for (megolmSessionData in megolmSessionsData) { for (megolmSessionData in megolmSessionsData) {
val sessionId = megolmSessionData.sessionId val sessionId = megolmSessionData.sessionId
val senderKey = megolmSessionData.senderKey val senderKey = megolmSessionData.senderKey
val roomId = megolmSessionData.roomId val roomId = megolmSessionData.roomId
@ -583,7 +574,7 @@ internal class MXOlmDevice @Inject constructor(
try { try {
if (!TextUtils.equals(session.olmInboundGroupSession?.sessionIdentifier(), sessionId)) { if (!TextUtils.equals(session.olmInboundGroupSession?.sessionIdentifier(), sessionId)) {
Timber.e("## importInboundGroupSession : ERROR: Mismatched group session ID from senderKey: " + senderKey!!) Timber.e("## importInboundGroupSession : ERROR: Mismatched group session ID from senderKey: $senderKey")
if (session.olmInboundGroupSession != null) session.olmInboundGroupSession!!.releaseSession() if (session.olmInboundGroupSession != null) session.olmInboundGroupSession!!.releaseSession()
continue continue
} }
@ -652,9 +643,8 @@ internal class MXOlmDevice @Inject constructor(
// Check that the room id matches the original one for the session. This stops // Check that the room id matches the original one for the session. This stops
// the HS pretending a message was targeting a different room. // the HS pretending a message was targeting a different room.
if (roomId == session.roomId) { if (roomId == session.roomId) {
var decryptResult: OlmInboundGroupSession.DecryptMessageResult? = null val decryptResult = try {
try { session.olmInboundGroupSession!!.decryptMessage(body)
decryptResult = session.olmInboundGroupSession!!.decryptMessage(body)
} catch (e: OlmException) { } catch (e: OlmException) {
Timber.e(e, "## decryptGroupMessage () : decryptMessage failed") Timber.e(e, "## decryptGroupMessage () : decryptMessage failed")
throw MXCryptoError.OlmError(e) throw MXCryptoError.OlmError(e)
@ -747,7 +737,6 @@ internal class MXOlmDevice @Inject constructor(
return if (theirDeviceIdentityKey.isEmpty() || sessionId.isEmpty()) null else { return if (theirDeviceIdentityKey.isEmpty() || sessionId.isEmpty()) null else {
store.getDeviceSession(sessionId, theirDeviceIdentityKey) store.getDeviceSession(sessionId, theirDeviceIdentityKey)
} }
} }
/** /**

View File

@ -15,7 +15,6 @@
*/ */
package im.vector.matrix.android.internal.crypto package im.vector.matrix.android.internal.crypto
interface NewSessionListener { interface NewSessionListener {
fun onNewSession(roomId: String?, senderKey: String, sessionId: String) fun onNewSession(roomId: String?, senderKey: String, sessionId: String)
} }

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