mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-16 12:00:03 +03:00
Merge pull request #8578 from vector-im/feature/bma/crashFixes
Crash fixes
This commit is contained in:
commit
180a2eec60
9 changed files with 159 additions and 28 deletions
|
@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.handler
|
|||
import androidx.work.BackoffPolicy
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import org.matrix.android.sdk.api.MatrixPatterns
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorker
|
||||
import org.matrix.android.sdk.internal.crypto.crosssigning.UpdateTrustWorkerDataRepository
|
||||
import org.matrix.android.sdk.internal.di.SessionId
|
||||
|
@ -81,7 +82,9 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor(
|
|||
}
|
||||
}
|
||||
if (hasUpdate) {
|
||||
updateUserAccountDataTask.execute(UpdateUserAccountDataTask.DirectChatParams(directMessages = directChats))
|
||||
tryOrNull("Unable to update user account data") {
|
||||
updateUserAccountDataTask.execute(UpdateUserAccountDataTask.DirectChatParams(directMessages = directChats))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.zhuinden.monarchy.Monarchy
|
|||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import org.matrix.android.sdk.api.failure.InitialSyncRequestReason
|
||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
|
||||
|
@ -122,7 +123,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
|
|||
val updateUserAccountParams = UpdateUserAccountDataTask.DirectChatParams(
|
||||
directMessages = directChats
|
||||
)
|
||||
updateUserAccountDataTask.execute(updateUserAccountParams)
|
||||
tryOrNull("Unable to update user account data") { updateUserAccountDataTask.execute(updateUserAccountParams) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import im.vector.app.core.platform.VectorViewModelAction
|
|||
import java.io.OutputStream
|
||||
|
||||
sealed class BootstrapActions : VectorViewModelAction {
|
||||
object Retry : BootstrapActions()
|
||||
|
||||
// Navigation
|
||||
|
||||
|
|
|
@ -212,6 +212,11 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBoot
|
|||
views.bootstrapTitleText.text = getString(R.string.upgrade_security)
|
||||
showFragment(BootstrapMigrateBackupFragment::class)
|
||||
}
|
||||
is BootstrapStep.Error -> {
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title)
|
||||
showFragment(BootstrapErrorFragment::class)
|
||||
}
|
||||
}
|
||||
super.invalidate()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* 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 im.vector.app.features.crypto.recover
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentBootstrapErrorBinding
|
||||
|
||||
@AndroidEntryPoint
|
||||
class BootstrapErrorFragment :
|
||||
VectorBaseFragment<FragmentBootstrapErrorBinding>() {
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapErrorBinding {
|
||||
return FragmentBootstrapErrorBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
when (state.step) {
|
||||
is BootstrapStep.Error -> {
|
||||
views.bootstrapDescriptionText.setTextOrHide(errorFormatter.toHumanReadable(state.step.error))
|
||||
}
|
||||
else -> {
|
||||
// Should not happen, show a generic error
|
||||
views.bootstrapDescriptionText.setTextOrHide(getString(R.string.unknown_error))
|
||||
}
|
||||
}
|
||||
views.bootstrapRetryButton.onClick {
|
||||
sharedViewModel.handle(BootstrapActions.Retry)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,6 +54,7 @@ import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromR
|
|||
import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult
|
||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||
import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth
|
||||
import timber.log.Timber
|
||||
import java.io.OutputStream
|
||||
import kotlin.coroutines.Continuation
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
@ -118,37 +119,48 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
SetupMode.NORMAL -> {
|
||||
// need to check if user have an existing keybackup
|
||||
setState {
|
||||
copy(step = BootstrapStep.CheckingMigration)
|
||||
}
|
||||
checkMigration()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We need to check if there is an existing backup
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val version = tryOrNull { session.cryptoService().keysBackupService().getCurrentVersion() }?.toKeysVersionResult()
|
||||
if (version == null) {
|
||||
// we just resume plain bootstrap
|
||||
doesKeyBackupExist = false
|
||||
private fun checkMigration() {
|
||||
// need to check if user have an existing keybackup
|
||||
setState {
|
||||
copy(step = BootstrapStep.CheckingMigration)
|
||||
}
|
||||
|
||||
// We need to check if there is an existing backup
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val version = tryOrNull { session.cryptoService().keysBackupService().getCurrentVersion() }?.toKeysVersionResult()
|
||||
if (version == null) {
|
||||
// we just resume plain bootstrap
|
||||
doesKeyBackupExist = false
|
||||
setState {
|
||||
copy(step = BootstrapStep.FirstForm(keyBackUpExist = doesKeyBackupExist, methods = this.secureBackupMethod))
|
||||
}
|
||||
} else {
|
||||
// we need to get existing backup passphrase/key and convert to SSSS
|
||||
val keyVersion = tryOrNull {
|
||||
session.cryptoService().keysBackupService().getVersion(version.version)
|
||||
}
|
||||
if (keyVersion == null) {
|
||||
// strange case... just finish?
|
||||
_viewEvents.post(BootstrapViewEvents.Dismiss(false))
|
||||
} else {
|
||||
doesKeyBackupExist = true
|
||||
isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
|
||||
setState {
|
||||
copy(step = BootstrapStep.FirstForm(keyBackUpExist = doesKeyBackupExist, methods = this.secureBackupMethod))
|
||||
}
|
||||
} else {
|
||||
// we need to get existing backup passphrase/key and convert to SSSS
|
||||
val keyVersion = tryOrNull {
|
||||
session.cryptoService().keysBackupService().getVersion(version.version)
|
||||
}
|
||||
if (keyVersion == null) {
|
||||
// strange case... just finish?
|
||||
_viewEvents.post(BootstrapViewEvents.Dismiss(false))
|
||||
} else {
|
||||
doesKeyBackupExist = true
|
||||
isBackupCreatedFromPassphrase = keyVersion.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
|
||||
setState {
|
||||
copy(step = BootstrapStep.FirstForm(keyBackUpExist = doesKeyBackupExist, methods = this.secureBackupMethod))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "Error while checking key backup")
|
||||
setState {
|
||||
copy(step = BootstrapStep.Error(failure))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +280,9 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||
copy(step = BootstrapStep.AccountReAuth(stringProvider.getString(R.string.authentication_error)))
|
||||
}
|
||||
}
|
||||
BootstrapActions.Retry -> {
|
||||
checkMigration()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -568,6 +583,12 @@ class BootstrapSharedViewModel @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
is BootstrapStep.Error -> {
|
||||
// do we let you cancel from here?
|
||||
if (state.canLeave) {
|
||||
_viewEvents.post(BootstrapViewEvents.SkipBootstrap(state.passphrase != null))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,8 @@ sealed class BootstrapStep {
|
|||
object Initializing : BootstrapStep()
|
||||
data class SaveRecoveryKey(val isSaved: Boolean) : BootstrapStep()
|
||||
object DoneSuccess : BootstrapStep()
|
||||
|
||||
data class Error(val error: Throwable) : BootstrapStep()
|
||||
}
|
||||
|
||||
fun BootstrapStep.GetBackupSecretForMigration.useKey(): Boolean {
|
||||
|
|
|
@ -71,6 +71,7 @@ import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerC
|
|||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
import org.matrix.android.sdk.flow.flow
|
||||
import org.matrix.android.sdk.flow.unwrap
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import java.util.UUID
|
||||
|
@ -265,7 +266,17 @@ class VectorSettingsGeneralFragment :
|
|||
// Disable it while updating the state, will be re-enabled by the account data listener.
|
||||
it.isEnabled = false
|
||||
lifecycleScope.launch {
|
||||
session.integrationManagerService().setIntegrationEnabled(newValue as Boolean)
|
||||
try {
|
||||
session.integrationManagerService().setIntegrationEnabled(newValue as Boolean)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "Failed to update integration manager state")
|
||||
activity?.let { activity ->
|
||||
Toast.makeText(activity, errorFormatter.toHumanReadable(failure), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
// Restore the previous state
|
||||
it.isChecked = !it.isChecked
|
||||
it.isEnabled = true
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
33
vector/src/main/res/layout/fragment_bootstrap_error.xml
Normal file
33
vector/src/main/res/layout/fragment_bootstrap_error.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="200dp"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bootstrapDescriptionText"
|
||||
style="@style/Widget.Vector.TextView.Body"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/error_check_network"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/bootstrapRetryButton"
|
||||
style="@style/Widget.Vector.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:text="@string/global_retry"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bootstrapDescriptionText"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Add table
Reference in a new issue