diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-06-26 17:13:49 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-07-01 20:22:03 +0000 |
| commit | 5bf48b1125b520ffa39ac13075c8d56fd5c91c6b (patch) | |
| tree | 8b8e5e894a8810dfa012a962609e4cc48d30a799 /android/src | |
| parent | 61fcd8bec8f84e7c4278f28ffc6c5fafdb30c5e5 (diff) | |
| download | mullvadvpn-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.kt | 284 |
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 - } - } - } -} |
