diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-22 16:32:48 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2021-04-22 16:32:48 -0300 |
| commit | 218d6f677eaa1dd0d635158fa69e56df9299e8ad (patch) | |
| tree | a6e75ebc3dab3d7f09249172866b1ef813d4b816 /android/src/main | |
| parent | cf6dd6e770c5a4b52908a8595692c9a2a932a490 (diff) | |
| parent | 4035d890540b69bd8e6671dad4e70b62414f2490 (diff) | |
| download | mullvadvpn-218d6f677eaa1dd0d635158fa69e56df9299e8ad.tar.xz mullvadvpn-218d6f677eaa1dd0d635158fa69e56df9299e8ad.zip | |
Merge branch 'split-voucher-redeemer'
Diffstat (limited to 'android/src/main')
9 files changed, 128 insertions, 25 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt index ab71cdc133..c48758230d 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Event.kt @@ -9,6 +9,7 @@ import net.mullvad.mullvadvpn.model.LoginStatus as LoginStatusData import net.mullvad.mullvadvpn.model.RelayList import net.mullvad.mullvadvpn.model.Settings import net.mullvad.mullvadvpn.model.TunnelState +import net.mullvad.mullvadvpn.model.VoucherSubmissionResult as VoucherSubmissionResultData // Events that can be sent from the service sealed class Event : Message.EventMessage() { @@ -48,6 +49,12 @@ sealed class Event : Message.EventMessage() { data class TunnelStateChange(val tunnelState: TunnelState) : Event() @Parcelize + data class VoucherSubmissionResult( + val voucher: String, + val result: VoucherSubmissionResultData + ) : Event() + + @Parcelize data class WireGuardKeyStatus(val keyStatus: KeygenEvent?) : Event() companion object { diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt index 67ae40f187..0f64daece7 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt @@ -87,6 +87,9 @@ sealed class Request : Message.RequestMessage() { data class SetWireGuardMtu(val mtu: Int?) : Request() @Parcelize + data class SubmitVoucher(val voucher: String) : Request() + + @Parcelize data class VpnPermissionResponse(val isGranted: Boolean) : Request() @Parcelize diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt index 9a14c4cf7e..bf96646516 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmission.kt @@ -1,3 +1,7 @@ package net.mullvad.mullvadvpn.model -data class VoucherSubmission(val timeAdded: Long, val newExpiry: String) +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class VoucherSubmission(val timeAdded: Long, val newExpiry: String) : Parcelable diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt index 6978ebba73..7403d66014 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/model/VoucherSubmissionResult.kt @@ -1,9 +1,21 @@ package net.mullvad.mullvadvpn.model -sealed class VoucherSubmissionResult { - class Ok(val submission: VoucherSubmission) : VoucherSubmissionResult() - object InvalidVoucher : VoucherSubmissionResult() - object VoucherAlreadyUsed : VoucherSubmissionResult() - object RpcError : VoucherSubmissionResult() - object OtherError : VoucherSubmissionResult() +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +sealed class VoucherSubmissionResult : Parcelable { + @Parcelize + class Ok(val submission: VoucherSubmission) : VoucherSubmissionResult(), Parcelable + + @Parcelize + object InvalidVoucher : VoucherSubmissionResult(), Parcelable + + @Parcelize + object VoucherAlreadyUsed : VoucherSubmissionResult(), Parcelable + + @Parcelize + object RpcError : VoucherSubmissionResult(), Parcelable + + @Parcelize + object OtherError : VoucherSubmissionResult(), Parcelable } diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt index f251f39340..188f75a0ea 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt @@ -47,6 +47,7 @@ class ServiceEndpoint( val locationInfoCache = LocationInfoCache(this) val relayListListener = RelayListListener(this) val splitTunneling = SplitTunneling(SplitTunnelingPersistence(context), this) + val voucherRedeemer = VoucherRedeemer(this) init { dispatcher.registerHandler(Request.RegisterListener::class) { request -> @@ -68,6 +69,7 @@ class ServiceEndpoint( relayListListener.onDestroy() settingsListener.onDestroy() splitTunneling.onDestroy() + voucherRedeemer.onDestroy() } internal fun sendEvent(event: Event) { diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt new file mode 100644 index 0000000000..6b83b0d333 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt @@ -0,0 +1,40 @@ +package net.mullvad.mullvadvpn.service.endpoint + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ClosedReceiveChannelException +import kotlinx.coroutines.channels.actor +import kotlinx.coroutines.channels.sendBlocking +import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.Request +import net.mullvad.mullvadvpn.model.VoucherSubmissionResult + +class VoucherRedeemer(private val endpoint: ServiceEndpoint) { + private val daemon + get() = endpoint.intermittentDaemon + + private val voucherChannel = spawnActor() + + init { + endpoint.dispatcher.registerHandler(Request.SubmitVoucher::class) { request -> + voucherChannel.sendBlocking(request.voucher) + } + } + + fun onDestroy() { + voucherChannel.close() + } + + private fun spawnActor() = GlobalScope.actor<String>(Dispatchers.Default, Channel.UNLIMITED) { + try { + for (voucher in channel) { + val result = daemon.await().submitVoucher(voucher) + + endpoint.sendEvent(Event.VoucherSubmissionResult(voucher, result)) + } + } catch (exception: ClosedReceiveChannelException) { + // Voucher channel was closed, stop the actor + } + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/RedeemVoucherDialogFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/RedeemVoucherDialogFragment.kt index e5936a1ffb..41cb29498b 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/RedeemVoucherDialogFragment.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/RedeemVoucherDialogFragment.kt @@ -15,8 +15,8 @@ import android.widget.TextView import androidx.fragment.app.DialogFragment import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.model.VoucherSubmissionResult -import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache +import net.mullvad.mullvadvpn.ui.serviceconnection.VoucherRedeemer import net.mullvad.mullvadvpn.ui.widget.Button import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.util.SegmentedInputFormatter @@ -33,14 +33,8 @@ class RedeemVoucherDialogFragment : DialogFragment() { private var accountCache: AccountCache? = null private var accountExpiry: DateTime? = null - private var accountExpiryListener: Int? = null private var redeemButton: Button? = null - - private var daemon: MullvadDaemon? = null - set(value) { - field = value - updateRedeemButton() - } + private var voucherRedeemer: VoucherRedeemer? = null private var voucherInputIsValid = false set(value) { @@ -54,8 +48,6 @@ class RedeemVoucherDialogFragment : DialogFragment() { parentActivity = context as MainActivity parentActivity.serviceNotifier.subscribe(this) { connection -> - daemon = connection?.daemon - accountCache?.onAccountExpiryChange?.unsubscribe(this@RedeemVoucherDialogFragment) accountCache = connection?.accountCache?.apply { @@ -64,6 +56,10 @@ class RedeemVoucherDialogFragment : DialogFragment() { accountExpiry = newAccountExpiry } } + + voucherRedeemer = connection?.voucherRedeemer + + updateRedeemButton() } } @@ -126,25 +122,19 @@ class RedeemVoucherDialogFragment : DialogFragment() { override fun onDetach() { parentActivity.serviceNotifier.unsubscribe(this) - accountExpiryListener?.let { id -> - accountCache?.onAccountExpiryChange?.unsubscribe(id) - } - super.onDetach() } private fun updateRedeemButton() { redeemButton?.apply { - setEnabled(voucherInputIsValid && daemon != null) + setEnabled(voucherInputIsValid && voucherRedeemer != null) } } private suspend fun submitVoucher() { errorMessage.visibility = View.INVISIBLE - val result = jobTracker.runOnBackground { - daemon?.submitVoucher(voucherInput.text.toString()) - } + val result = voucherRedeemer?.submit(voucherInput.text.toString()) when (result) { is VoucherSubmissionResult.Ok -> handleAddedTime(result.submission.timeAdded) diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt index 3034b64073..b17db68b34 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt @@ -43,6 +43,7 @@ class ServiceConnection( val splitTunneling = get<SplitTunneling>( parameters = { parametersOf(service.messenger, dispatcher) } ) + val voucherRedeemer = VoucherRedeemer(service.messenger, dispatcher) val vpnPermission = VpnPermission(service.messenger) val appVersionInfoCache = AppVersionInfoCache(dispatcher, settingsListener) @@ -67,6 +68,7 @@ class ServiceConnection( keyStatusListener.onDestroy() locationInfoCache.onDestroy() settingsListener.onDestroy() + voucherRedeemer.onDestroy() appVersionInfoCache.onDestroy() customDns.onDestroy() diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt new file mode 100644 index 0000000000..d2378100ea --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/VoucherRedeemer.kt @@ -0,0 +1,43 @@ +package net.mullvad.mullvadvpn.ui.serviceconnection + +import android.os.Messenger +import kotlinx.coroutines.CompletableDeferred +import net.mullvad.mullvadvpn.ipc.Event +import net.mullvad.mullvadvpn.ipc.MessageDispatcher +import net.mullvad.mullvadvpn.ipc.Request +import net.mullvad.mullvadvpn.model.VoucherSubmissionResult + +class VoucherRedeemer(val connection: Messenger, eventDispatcher: MessageDispatcher<Event>) { + private val activeSubmissions = + mutableMapOf<String, CompletableDeferred<VoucherSubmissionResult>>() + + init { + eventDispatcher.registerHandler(Event.VoucherSubmissionResult::class) { event -> + synchronized(this@VoucherRedeemer) { + activeSubmissions.remove(event.voucher)?.complete(event.result) + } + } + } + + suspend fun submit(voucher: String): VoucherSubmissionResult { + val result = CompletableDeferred<VoucherSubmissionResult>() + + synchronized(this) { + activeSubmissions.put(voucher, result) + } + + connection.send(Request.SubmitVoucher(voucher).message) + + return result.await() + } + + fun onDestroy() { + synchronized(this) { + for ((_, submission) in activeSubmissions) { + submission.cancel() + } + + activeSubmissions.clear() + } + } +} |
