Skip to content

Commit

Permalink
More crash fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dzolnai committed Oct 17, 2024
1 parent 5e0d5d9 commit 471eb14
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ import nl.eduvpn.app.service.VPNConnectionService
import nl.eduvpn.app.service.VPNService.VPNStatus
import nl.eduvpn.app.utils.ErrorDialog
import nl.eduvpn.app.utils.FormattingUtils
import nl.eduvpn.app.utils.Log
import nl.eduvpn.app.viewmodel.BaseConnectionViewModel
import nl.eduvpn.app.viewmodel.ConnectionStatusViewModel
import nl.eduvpn.app.viewmodel.MainViewModel
import org.eduvpn.common.Protocol
import java.util.logging.Logger

/**
* The fragment which displays the status of the current connection.
Expand All @@ -74,10 +76,11 @@ class ConnectionStatusFragment : BaseFragment<FragmentConnectionStatusBinding>()
binding.failoverNeeded = mainViewModel.failoverResult.value ?: false
binding.secondsConnected = viewModel.connectionTimeLiveData.map { secondsConnected ->
val context = this@ConnectionStatusFragment.context ?: return@map null
FormattingUtils.formatDurationSeconds(
context,
secondsConnected
)
if (secondsConnected < 0) {
FormattingUtils.formatDurationSeconds(context, null)
} else {
FormattingUtils.formatDurationSeconds(context, secondsConnected)
}
}
binding.bytesDownloaded = viewModel.byteCountFlow.map { bc ->
val context = this@ConnectionStatusFragment.context ?: return@map null
Expand Down Expand Up @@ -300,18 +303,29 @@ class ConnectionStatusFragment : BaseFragment<FragmentConnectionStatusBinding>()
viewModel.isInDisconnectMode.value = false
setToggleCheckedWithoutAction(true)
viewModel.viewModelScope.launch(Dispatchers.IO) {
viewModel.selectProfileToConnectTo(profile, preferTcp = false).onFailure { thr ->
withContext(Dispatchers.Main) {
setToggleCheckedWithoutAction(false)
viewModel.isInDisconnectMode.value = true
ErrorDialog.show(requireActivity(), thr)
try {
viewModel.selectProfileToConnectTo(profile, preferTcp = false).onFailure { thr ->
withContext(Dispatchers.Main) {
setToggleCheckedWithoutAction(false)
viewModel.isInDisconnectMode.value = true
ErrorDialog.show(requireActivity(), thr)
}
}.onSuccess {
// Relaunch this fragment. This is required, because in some cases, the backend
// implementation (WireGuard vs OpenVPN) might be different, and we would be connected
// to the incorrect one.
(activity as? MainActivity)?.openFragment(ConnectionStatusFragment(), openOnTop = false)
}
} catch (ex: Exception) {
Log.w(TAG, "Could not select profile to connect to!", ex)
activity?.let {
ErrorDialog.show(it, ex)
}
}.onSuccess {
// Relaunch this fragment. This is required, because in some cases, the backend
// implementation (WireGuard vs OpenVPN) might be different, and we would be connected
// to the incorrect one.
(activity as? MainActivity)?.openFragment(ConnectionStatusFragment(), openOnTop = false)
}
}
}

companion object {
private val TAG = ConnectionStatusFragment::class.java.name
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ class OrganizationSelectionFragment : BaseFragment<FragmentOrganizationSelection
viewModel.parentAction.observe(viewLifecycleOwner) { parentAction ->
when (parentAction) {
is BaseConnectionViewModel.ParentAction.DisplayError -> {
ErrorDialog.show(requireActivity(), parentAction.title, parentAction.message)
activity?.let { activity ->
ErrorDialog.show(activity, parentAction.title, parentAction.message)
}
}
is BaseConnectionViewModel.ParentAction.ShowContextCanceledToast -> {
Snackbar.make(view, parentAction.message, Snackbar.LENGTH_LONG).show()
Expand All @@ -143,7 +145,9 @@ class OrganizationSelectionFragment : BaseFragment<FragmentOrganizationSelection
viewModel.viewModelScope.launch {
viewModel.error.collectLatest { exception ->
if (exception != null) {
ErrorDialog.show(requireActivity(), exception)
activity?.let { activity ->
ErrorDialog.show(activity, exception)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class ApplicationModule(private val application: EduVPNApplication) {
fun provideConnectionTimeLiveData(
vpnService: VPNService,
@Named("timer") timer: LiveData<Unit>
): LiveData<Long?> {
): LiveData<Long> {
return ConnectionTimeLiveData.create(vpnService, timer)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ object ConnectionTimeLiveData {
fun create(
vpnStatusLiveData: LiveData<VPNService.VPNStatus>,
timer: LiveData<Unit>
): LiveData<Long?> {
): LiveData<Long> {
var connectionTime = 0L

val connectionTimeLiveData = MediatorLiveData<Long?>()
val connectionTimeLiveData = MediatorLiveData<Long>()

val update = {
connectionTimeLiveData.value = (System.currentTimeMillis() - connectionTime) / 1000L
Expand All @@ -52,7 +52,7 @@ object ConnectionTimeLiveData {
}
} else if (vpnStatus == VPNService.VPNStatus.DISCONNECTED) {
connectionTimeLiveData.removeSource(timer)
connectionTimeLiveData.value = null
connectionTimeLiveData.value = -1
}
}

Expand Down
5 changes: 2 additions & 3 deletions app/src/main/java/nl/eduvpn/app/service/BackendService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,12 @@ class BackendService(
return true
}

@kotlin.jvm.Throws(CommonException::class, UnknownFormatException::class)
suspend fun getAddedServers(): AddedServers = withContext(Dispatchers.IO) {
fun getAddedServers(): AddedServers {
val dataErrorTuple = goBackend.addedServers
if (dataErrorTuple.isError) {
throw CommonException(dataErrorTuple.error)
}
serializerService.deserializeAddedServers(dataErrorTuple.data)
return serializerService.deserializeAddedServers(dataErrorTuple.data)
}

@kotlin.jvm.Throws(CommonException::class, UnknownFormatException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,17 @@ public void startForeground(int id, @NonNull Notification notification) {
*/
public void disconnect() {
try {
_openVPNService.stopVPN(false);
if (_openVPNService == null) {
ConnectionStatus previousStatus = _connectionStatus;
_connectionStatus = ConnectionStatus.LEVEL_NOTCONNECTED;
if (previousStatus != _connectionStatus) {
_updatesHandler.post(() -> {
setValue(connectionStatusToVPNStatus(_connectionStatus));
});
}
} else {
_openVPNService.stopVPN(false);
}
} catch (RemoteException ex) {
Log.e(TAG, "Exception when trying to stop connection. Connection might not be closed!", ex);
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/nl/eduvpn/app/service/HistoryService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class HistoryService(private val backendService: BackendService) {
* Loads the state of the service.
*/
@kotlin.jvm.Throws(Exception::class)
suspend fun load() {
fun load() {
try {
addedServers = backendService.getAddedServers()
notifyListeners()
Expand Down Expand Up @@ -90,7 +90,7 @@ class HistoryService(private val backendService: BackendService) {
* @param instance The instance to remove the data for.
*/
@Throws(CommonException::class)
suspend fun removeAllDataForInstance(instance: Instance) {
fun removeAllDataForInstance(instance: Instance) {
backendService.removeServer(instance)
load()
notifyListeners()
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/nl/eduvpn/app/utils/ErrorDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ object ErrorDialog {
putString(ErrorDialogFragment.ARGS_KEY_TITLE, title)
putString(ErrorDialogFragment.ARGS_KEY_MESSAGE, message)
}
dialog.show(activity.supportFragmentManager, null)
if (!activity.isFinishing && !activity.supportFragmentManager.isStateSaved) {
dialog.show(activity.supportFragmentManager, null)
}
return dialog
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import nl.eduvpn.app.livedata.toSingleEvent
import nl.eduvpn.app.service.*
import nl.eduvpn.app.utils.Log
import nl.eduvpn.app.utils.runCatchingCoroutine
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

/**
Expand Down Expand Up @@ -142,17 +140,6 @@ abstract class BaseConnectionViewModel(
}
}

private fun <T> showError(thr: Throwable?, resourceId: Int): Result<T> {
val message = context.getString(resourceId, thr)
Log.e(TAG, message, thr)
connectionState.value = ConnectionState.Ready
_parentAction.value = ParentAction.DisplayError(
R.string.error_dialog_title,
message
)
return Result.failure(thr ?: RuntimeException(message))
}

fun disconnectWithCall(vpnService: VPNService) {
vpnConnectionService.disconnect(context, vpnService)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ConnectionStatusViewModel @Inject constructor(
@Named("timer")
val timer: LiveData<Unit>,
@Named("connectionTimeLiveData")
val connectionTimeLiveData: LiveData<Long?>,
val connectionTimeLiveData: LiveData<Long>,
private val backendService: BackendService,
vpnConnectionService: VPNConnectionService,
) : BaseConnectionViewModel(
Expand Down
12 changes: 5 additions & 7 deletions app/src/main/java/nl/eduvpn/app/viewmodel/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,11 @@ class MainViewModel @Inject constructor(
_mainParentAction.postValue(MainParentAction.OnProxyGuardReady)
}
)
viewModelScope.launch(Dispatchers.IO) {
try {
historyService.load()
} catch (ex: Exception) {
Log.w(TAG, "Could not load history from the common backend on initialization!", ex)
_mainParentAction.postValue(MainParentAction.ShowError(ex))
}
try {
historyService.load()
} catch (ex: Exception) {
Log.w(TAG, "Could not load history from the common backend on initialization!", ex)
_mainParentAction.postValue(MainParentAction.ShowError(ex))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,21 @@ class ServerSelectionViewModel @Inject constructor(

private fun refresh() {
viewModelScope.launch(Dispatchers.IO) {
println("XXX Starting refresh")
try {
historyService.removeListener(this@ServerSelectionViewModel)
historyService.load()
historyService.addListener(this@ServerSelectionViewModel)

println("XXX Added server in SSM ${historyService.addedServers?.customServers}")
val needsServerList = historyService.addedServers?.secureInternetServer != null
if (needsServerList) {
refreshServerList()
} else {
refreshInstances()
}
} catch (ex: Exception) {
Log.w(TAG, "XXX Could not refresh server selection list", ex)
_parentAction.postValue(ParentAction.DisplayError(R.string.error_dialog_title, ex.message ?: ex.toString()))
}
}
Expand Down

0 comments on commit 471eb14

Please sign in to comment.