summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-06-26 17:13:49 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-07-01 20:22:03 +0000
commit5bf48b1125b520ffa39ac13075c8d56fd5c91c6b (patch)
tree8b8e5e894a8810dfa012a962609e4cc48d30a799 /android/src
parent61fcd8bec8f84e7c4278f28ffc6c5fafdb30c5e5 (diff)
downloadmullvadvpn-5bf48b1125b520ffa39ac13075c8d56fd5c91c6b.tar.xz
mullvadvpn-5bf48b1125b520ffa39ac13075c8d56fd5c91c6b.zip
Remove old `NotificationBanner` controller
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NotificationBanner.kt284
1 files changed, 0 insertions, 284 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NotificationBanner.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NotificationBanner.kt
deleted file mode 100644
index efb27bc4d7..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/NotificationBanner.kt
+++ /dev/null
@@ -1,284 +0,0 @@
-package net.mullvad.mullvadvpn.ui
-
-import android.content.Context
-import android.content.Intent
-import android.graphics.drawable.Drawable
-import android.net.Uri
-import android.view.View
-import android.widget.ImageView
-import android.widget.TextView
-import kotlin.properties.Delegates.observable
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache
-import net.mullvad.mullvadvpn.model.KeygenEvent
-import net.mullvad.mullvadvpn.model.TunnelState
-import net.mullvad.mullvadvpn.service.MullvadDaemon
-import net.mullvad.mullvadvpn.util.TimeLeftFormatter
-import net.mullvad.talpid.tunnel.ActionAfterDisconnect
-import net.mullvad.talpid.tunnel.ErrorState
-import net.mullvad.talpid.tunnel.ErrorStateCause
-import net.mullvad.talpid.tunnel.ParameterGenerationError
-import org.joda.time.DateTime
-
-class NotificationBanner(
- val parentView: View,
- val context: Context,
- val versionInfoCache: AppVersionInfoCache,
- val daemon: MullvadDaemon
-) {
- enum class ExternalLink {
- BuyMoreTime,
- Download,
- KeyManagement
- }
-
- private val resources = context.resources
- private val timeLeftFormatter = TimeLeftFormatter(resources)
-
- private val buyMoreTimeUrl = context.getString(R.string.account_url)
- private val downloadUrl = Uri.parse(context.getString(R.string.download_url))
- private val keyManagementUrl = context.getString(R.string.wg_key_url)
-
- private val errorImage = resources.getDrawable(R.drawable.icon_notification_error, null)
- private val warningImage = resources.getDrawable(R.drawable.icon_notification_warning, null)
-
- private val banner: View = parentView.findViewById(R.id.notification_banner)
- private val status: ImageView = parentView.findViewById(R.id.notification_status)
- private val title: TextView = parentView.findViewById(R.id.notification_title)
- private val message: TextView = parentView.findViewById(R.id.notification_message)
- private val icon: View = parentView.findViewById(R.id.notification_icon)
-
- private var updateJob: Job? = null
-
- private var externalLink: ExternalLink? = null
- private var visible = false
-
- private val clickController = BlockingController(
- object : BlockableView {
- override fun setEnabled(enabled: Boolean) {
- if (enabled) {
- banner.setAlpha(1f)
- banner.setClickable(true)
- } else {
- banner.setAlpha(0.5f)
- banner.setClickable(false)
- }
- }
-
- override fun onClick() = GlobalScope.launch(Dispatchers.Default) {
- buildUrl()?.let { url ->
- context.startActivity(Intent(Intent.ACTION_VIEW, url))
- }
- }
-
- private fun buildUrl() = when (externalLink) {
- ExternalLink.BuyMoreTime -> Uri.parse(buyMoreTimeUrl + buildUrlTokenParameter())
- ExternalLink.Download -> downloadUrl
- ExternalLink.KeyManagement -> Uri.parse(keyManagementUrl + buildUrlTokenParameter())
- null -> null
- }
-
- private fun buildUrlTokenParameter() = "?token=${daemon.getWwwAuthToken()}"
- }
- )
-
- var accountExpiry by observable<DateTime?>(null) { _, _, _ -> update() }
- var keyState by observable<KeygenEvent?>(null) { _, _, _ -> update() }
- var tunnelState by observable<TunnelState>(TunnelState.Disconnected()) { _, _, _ -> update() }
-
- init {
- banner.setOnClickListener { clickController.action() }
- }
-
- fun onResume() {
- versionInfoCache.onUpdate = {
- updateJob = GlobalScope.launch(Dispatchers.Main) { update() }
- }
- }
-
- fun onPause() {
- versionInfoCache.onUpdate = null
- updateJob?.cancel()
- clickController.onPause()
- }
-
- private fun update() {
- externalLink = null
-
- updateBasedOnTunnelState() ||
- updateBasedOnKeyState() ||
- updateBasedOnVersionInfo() ||
- updateBasedOnAccountExpiry()
- }
-
- private fun updateBasedOnKeyState(): Boolean {
- val keyState = keyState
- when (keyState) {
- null -> return false
- is KeygenEvent.NewKey -> return false
- is KeygenEvent.TooManyKeys -> {
- externalLink = ExternalLink.KeyManagement
- showError(R.string.wireguard_error, R.string.too_many_keys)
- }
- is KeygenEvent.GenerationFailure -> {
- showError(R.string.wireguard_error, R.string.failed_to_generate_key)
- }
- }
-
- return true
- }
-
- private fun updateBasedOnTunnelState(): Boolean {
- val state = tunnelState
-
- when (state) {
- is TunnelState.Disconnecting -> {
- when (state.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> return false
- ActionAfterDisconnect.Block -> showBlocking(null)
- ActionAfterDisconnect.Reconnect -> showBlocking(null)
- }
- }
- is TunnelState.Disconnected -> return false
- is TunnelState.Connecting -> showBlocking(null)
- is TunnelState.Connected -> return false
- is TunnelState.Error -> showBlocking(state.errorState)
- }
-
- return true
- }
-
- private fun updateBasedOnVersionInfo(): Boolean {
- if (versionInfoCache.isOutdated || !versionInfoCache.isSupported) {
- val title: Int
- val statusImage: Drawable
- val template: Int
-
- if (versionInfoCache.isSupported) {
- title = R.string.update_available
- template = R.string.update_available_description
- statusImage = warningImage
- } else {
- title = R.string.unsupported_version
- template = R.string.unsupported_version_description
- statusImage = errorImage
- }
-
- val parameter = versionInfoCache.upgradeVersion
- val description = context.getString(template, parameter)
-
- externalLink = ExternalLink.Download
-
- show(statusImage, title, description)
-
- return true
- } else {
- return false
- }
- }
-
- private fun updateBasedOnAccountExpiry(): Boolean {
- val expiry = accountExpiry
- val threeDaysFromNow = DateTime.now().plusDays(3)
-
- if (expiry != null && expiry.isBefore(threeDaysFromNow)) {
- val timeLeft = timeLeftFormatter.format(expiry)
-
- externalLink = ExternalLink.BuyMoreTime
-
- show(warningImage, R.string.account_credit_expires_soon, timeLeft)
- } else {
- hide()
- }
-
- return true
- }
-
- private fun showBlocking(errorState: ErrorState?) {
- val cause = errorState?.cause
-
- val messageText = when (cause) {
- null -> null
- is ErrorStateCause.AuthFailed -> R.string.auth_failed
- is ErrorStateCause.Ipv6Unavailable -> R.string.ipv6_unavailable
- is ErrorStateCause.SetFirewallPolicyError -> R.string.set_firewall_policy_error
- is ErrorStateCause.SetDnsError -> R.string.set_dns_error
- is ErrorStateCause.StartTunnelError -> R.string.start_tunnel_error
- is ErrorStateCause.IsOffline -> R.string.is_offline
- is ErrorStateCause.TapAdapterProblem -> R.string.tap_adapter_problem
- is ErrorStateCause.TunnelParameterError -> {
- when (cause.error) {
- ParameterGenerationError.NoMatchingRelay -> R.string.no_matching_relay
- ParameterGenerationError.NoMatchingBridgeRelay -> {
- R.string.no_matching_bridge_relay
- }
- ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key
- ParameterGenerationError.CustomTunnelHostResultionError -> {
- R.string.custom_tunnel_host_resolution_error
- }
- }
- }
- is ErrorStateCause.VpnPermissionDenied -> R.string.vpn_permission_denied_error
- }
-
- // if the error state is null, we can assume that we are secure
- if (errorState?.isBlocking ?: true) {
- showError(R.string.blocking_internet, messageText)
- } else {
- val updatedMessageText = when (cause) {
- is ErrorStateCause.VpnPermissionDenied -> messageText
- else -> R.string.failed_to_block_internet
- }
-
- showError(R.string.not_blocking_internet, updatedMessageText)
- }
- }
-
- private fun showError(titleText: Int, messageText: Int?) {
- showError(titleText, messageText?.let { context.getString(it) })
- }
-
- private fun showError(titleText: Int, messageText: String?) {
- show(errorImage, titleText, messageText)
- }
-
- private fun show(statusImage: Drawable, titleText: Int, messageText: String?) {
- if (!visible) {
- visible = true
- banner.visibility = View.VISIBLE
- banner.translationY = -banner.height.toFloat()
- banner.animate().translationY(0.0F).setDuration(350).start()
- }
-
- status.setImageDrawable(statusImage)
- title.setText(titleText)
-
- if (messageText == null) {
- message.visibility = View.GONE
- } else {
- message.setText(messageText)
- message.visibility = View.VISIBLE
- }
-
- if (externalLink == null) {
- banner.setClickable(false)
- icon.visibility = View.GONE
- } else {
- banner.setClickable(true)
- icon.visibility = View.VISIBLE
- }
- }
-
- private fun hide() {
- if (visible) {
- visible = false
- banner.animate().translationY(-banner.height.toFloat()).setDuration(350).withEndAction {
- banner.visibility = View.INVISIBLE
- }
- }
- }
-}