Merge pull request #6929 from vector-im/feature/bma/android12
Target API 32 (Android 12)
This commit is contained in:
commit
151f6245db
|
@ -71,6 +71,14 @@ allprojects {
|
||||||
groups.mavenCentral.group.each { includeGroup it }
|
groups.mavenCentral.group.each { includeGroup it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// snapshots repository
|
||||||
|
maven {
|
||||||
|
url "https://oss.sonatype.org/content/repositories/snapshots"
|
||||||
|
content {
|
||||||
|
groups.snapshot.regex.each { includeGroupByRegex it }
|
||||||
|
groups.snapshot.group.each { includeGroup it }
|
||||||
|
}
|
||||||
|
}
|
||||||
maven {
|
maven {
|
||||||
url 'https://jitpack.io'
|
url 'https://jitpack.io'
|
||||||
content {
|
content {
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Target API 12 and compile with Android SDK 32.
|
|
@ -1,20 +1,17 @@
|
||||||
ext.versions = [
|
ext.versions = [
|
||||||
|
|
||||||
'minSdk' : 21,
|
'minSdk' : 21,
|
||||||
'compileSdk' : 31,
|
'compileSdk' : 32,
|
||||||
'targetSdk' : 31,
|
'targetSdk' : 32,
|
||||||
'sourceCompat' : JavaVersion.VERSION_11,
|
'sourceCompat' : JavaVersion.VERSION_11,
|
||||||
'targetCompat' : JavaVersion.VERSION_11,
|
'targetCompat' : JavaVersion.VERSION_11,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def gradle = "7.2.2"
|
||||||
// Pinned to 7.1.3 because of https://github.com/vector-im/element-android/issues/6142
|
|
||||||
// Please test carefully before upgrading again.
|
|
||||||
def gradle = "7.1.3"
|
|
||||||
// Ref: https://kotlinlang.org/releases.html
|
// Ref: https://kotlinlang.org/releases.html
|
||||||
def kotlin = "1.6.21"
|
def kotlin = "1.7.10"
|
||||||
def kotlinCoroutines = "1.6.4"
|
def kotlinCoroutines = "1.6.4"
|
||||||
def dagger = "2.42"
|
def dagger = "2.43.2"
|
||||||
def appDistribution = "16.0.0-beta04"
|
def appDistribution = "16.0.0-beta04"
|
||||||
def retrofit = "2.9.0"
|
def retrofit = "2.9.0"
|
||||||
def arrow = "0.8.2"
|
def arrow = "0.8.2"
|
||||||
|
@ -28,7 +25,9 @@ def mavericks = "2.7.0"
|
||||||
def glide = "4.13.2"
|
def glide = "4.13.2"
|
||||||
def bigImageViewer = "1.8.1"
|
def bigImageViewer = "1.8.1"
|
||||||
def jjwt = "0.11.5"
|
def jjwt = "0.11.5"
|
||||||
def vanniktechEmoji = "0.15.0"
|
// Temporary version to unblock #6929. Once 0.16.0 is released we should use it, and revert
|
||||||
|
// the whole commit which set version 0.16.0-SNAPSHOT
|
||||||
|
def vanniktechEmoji = "0.16.0-SNAPSHOT"
|
||||||
|
|
||||||
def fragment = "1.5.2"
|
def fragment = "1.5.2"
|
||||||
|
|
||||||
|
@ -51,7 +50,7 @@ ext.libs = [
|
||||||
],
|
],
|
||||||
androidx : [
|
androidx : [
|
||||||
'activity' : "androidx.activity:activity:1.5.1",
|
'activity' : "androidx.activity:activity:1.5.1",
|
||||||
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
|
'appCompat' : "androidx.appcompat:appcompat:1.5.1",
|
||||||
'biometric' : "androidx.biometric:biometric:1.1.0",
|
'biometric' : "androidx.biometric:biometric:1.1.0",
|
||||||
'core' : "androidx.core:core-ktx:1.8.0",
|
'core' : "androidx.core:core-ktx:1.8.0",
|
||||||
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
|
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
|
||||||
|
|
|
@ -38,6 +38,13 @@ ext.groups = [
|
||||||
'com.google.testing.platform',
|
'com.google.testing.platform',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
snapshot: [
|
||||||
|
regex: [
|
||||||
|
],
|
||||||
|
group: [
|
||||||
|
'com.vanniktech',
|
||||||
|
]
|
||||||
|
],
|
||||||
mavenCentral: [
|
mavenCentral: [
|
||||||
regex: [
|
regex: [
|
||||||
],
|
],
|
||||||
|
@ -118,7 +125,7 @@ ext.groups = [
|
||||||
'com.sun.xml.bind.mvn',
|
'com.sun.xml.bind.mvn',
|
||||||
'com.sun.xml.fastinfoset',
|
'com.sun.xml.fastinfoset',
|
||||||
'com.thoughtworks.qdox',
|
'com.thoughtworks.qdox',
|
||||||
'com.vanniktech',
|
// 'com.vanniktech',
|
||||||
'commons-cli',
|
'commons-cli',
|
||||||
'commons-codec',
|
'commons-codec',
|
||||||
'commons-io',
|
'commons-io',
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package im.vector.lib.attachmentviewer
|
package im.vector.lib.attachmentviewer
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -136,7 +135,6 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun setDecorViewFullScreen() {
|
private fun setDecorViewFullScreen() {
|
||||||
// This is important for the dispatchTouchEvent, if not we must correct
|
// This is important for the dispatchTouchEvent, if not we must correct
|
||||||
// the touch coordinates
|
// the touch coordinates
|
||||||
|
@ -144,22 +142,20 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
window.setDecorFitsSystemWindows(false)
|
window.setDecorFitsSystemWindows(false)
|
||||||
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
} else {
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
|
|
||||||
}
|
|
||||||
// New API instead of FLAG_TRANSLUCENT_STATUS
|
// New API instead of FLAG_TRANSLUCENT_STATUS
|
||||||
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
||||||
// new API instead of FLAG_TRANSLUCENT_NAVIGATION
|
// new API instead of FLAG_TRANSLUCENT_NAVIGATION
|
||||||
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.decorView.systemUiVisibility = (
|
window.decorView.systemUiVisibility = (
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
or View.SYSTEM_UI_FLAG_IMMERSIVE)
|
or View.SYSTEM_UI_FLAG_IMMERSIVE)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +340,6 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
?.handleCommand(commands)
|
?.handleCommand(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun hideSystemUI() {
|
private fun hideSystemUI() {
|
||||||
systemUiVisibility = false
|
systemUiVisibility = false
|
||||||
// Enables regular immersive mode.
|
// Enables regular immersive mode.
|
||||||
|
@ -356,17 +351,13 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
// new API instead of SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
// new API instead of SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||||
window.decorView.windowInsetsController?.hide(WindowInsets.Type.navigationBars())
|
window.decorView.windowInsetsController?.hide(WindowInsets.Type.navigationBars())
|
||||||
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
} else {
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
|
|
||||||
}
|
|
||||||
// New API instead of FLAG_TRANSLUCENT_STATUS
|
// New API instead of FLAG_TRANSLUCENT_STATUS
|
||||||
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
||||||
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
|
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
|
||||||
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
|
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||||
// Set the content to appear under the system bars so that the
|
// Set the content to appear under the system bars so that the
|
||||||
// content doesn't resize when the system bars hide and show.
|
// content doesn't resize when the system bars hide and show.
|
||||||
|
@ -381,13 +372,13 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
||||||
|
|
||||||
// Shows the system bars by removing all the flags
|
// Shows the system bars by removing all the flags
|
||||||
// except for the ones that make the content appear under the system bars.
|
// except for the ones that make the content appear under the system bars.
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun showSystemUI() {
|
private fun showSystemUI() {
|
||||||
systemUiVisibility = true
|
systemUiVisibility = true
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
window.setDecorFitsSystemWindows(false)
|
window.setDecorFitsSystemWindows(false)
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.session.room.send.queue
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CancellationException
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.matrix.android.sdk.api.auth.data.SessionParams
|
|
||||||
import org.matrix.android.sdk.api.auth.data.sessionId
|
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
|
||||||
import org.matrix.android.sdk.api.failure.Failure
|
|
||||||
import org.matrix.android.sdk.api.failure.isLimitExceededError
|
|
||||||
import org.matrix.android.sdk.api.failure.isTokenError
|
|
||||||
import org.matrix.android.sdk.api.session.Session
|
|
||||||
import org.matrix.android.sdk.api.session.crypto.CryptoService
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
|
||||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
|
||||||
import org.matrix.android.sdk.api.util.Cancelable
|
|
||||||
import org.matrix.android.sdk.internal.session.SessionScope
|
|
||||||
import org.matrix.android.sdk.internal.task.TaskExecutor
|
|
||||||
import timber.log.Timber
|
|
||||||
import java.io.IOException
|
|
||||||
import java.util.Timer
|
|
||||||
import java.util.TimerTask
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlin.concurrent.schedule
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple ever running thread unique for that session responsible of sending events in order.
|
|
||||||
* Each send is retried 3 times, if there is no network (e.g if cannot ping homeserver) it will wait and
|
|
||||||
* periodically test reachability before resume (does not count as a retry)
|
|
||||||
*
|
|
||||||
* If the app is killed before all event were sent, on next wakeup the scheduled events will be re posted
|
|
||||||
*/
|
|
||||||
@Deprecated("You should know use EventSenderProcessorCoroutine instead")
|
|
||||||
@SessionScope
|
|
||||||
internal class EventSenderProcessorThread @Inject constructor(
|
|
||||||
private val cryptoService: CryptoService,
|
|
||||||
private val sessionParams: SessionParams,
|
|
||||||
private val queuedTaskFactory: QueuedTaskFactory,
|
|
||||||
private val taskExecutor: TaskExecutor,
|
|
||||||
private val memento: QueueMemento
|
|
||||||
) : Thread("Matrix-SENDER_THREAD_SID_${sessionParams.credentials.sessionId()}"), EventSenderProcessor {
|
|
||||||
|
|
||||||
private fun markAsManaged(task: QueuedTask) {
|
|
||||||
memento.track(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun markAsFinished(task: QueuedTask) {
|
|
||||||
memento.unTrack(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSessionStarted(session: Session) {
|
|
||||||
start()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSessionStopped(session: Session) {
|
|
||||||
interrupt()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun start() {
|
|
||||||
super.start()
|
|
||||||
// We should check for sending events not handled because app was killed
|
|
||||||
// But we should be careful of only took those that was submitted to us, because if it's
|
|
||||||
// for example it's a media event it is handled by some worker and he will handle it
|
|
||||||
// This is a bit fragile :/
|
|
||||||
// also some events cannot be retried manually by users, e.g reactions
|
|
||||||
// they were previously relying on workers to do the work :/ and was expected to always finally succeed
|
|
||||||
// Also some echos are not to be resent like redaction echos (fake event created for aggregation)
|
|
||||||
|
|
||||||
tryOrNull {
|
|
||||||
taskExecutor.executorScope.launch {
|
|
||||||
Timber.d("## Send relaunched pending events on restart")
|
|
||||||
memento.restoreTasks(this@EventSenderProcessorThread)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// API
|
|
||||||
override fun postEvent(event: Event): Cancelable {
|
|
||||||
return postEvent(event, event.roomId?.let { cryptoService.isRoomEncrypted(it) } ?: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postEvent(event: Event, encrypt: Boolean): Cancelable {
|
|
||||||
val task = queuedTaskFactory.createSendTask(event, encrypt)
|
|
||||||
return postTask(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postRedaction(redactionLocalEcho: Event, reason: String?): Cancelable {
|
|
||||||
return postRedaction(redactionLocalEcho.eventId!!, redactionLocalEcho.redacts!!, redactionLocalEcho.roomId!!, reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postRedaction(redactionLocalEchoId: String, eventToRedactId: String, roomId: String, reason: String?): Cancelable {
|
|
||||||
val task = queuedTaskFactory.createRedactTask(redactionLocalEchoId, eventToRedactId, roomId, reason)
|
|
||||||
return postTask(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun postTask(task: QueuedTask): Cancelable {
|
|
||||||
// non blocking add to queue
|
|
||||||
sendingQueue.add(task)
|
|
||||||
markAsManaged(task)
|
|
||||||
return task
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun cancel(eventId: String, roomId: String) {
|
|
||||||
(currentTask as? SendEventQueuedTask)
|
|
||||||
?.takeIf { it.event.eventId == eventId && it.event.roomId == roomId }
|
|
||||||
?.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val RETRY_WAIT_TIME_MS = 10_000L
|
|
||||||
}
|
|
||||||
|
|
||||||
private var currentTask: QueuedTask? = null
|
|
||||||
|
|
||||||
private var sendingQueue = LinkedBlockingQueue<QueuedTask>()
|
|
||||||
|
|
||||||
private var networkAvailableLock = Object()
|
|
||||||
private var canReachServer = true
|
|
||||||
private var retryNoNetworkTask: TimerTask? = null
|
|
||||||
|
|
||||||
override fun run() {
|
|
||||||
Timber.v("## SendThread started")
|
|
||||||
try {
|
|
||||||
while (!isInterrupted) {
|
|
||||||
Timber.v("## SendThread wait for task to process")
|
|
||||||
val task = sendingQueue.take()
|
|
||||||
.also { currentTask = it }
|
|
||||||
Timber.v("## SendThread Found task to process $task")
|
|
||||||
|
|
||||||
if (task.isCancelled()) {
|
|
||||||
Timber.v("## SendThread send cancelled for $task")
|
|
||||||
// we do not execute this one
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// we check for network connectivity
|
|
||||||
while (!canReachServer) {
|
|
||||||
Timber.v("## SendThread cannot reach server")
|
|
||||||
// schedule to retry
|
|
||||||
waitForNetwork()
|
|
||||||
// if thread as been killed meanwhile
|
|
||||||
// if (state == State.KILLING) break
|
|
||||||
}
|
|
||||||
Timber.v("## Server is Reachable")
|
|
||||||
// so network is available
|
|
||||||
|
|
||||||
runBlocking {
|
|
||||||
retryLoop@ while (task.retryCount.get() < 3) {
|
|
||||||
try {
|
|
||||||
// SendPerformanceProfiler.startStage(task.event.eventId!!, SendPerformanceProfiler.Stages.SEND_WORKER)
|
|
||||||
Timber.v("## SendThread retryLoop for $task retryCount ${task.retryCount}")
|
|
||||||
task.execute()
|
|
||||||
// sendEventTask.execute(SendEventTask.Params(task.event, task.encrypt, cryptoService))
|
|
||||||
// SendPerformanceProfiler.stopStage(task.event.eventId, SendPerformanceProfiler.Stages.SEND_WORKER)
|
|
||||||
break@retryLoop
|
|
||||||
} catch (exception: Throwable) {
|
|
||||||
when {
|
|
||||||
exception is IOException || exception is Failure.NetworkConnection -> {
|
|
||||||
canReachServer = false
|
|
||||||
if (task.retryCount.getAndIncrement() >= 3) task.onTaskFailed()
|
|
||||||
while (!canReachServer) {
|
|
||||||
Timber.v("## SendThread retryLoop cannot reach server")
|
|
||||||
// schedule to retry
|
|
||||||
waitForNetwork()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(exception.isLimitExceededError()) -> {
|
|
||||||
if (task.retryCount.getAndIncrement() >= 3) task.onTaskFailed()
|
|
||||||
Timber.v("## SendThread retryLoop retryable error for $task reason: ${exception.localizedMessage}")
|
|
||||||
// wait a bit
|
|
||||||
// Todo if its a quota exception can we get timout?
|
|
||||||
sleep(3_000)
|
|
||||||
continue@retryLoop
|
|
||||||
}
|
|
||||||
exception.isTokenError() -> {
|
|
||||||
Timber.v("## SendThread retryLoop retryable TOKEN error, interrupt")
|
|
||||||
// we can exit the loop
|
|
||||||
task.onTaskFailed()
|
|
||||||
throw InterruptedException()
|
|
||||||
}
|
|
||||||
exception is CancellationException -> {
|
|
||||||
Timber.v("## SendThread task has been cancelled")
|
|
||||||
break@retryLoop
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Timber.v("## SendThread retryLoop Un-Retryable error, try next task")
|
|
||||||
// this task is in error, check next one?
|
|
||||||
task.onTaskFailed()
|
|
||||||
break@retryLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
markAsFinished(task)
|
|
||||||
}
|
|
||||||
} catch (interruptionException: InterruptedException) {
|
|
||||||
// will be thrown is thread is interrupted while seeping
|
|
||||||
interrupt()
|
|
||||||
Timber.v("## InterruptedException!! ${interruptionException.localizedMessage}")
|
|
||||||
}
|
|
||||||
// state = State.KILLED
|
|
||||||
// is this needed?
|
|
||||||
retryNoNetworkTask?.cancel()
|
|
||||||
Timber.w("## SendThread finished")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun waitForNetwork() {
|
|
||||||
retryNoNetworkTask = Timer(SyncState.NoNetwork.toString(), false).schedule(RETRY_WAIT_TIME_MS) {
|
|
||||||
synchronized(networkAvailableLock) {
|
|
||||||
canReachServer = HomeServerAvailabilityChecker(sessionParams).check().also {
|
|
||||||
Timber.v("## SendThread checkHostAvailable $it")
|
|
||||||
}
|
|
||||||
networkAvailableLock.notify()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
synchronized(networkAvailableLock) { networkAvailableLock.wait() }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -87,6 +87,7 @@
|
||||||
|
|
||||||
<!-- Manifest -->
|
<!-- Manifest -->
|
||||||
<issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" />
|
<issue id="PermissionImpliesUnsupportedChromeOsHardware" severity="error" />
|
||||||
|
<issue id="DataExtractionRules" severity="error" />
|
||||||
|
|
||||||
<!-- Performance -->
|
<!-- Performance -->
|
||||||
<issue id="UselessParent" severity="error" />
|
<issue id="UselessParent" severity="error" />
|
||||||
|
|
|
@ -191,7 +191,7 @@ android {
|
||||||
// Known limitation: it does not modify the value in the BuildConfig.java generated file
|
// Known limitation: it does not modify the value in the BuildConfig.java generated file
|
||||||
// See https://issuetracker.google.com/issues/171133218
|
// See https://issuetracker.google.com/issues/171133218
|
||||||
output.versionCodeOverride = baseVariantVersion + baseAbiVersionCode
|
output.versionCodeOverride = baseVariantVersion + baseAbiVersionCode
|
||||||
print "ABI " + output.getFilter(OutputFile.ABI) + " \t-> VersionCode = " + output.versionCodeOverride + "\n"
|
print "ABI " + output.getFilter(OutputFile.ABI) + " \t-> VersionCode = " + output.versionCode + "\n"
|
||||||
output.outputFileName = output.outputFileName.replace("vector-app", "vector")
|
output.outputFileName = output.outputFileName.replace("vector-app", "vector")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,6 @@ private fun useMediaStoreScreenshotStorage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun usePublicExternalScreenshotStorage(
|
private fun usePublicExternalScreenshotStorage(
|
||||||
contentValues: ContentValues,
|
contentValues: ContentValues,
|
||||||
contentResolver: ContentResolver,
|
contentResolver: ContentResolver,
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
<application
|
<application
|
||||||
android:name="im.vector.app.VectorApplication"
|
android:name="im.vector.app.VectorApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:hasFragileUserData="true"
|
android:hasFragileUserData="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<full-backup-content>
|
||||||
|
<exclude
|
||||||
|
domain="file"
|
||||||
|
path="." />
|
||||||
|
<exclude
|
||||||
|
domain="database"
|
||||||
|
path="." />
|
||||||
|
<exclude
|
||||||
|
domain="sharedpref"
|
||||||
|
path="." />
|
||||||
|
<exclude
|
||||||
|
domain="external"
|
||||||
|
path="." />
|
||||||
|
<exclude
|
||||||
|
domain="root"
|
||||||
|
path="." />
|
||||||
|
</full-backup-content>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<exclude domain="root" />
|
||||||
|
<exclude domain="file" />
|
||||||
|
<exclude domain="database" />
|
||||||
|
<exclude domain="sharedpref" />
|
||||||
|
<exclude domain="external" />
|
||||||
|
</cloud-backup>
|
||||||
|
<device-transfer>
|
||||||
|
<exclude domain="root" />
|
||||||
|
<exclude domain="file" />
|
||||||
|
<exclude domain="database" />
|
||||||
|
<exclude domain="sharedpref" />
|
||||||
|
<exclude domain="external" />
|
||||||
|
</device-transfer>
|
||||||
|
</data-extraction-rules>
|
|
@ -232,7 +232,7 @@ dependencies {
|
||||||
// UnifiedPush
|
// UnifiedPush
|
||||||
implementation 'com.github.UnifiedPush:android-connector:2.0.1'
|
implementation 'com.github.UnifiedPush:android-connector:2.0.1'
|
||||||
|
|
||||||
implementation "androidx.emoji2:emoji2:1.1.0"
|
implementation "androidx.emoji2:emoji2:1.2.0"
|
||||||
|
|
||||||
// WebRTC
|
// WebRTC
|
||||||
// org.webrtc:google-webrtc is for development purposes only
|
// org.webrtc:google-webrtc is for development purposes only
|
||||||
|
|
|
@ -318,13 +318,13 @@
|
||||||
<activity android:name=".features.poll.create.CreatePollActivity" />
|
<activity android:name=".features.poll.create.CreatePollActivity" />
|
||||||
<activity android:name=".features.location.LocationSharingActivity" />
|
<activity android:name=".features.location.LocationSharingActivity" />
|
||||||
<activity android:name=".features.location.live.map.LiveLocationMapViewActivity" />
|
<activity android:name=".features.location.live.map.LiveLocationMapViewActivity" />
|
||||||
<activity android:name=".features.settings.font.FontScaleSettingActivity"/>
|
<activity android:name=".features.settings.font.FontScaleSettingActivity" />
|
||||||
<activity android:name=".features.call.dialpad.PstnDialActivity" />
|
<activity android:name=".features.call.dialpad.PstnDialActivity" />
|
||||||
<activity android:name=".features.home.room.list.home.invites.InvitesActivity"/>
|
<activity android:name=".features.home.room.list.home.invites.InvitesActivity" />
|
||||||
<activity android:name=".features.home.room.list.home.release.ReleaseNotesActivity"/>
|
<activity android:name=".features.home.room.list.home.release.ReleaseNotesActivity" />
|
||||||
<activity android:name=".features.settings.devices.v2.overview.SessionOverviewActivity"/>
|
<activity android:name=".features.settings.devices.v2.overview.SessionOverviewActivity" />
|
||||||
<activity android:name=".features.settings.devices.v2.othersessions.OtherSessionsActivity" />
|
<activity android:name=".features.settings.devices.v2.othersessions.OtherSessionsActivity" />
|
||||||
<activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity"/>
|
<activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity" />
|
||||||
|
|
||||||
<!-- Services -->
|
<!-- Services -->
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,6 @@ fun Context.safeOpenOutputStream(uri: Uri): OutputStream? {
|
||||||
*
|
*
|
||||||
* @return true if no active connection is found
|
* @return true if no active connection is found
|
||||||
*/
|
*/
|
||||||
@Suppress("deprecation")
|
|
||||||
@SuppressLint("NewApi") // false positive
|
@SuppressLint("NewApi") // false positive
|
||||||
fun Context.inferNoConnectivity(sdkIntProvider: BuildVersionSdkIntProvider): Boolean {
|
fun Context.inferNoConnectivity(sdkIntProvider: BuildVersionSdkIntProvider): Boolean {
|
||||||
val connectivityManager = getSystemService<ConnectivityManager>()!!
|
val connectivityManager = getSystemService<ConnectivityManager>()!!
|
||||||
|
@ -104,6 +103,7 @@ fun Context.inferNoConnectivity(sdkIntProvider: BuildVersionSdkIntProvider): Boo
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
when (connectivityManager.activeNetworkInfo?.type) {
|
when (connectivityManager.activeNetworkInfo?.type) {
|
||||||
ConnectivityManager.TYPE_WIFI -> false
|
ConnectivityManager.TYPE_WIFI -> false
|
||||||
ConnectivityManager.TYPE_MOBILE -> false
|
ConnectivityManager.TYPE_MOBILE -> false
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package im.vector.app.core.platform
|
package im.vector.app.core.platform
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -464,23 +463,18 @@ abstract class VectorBaseActivity<VB : ViewBinding> : AppCompatActivity(), Maver
|
||||||
/**
|
/**
|
||||||
* Force to render the activity in fullscreen.
|
* Force to render the activity in fullscreen.
|
||||||
*/
|
*/
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun setFullScreen() {
|
private fun setFullScreen() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
window.setDecorFitsSystemWindows(false)
|
window.setDecorFitsSystemWindows(false)
|
||||||
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
} else {
|
|
||||||
@SuppressLint("WrongConstant")
|
|
||||||
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
|
|
||||||
}
|
|
||||||
// New API instead of FLAG_TRANSLUCENT_STATUS
|
// New API instead of FLAG_TRANSLUCENT_STATUS
|
||||||
window.statusBarColor = ContextCompat.getColor(this, im.vector.lib.attachmentviewer.R.color.half_transparent_status_bar)
|
window.statusBarColor = ContextCompat.getColor(this, im.vector.lib.attachmentviewer.R.color.half_transparent_status_bar)
|
||||||
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
|
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
|
||||||
window.navigationBarColor = ContextCompat.getColor(this, im.vector.lib.attachmentviewer.R.color.half_transparent_status_bar)
|
window.navigationBarColor = ContextCompat.getColor(this, im.vector.lib.attachmentviewer.R.color.half_transparent_status_bar)
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
|
|
@ -309,7 +309,6 @@ suspend fun saveMedia(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun saveMediaLegacy(
|
private fun saveMediaLegacy(
|
||||||
context: Context,
|
context: Context,
|
||||||
mediaMimeType: String?,
|
mediaMimeType: String?,
|
||||||
|
@ -340,6 +339,7 @@ private fun saveMediaLegacy(
|
||||||
val savedFile = saveFileIntoLegacy(file, downloadDir, outputFilename, currentTimeMillis)
|
val savedFile = saveFileIntoLegacy(file, downloadDir, outputFilename, currentTimeMillis)
|
||||||
if (savedFile != null) {
|
if (savedFile != null) {
|
||||||
val downloadManager = context.getSystemService<DownloadManager>()
|
val downloadManager = context.getSystemService<DownloadManager>()
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
downloadManager?.addCompletedDownload(
|
downloadManager?.addCompletedDownload(
|
||||||
savedFile.name,
|
savedFile.name,
|
||||||
title,
|
title,
|
||||||
|
@ -430,7 +430,6 @@ fun selectTxtFileToWrite(
|
||||||
* @param currentTimeMillis the current time in milliseconds
|
* @param currentTimeMillis the current time in milliseconds
|
||||||
* @return the created file
|
* @return the created file
|
||||||
*/
|
*/
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
fun saveFileIntoLegacy(sourceFile: File, dstDirPath: File, outputFilename: String?, currentTimeMillis: Long): File? {
|
fun saveFileIntoLegacy(sourceFile: File, dstDirPath: File, outputFilename: String?, currentTimeMillis: Long): File? {
|
||||||
// defines another name for the external media
|
// defines another name for the external media
|
||||||
var dstFileName: String
|
var dstFileName: String
|
||||||
|
|
|
@ -169,11 +169,11 @@ class AttachmentsPreviewFragment :
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun applyInsets() {
|
private fun applyInsets() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
activity?.window?.setDecorFitsSystemWindows(false)
|
activity?.window?.setDecorFitsSystemWindows(false)
|
||||||
} else {
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
view?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
view?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
}
|
}
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerBottomContainer) { v, insets ->
|
ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerBottomContainer) { v, insets ->
|
||||||
|
|
|
@ -92,7 +92,6 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
|
||||||
* @return true if an app task is corrupted by a potentially malicious activity
|
* @return true if an app task is corrupted by a potentially malicious activity
|
||||||
*/
|
*/
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private suspend fun isTaskCorrupted(activity: Activity): Boolean = withContext(Dispatchers.Default) {
|
private suspend fun isTaskCorrupted(activity: Activity): Boolean = withContext(Dispatchers.Default) {
|
||||||
val context = activity.applicationContext
|
val context = activity.applicationContext
|
||||||
val packageManager: PackageManager = context.packageManager
|
val packageManager: PackageManager = context.packageManager
|
||||||
|
@ -120,6 +119,7 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager
|
||||||
// This was present in ActivityManager.RunningTaskInfo class since API level 1!
|
// This was present in ActivityManager.RunningTaskInfo class since API level 1!
|
||||||
// and it is inherited from TaskInfo since Android Q (API level 29).
|
// and it is inherited from TaskInfo since Android Q (API level 29).
|
||||||
// API 29 changes : https://developer.android.com/sdk/api_diff/29/changes/android.app.ActivityManager.RunningTaskInfo
|
// API 29 changes : https://developer.android.com/sdk/api_diff/29/changes/android.app.ActivityManager.RunningTaskInfo
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
manager.getRunningTasks(10).any { runningTaskInfo ->
|
manager.getRunningTasks(10).any { runningTaskInfo ->
|
||||||
runningTaskInfo.topActivity?.let {
|
runningTaskInfo.topActivity?.let {
|
||||||
// Check whether the activity task affinity matches with app task affinity.
|
// Check whether the activity task affinity matches with app task affinity.
|
||||||
|
|
|
@ -50,10 +50,10 @@ class FallbackBiometricDialogFragment : DialogFragment(R.layout.fragment_biometr
|
||||||
|
|
||||||
private val parsedArgs by args<Args>()
|
private val parsedArgs by args<Args>()
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
retainInstance = true
|
retainInstance = true
|
||||||
|
|
||||||
setStyle(STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog)
|
setStyle(STYLE_NORMAL, android.R.style.Theme_Material_Light_Dialog)
|
||||||
|
|
|
@ -82,15 +82,18 @@ class RoomUploadsMediaFragment :
|
||||||
controller.listener = this
|
controller.listener = this
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
private fun getNumberOfColumns(): Int {
|
private fun getNumberOfColumns(): Int {
|
||||||
val displayMetrics = DisplayMetrics()
|
val screenWidthInPx = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
val a = requireActivity().windowManager.currentWindowMetrics
|
||||||
requireContext().display?.getMetrics(displayMetrics)
|
a.bounds.width()
|
||||||
} else {
|
} else {
|
||||||
|
val displayMetrics = DisplayMetrics()
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics)
|
||||||
|
displayMetrics.widthPixels
|
||||||
}
|
}
|
||||||
return dimensionConverter.pxToDp(displayMetrics.widthPixels) / IMAGE_SIZE_DP
|
val screenWidthInDp = dimensionConverter.pxToDp(screenWidthInPx)
|
||||||
|
return screenWidthInDp / IMAGE_SIZE_DP
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
|
Loading…
Reference in New Issue