Merge pull request #1082 from vector-im/feature/fix_rageshakes
Fix crashes reported by rageshakes
This commit is contained in:
commit
6e67d4749f
@ -22,6 +22,7 @@ import android.content.IntentFilter
|
|||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface NetworkCallbackStrategy {
|
internal interface NetworkCallbackStrategy {
|
||||||
@ -70,7 +71,16 @@ internal class PreferredNetworkCallbackStrategy @Inject constructor(context: Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun unregister() {
|
override fun unregister() {
|
||||||
|
// It can crash after an application update, if not registered
|
||||||
|
val doUnregister = hasChangedCallback != null
|
||||||
hasChangedCallback = null
|
hasChangedCallback = null
|
||||||
conn.unregisterNetworkCallback(networkCallback)
|
if (doUnregister) {
|
||||||
|
// Add a try catch for safety
|
||||||
|
try {
|
||||||
|
conn.unregisterNetworkCallback(networkCallback)
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
Timber.e(t, "Unable to unregister network callback")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ internal object ThumbnailExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractVideoThumbnail(attachment: ContentAttachmentData): ThumbnailData? {
|
private fun extractVideoThumbnail(attachment: ContentAttachmentData): ThumbnailData? {
|
||||||
val thumbnail = ThumbnailUtils.createVideoThumbnail(attachment.path, MediaStore.Video.Thumbnails.MINI_KIND)
|
val thumbnail = ThumbnailUtils.createVideoThumbnail(attachment.path, MediaStore.Video.Thumbnails.MINI_KIND) ?: return null
|
||||||
val outputStream = ByteArrayOutputStream()
|
val outputStream = ByteArrayOutputStream()
|
||||||
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
|
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
|
||||||
val thumbnailWidth = thumbnail.width
|
val thumbnailWidth = thumbnail.width
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.internal.session.room.send
|
package im.vector.matrix.android.internal.session.room.send
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.media.MediaMetadataRetriever
|
import android.media.MediaMetadataRetriever
|
||||||
import androidx.exifinterface.media.ExifInterface
|
import androidx.exifinterface.media.ExifInterface
|
||||||
import im.vector.matrix.android.R
|
import im.vector.matrix.android.R
|
||||||
@ -275,9 +276,9 @@ internal class LocalEchoEventFactory @Inject constructor(
|
|||||||
mediaDataRetriever.setDataSource(attachment.path)
|
mediaDataRetriever.setDataSource(attachment.path)
|
||||||
|
|
||||||
// Use frame to calculate height and width as we are sure to get the right ones
|
// Use frame to calculate height and width as we are sure to get the right ones
|
||||||
val firstFrame = mediaDataRetriever.frameAtTime
|
val firstFrame: Bitmap? = mediaDataRetriever.frameAtTime
|
||||||
val height = firstFrame.height
|
val height = firstFrame?.height ?: 0
|
||||||
val width = firstFrame.width
|
val width = firstFrame?.width ?: 0
|
||||||
mediaDataRetriever.release()
|
mediaDataRetriever.release()
|
||||||
|
|
||||||
val thumbnailInfo = ThumbnailExtractor.extractThumbnail(attachment)?.let {
|
val thumbnailInfo = ThumbnailExtractor.extractThumbnail(attachment)?.let {
|
||||||
|
@ -48,7 +48,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val sessionId = intent.getStringExtra(SyncService.EXTRA_SESSION_ID)
|
val sessionId = intent.getStringExtra(SyncService.EXTRA_SESSION_ID) ?: return
|
||||||
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
|
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
|
||||||
Timber.d("RestartBroadcastReceiver received intent")
|
Timber.d("RestartBroadcastReceiver received intent")
|
||||||
VectorSyncService.newIntent(context, sessionId).let {
|
VectorSyncService.newIntent(context, sessionId).let {
|
||||||
|
@ -38,6 +38,7 @@ import android.text.TextUtils.substring
|
|||||||
import android.text.style.ForegroundColorSpan
|
import android.text.style.ForegroundColorSpan
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
|
import timber.log.Timber
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
@ -300,7 +301,13 @@ class EllipsizingTextView @JvmOverloads constructor(context: Context, attrs: Att
|
|||||||
private inner class EllipsizeEndStrategy : EllipsizeStrategy() {
|
private inner class EllipsizeEndStrategy : EllipsizeStrategy() {
|
||||||
override fun createEllipsizedText(fullText: CharSequence?): CharSequence? {
|
override fun createEllipsizedText(fullText: CharSequence?): CharSequence? {
|
||||||
val layout = createWorkingLayout(fullText)
|
val layout = createWorkingLayout(fullText)
|
||||||
val cutOffIndex = layout.getLineEnd(maxLines - 1)
|
val cutOffIndex = try {
|
||||||
|
layout.getLineEnd(maxLines - 1)
|
||||||
|
} catch (exception: IndexOutOfBoundsException) {
|
||||||
|
// Not sure to understand why this is happening
|
||||||
|
Timber.e(exception, "IndexOutOfBoundsException, maxLine: $maxLines")
|
||||||
|
0
|
||||||
|
}
|
||||||
val textLength = fullText!!.length
|
val textLength = fullText!!.length
|
||||||
var cutOffLength = textLength - cutOffIndex
|
var cutOffLength = textLength - cutOffIndex
|
||||||
if (cutOffLength < ELLIPSIS.length) cutOffLength = ELLIPSIS.length
|
if (cutOffLength < ELLIPSIS.length) cutOffLength = ELLIPSIS.length
|
||||||
|
@ -25,6 +25,7 @@ import com.kbeanie.multipicker.api.Picker.PICK_CONTACT
|
|||||||
import com.kbeanie.multipicker.api.Picker.PICK_FILE
|
import com.kbeanie.multipicker.api.Picker.PICK_FILE
|
||||||
import com.kbeanie.multipicker.api.Picker.PICK_IMAGE_CAMERA
|
import com.kbeanie.multipicker.api.Picker.PICK_IMAGE_CAMERA
|
||||||
import com.kbeanie.multipicker.api.Picker.PICK_IMAGE_DEVICE
|
import com.kbeanie.multipicker.api.Picker.PICK_IMAGE_DEVICE
|
||||||
|
import com.kbeanie.multipicker.core.ImagePickerImpl
|
||||||
import com.kbeanie.multipicker.core.PickerManager
|
import com.kbeanie.multipicker.core.PickerManager
|
||||||
import im.vector.matrix.android.BuildConfig
|
import im.vector.matrix.android.BuildConfig
|
||||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||||
@ -157,6 +158,9 @@ class AttachmentsHelper private constructor(private val context: Context,
|
|||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
val pickerManager = getPickerManagerForRequestCode(requestCode)
|
val pickerManager = getPickerManagerForRequestCode(requestCode)
|
||||||
if (pickerManager != null) {
|
if (pickerManager != null) {
|
||||||
|
if (pickerManager is ImagePickerImpl) {
|
||||||
|
pickerManager.reinitialize(capturePath)
|
||||||
|
}
|
||||||
pickerManager.submit(data)
|
pickerManager.submit(data)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -144,9 +144,9 @@ class ImageContentRenderer @Inject constructor(private val activeSessionHolder:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
imageView.setImageLoaderCallback(object: DefaultImageLoaderCallback {
|
imageView.setImageLoaderCallback(object : DefaultImageLoaderCallback {
|
||||||
override fun onSuccess(image: File?) {
|
override fun onSuccess(image: File?) {
|
||||||
imageView.ssiv.orientation = ORIENTATION_USE_EXIF
|
imageView.ssiv?.orientation = ORIENTATION_USE_EXIF
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -20,16 +20,16 @@ import android.content.Context
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import im.vector.matrix.android.api.permalinks.PermalinkData
|
import im.vector.matrix.android.api.permalinks.PermalinkData
|
||||||
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
||||||
import im.vector.matrix.android.api.session.Session
|
|
||||||
import im.vector.matrix.android.api.util.Optional
|
import im.vector.matrix.android.api.util.Optional
|
||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||||
import im.vector.riotx.features.navigation.Navigator
|
import im.vector.riotx.features.navigation.Navigator
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PermalinkHandler @Inject constructor(private val session: Session,
|
class PermalinkHandler @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val navigator: Navigator) {
|
private val navigator: Navigator) {
|
||||||
|
|
||||||
fun launch(
|
fun launch(
|
||||||
@ -80,7 +80,8 @@ class PermalinkHandler @Inject constructor(private val session: Session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> {
|
private fun PermalinkData.RoomLink.getRoomId(): Single<Optional<String>> {
|
||||||
return if (isRoomAlias) {
|
val session = activeSessionHolder.getSafeActiveSession()
|
||||||
|
return if (isRoomAlias && session != null) {
|
||||||
// At the moment we are not fetching on the server as we don't handle not join room
|
// At the moment we are not fetching on the server as we don't handle not join room
|
||||||
session.rx().getRoomIdByAlias(roomIdOrAlias, false).subscribeOn(Schedulers.io())
|
session.rx().getRoomIdByAlias(roomIdOrAlias, false).subscribeOn(Schedulers.io())
|
||||||
} else {
|
} else {
|
||||||
@ -92,6 +93,7 @@ class PermalinkHandler @Inject constructor(private val session: Session,
|
|||||||
* Open room either joined, or not
|
* Open room either joined, or not
|
||||||
*/
|
*/
|
||||||
private fun openRoom(context: Context, roomId: String?, eventId: String?, buildTask: Boolean) {
|
private fun openRoom(context: Context, roomId: String?, eventId: String?, buildTask: Boolean) {
|
||||||
|
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
return if (roomId != null && session.getRoom(roomId) != null) {
|
return if (roomId != null && session.getRoom(roomId) != null) {
|
||||||
navigator.openRoom(context, roomId, eventId, buildTask)
|
navigator.openRoom(context, roomId, eventId, buildTask)
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,6 +118,10 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(failure: Throwable) {
|
override fun onFailure(failure: Throwable) {
|
||||||
|
if (!isAdded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// revert the check box
|
// revert the check box
|
||||||
switchPref.isChecked = !switchPref.isChecked
|
switchPref.isChecked = !switchPref.isChecked
|
||||||
Toast.makeText(activity, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, R.string.unknown_error, Toast.LENGTH_SHORT).show()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user