Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify lockdown limitations in guide #6293

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Line wrap the file at 100 chars. Th
### Security
- Fix DNS leaks in blocking states or when no valid DNS has been configured due to an underlying OS
issue. In these cases a dummy DNS will be set to prevent leaks.
- Clarify lockdown limitations in the in-app guide.


## [android/2024.2-beta1] - 2024-04-17
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.mullvad.mullvadvpn.compose.screen

import android.net.Uri
import androidx.annotation.StringRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
Expand All @@ -16,6 +18,7 @@ import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerState
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
Expand All @@ -31,8 +34,14 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.UrlAnnotation
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.constraintlayout.compose.ConstrainedLayoutReference
import androidx.constraintlayout.compose.ConstraintLayout
Expand All @@ -46,12 +55,15 @@ import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
import net.mullvad.mullvadvpn.compose.component.ScaffoldWithLargeTopBarAndButton
import net.mullvad.mullvadvpn.compose.extensions.toAnnotatedString
import net.mullvad.mullvadvpn.compose.transitions.SlideInFromRightTransition
import net.mullvad.mullvadvpn.lib.common.util.openLink
import net.mullvad.mullvadvpn.lib.common.util.openVpnSettings
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens
import net.mullvad.mullvadvpn.lib.theme.color.AlphaDescription
import net.mullvad.mullvadvpn.lib.theme.color.AlphaInvisible
import net.mullvad.mullvadvpn.lib.theme.color.AlphaVisible
import net.mullvad.mullvadvpn.service.constant.IS_PLAY_BUILD
import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild

@Preview
@Composable
Expand Down Expand Up @@ -87,7 +99,8 @@ fun AutoConnectAndLockdownModeScreen(onBackClick: () -> Unit = {}) {
pagerState = pagerState,
backButtonRef = backButtonRef,
nextButtonRef = nextButtonRef,
pager = pager
pager = pager,
onOpenUrl = { url -> context.openLink(Uri.parse(url)) }
)

// Go to previous page
Expand Down Expand Up @@ -131,17 +144,18 @@ fun AutoConnectAndLockdownModeScreen(onBackClick: () -> Unit = {}) {
)
}
}
}
},
)
}

@OptIn(ExperimentalFoundationApi::class)
@OptIn(ExperimentalFoundationApi::class, ExperimentalTextApi::class)
@Composable
private fun ConstraintLayoutScope.AutoConnectCarousel(
pagerState: PagerState,
backButtonRef: ConstrainedLayoutReference,
nextButtonRef: ConstrainedLayoutReference,
pager: ConstrainedLayoutReference
pager: ConstrainedLayoutReference,
onOpenUrl: (String) -> Unit
) {
HorizontalPager(
state = pagerState,
Expand All @@ -152,32 +166,27 @@ private fun ConstraintLayoutScope.AutoConnectCarousel(
start.linkTo(backButtonRef.end)
end.linkTo(nextButtonRef.start)
bottom.linkTo(parent.bottom)
}
) { page ->
},
) { pageIndex ->
val page = PAGES.entries[pageIndex]
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
Text(
val annotatedTopText = page.annotatedTopText()
ClickableText(
modifier = Modifier.padding(horizontal = Dimens.largePadding),
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSecondary,
text =
HtmlCompat.fromHtml(
stringResource(id = PAGES.entries[page].topText),
HtmlCompat.FROM_HTML_MODE_COMPACT
)
.toAnnotatedString(
boldSpanStyle =
SpanStyle(
fontWeight = FontWeight.ExtraBold,
color = MaterialTheme.colorScheme.onPrimary
)
)
text = annotatedTopText,
onClick = {
annotatedTopText.getUrlAnnotations(it, it).let { annotation ->
annotation.firstOrNull()?.item?.url?.let { onOpenUrl(it) }
}
},
)
Image(
modifier = Modifier.padding(top = Dimens.topPadding, bottom = Dimens.bottomPadding),
painter = painterResource(id = PAGES.entries[page].image),
painter = painterResource(id = page.image),
contentDescription = null,
)
Text(
Expand All @@ -186,7 +195,7 @@ private fun ConstraintLayoutScope.AutoConnectCarousel(
color = MaterialTheme.colorScheme.onSecondary,
text =
HtmlCompat.fromHtml(
stringResource(id = PAGES.entries[page].bottomText),
stringResource(id = page.bottomText),
HtmlCompat.FROM_HTML_MODE_COMPACT
)
.toAnnotatedString(
Expand Down Expand Up @@ -255,20 +264,86 @@ private fun ConstraintLayoutScope.PageIndicator(
}
}

private enum class PAGES(val topText: Int, val image: Int, val bottomText: Int) {
@Composable
private fun buildTopText(@StringRes id: Int) = buildAnnotatedString {
withStyle(
style = SpanStyle(color = MaterialTheme.colorScheme.onSecondary),
) {
append(
HtmlCompat.fromHtml(stringResource(id = id), HtmlCompat.FROM_HTML_MODE_COMPACT)
.toAnnotatedString(
boldSpanStyle =
SpanStyle(
fontWeight = FontWeight.ExtraBold,
color = MaterialTheme.colorScheme.onPrimary
)
)
)
}
}

@OptIn(ExperimentalTextApi::class)
@Composable
private fun buildLockdownTopText() = buildAnnotatedString {
append(buildTopText(id = R.string.auto_connect_carousel_third_slide_top_text))
append(" ")

withLink(
UrlAnnotation(
stringResource(id = R.string.lockdown_url).appendHideNavOnPlayBuild(IS_PLAY_BUILD)
)
) {
withStyle(
style =
SpanStyle(
color = MaterialTheme.colorScheme.onPrimary,
textDecoration = TextDecoration.Underline
),
) {
append(
stringResource(
id = R.string.auto_connect_carousel_third_slide_top_text_website_link
)
)
append(".")
}
}
}

// Will be replaced by upstream withLink in Compose UI 1.7.0
@OptIn(ExperimentalTextApi::class)
inline fun <R : Any> AnnotatedString.Builder.withLink(
annotation: UrlAnnotation,
block: AnnotatedString.Builder.() -> R
): R {
val index = pushUrlAnnotation(annotation)
return try {
block(this)
} finally {
pop(index)
}
}

private enum class PAGES(
val annotatedTopText: @Composable () -> AnnotatedString,
val image: Int,
val bottomText: Int
) {
FIRST(
R.string.auto_connect_carousel_first_slide_top_text,
annotatedTopText =
@Composable { buildTopText(id = R.string.auto_connect_carousel_first_slide_top_text) },
R.drawable.carousel_slide_1_cogwheel,
R.string.auto_connect_carousel_first_slide_bottom_text
R.string.auto_connect_carousel_first_slide_bottom_text,
),
SECOND(
R.string.auto_connect_carousel_second_slide_top_text,
annotatedTopText =
@Composable { buildTopText(id = R.string.auto_connect_carousel_second_slide_top_text) },
R.drawable.carousel_slide_2_always_on,
R.string.auto_connect_carousel_second_slide_bottom_text
),
THIRD(
R.string.auto_connect_carousel_third_slide_top_text,
annotatedTopText = @Composable { buildLockdownTopText() },
R.drawable.carousel_slide_3_block_connections,
R.string.auto_connect_carousel_third_slide_bottom_text
R.string.auto_connect_carousel_third_slide_bottom_text,
)
}
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">Indstillingerne for automatisk forbindelse og Lockdown-tilstand kan findes i Android- systemindstillingerne. Følg denne vejledning for at aktivere en eller begge.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. For at aktivere automatisk forbindelse skal du klikke på knappen ud for &lt;b&gt;Altid-til VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_second_slide_top_text">Auto-tilslutning kaldes Altid-til VPN i Android-systemindstillingerne, og det sørger for, at du konstant er forbundet til VPN-tunnelen og automatisk forbinder efter genstart.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. For at aktivere Lockdown-tilstand skal du klikke på knappen ud for &lt;b&gt;Bloker forbindelser uden VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_third_slide_top_text">Lockdown-tilstand blokerer al internetadgang, hvis VPN-tunnelen afbrydes manuelt. &lt;br/&gt;&lt;b&gt;Advarsel: Denne indstilling blokerer opdelte apps og funktionen Lokal netværksdeling&lt;/b&gt;.</string>
<string name="auto_connect_footer">Opret automatisk forbindelse til en server, når appen starter.</string>
<string name="auto_connect_footer_legacy">Brug systemindstillingen &lt;b&gt;Altid til&lt;/b&gt; i stedet ved at følge vejledningen i &lt;b&gt;%1$s&lt;/b&gt; ovenfor.</string>
<string name="auto_connect_legacy">Automatisk forbindelse (ældre metode)</string>
Expand Down
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">Die Einstellungen für die automatische Verbindung und den Sperrmodus finden Sie in den Android-Systemeinstellungen. Folgen Sie dieser Anleitung, um eine oder beide Einstellungen zu aktivieren.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. Um die automatische Verbindung zu aktivieren, klicken Sie auf den Kippschalter neben &lt;b&gt;Always-on VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_second_slide_top_text">Die automatische Verbindung wird in den Android-Systemeinstellungen als „Always-on VPN“ bezeichnet und sorgt dafür, dass Sie ständig mit dem VPN-Tunnel verbunden sind und sich nach einem Neustart automatisch verbinden.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. Um den Sperrmodus zu aktivieren, klicken Sie auf den Kippschalter neben &lt;b&gt;Verbindungen ohne VPN sperren&lt;/b&gt;.</string>
<string name="auto_connect_carousel_third_slide_top_text">Der Sperrmodus blockiert den gesamten Internetzugang, wenn die Verbindung zum VPN-Tunnel manuell unterbrochen wird. &lt;br/&gt;&lt;b&gt;Warnung: Diese Einstellung blockiert geteilte Anwendungen und das Teilen im lokalen Netzwerk&lt;/b&gt;.</string>
<string name="auto_connect_footer">Stellt automatisch eine Verbindung zum Server her, wenn die App startet.</string>
<string name="auto_connect_footer_legacy">Bitte verwenden Sie stattdessen die Systemeinstellung &lt;b&gt;Always-on (Durchgehend aktiv)&lt;/b&gt;, indem Sie die Anleitung oben unter &lt;b&gt;%1$s&lt;/b&gt; befolgen.</string>
<string name="auto_connect_legacy">Automatische Verbindung (veraltet)</string>
Expand Down
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">La configuración del modo de bloqueo y de la conexión automática puede encontrarse en la configuración del sistema Android, siga esta guía para habilitar uno o ambos.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. Para habilitar la conexión automática, haga clic en el botón &lt;b&gt;VPN siempre activa&lt;/b&gt;.</string>
<string name="auto_connect_carousel_second_slide_top_text">La conexión automática se llama VPN siempre activa en la configuración del sistema Android y asegura estar conectado constantemente al túnel de la VPN y conectarse automáticamente después de cada reinicio.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. Para habilitar el modo de bloqueo, haga clic en el botón situado junto a &lt;b&gt;Bloquear conexiones sin VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_third_slide_top_text">El modo de bloqueo bloquea todo el acceso a Internet si el túnel de la VPN está desconectado manualmente. &lt;br/&gt;&lt;b&gt;Advertencia: Este ajuste bloquea las aplicaciones divididas y la opción Uso compartido de la red local&lt;/b&gt;.</string>
<string name="auto_connect_footer">Al iniciarse la aplicación, se conecta automáticamente a un servidor.</string>
<string name="auto_connect_footer_legacy">En su lugar, utilice el ajuste de sistema &lt;b&gt;Siempre activado&lt;/b&gt; siguiendo arriba la guía en &lt;b&gt;%1$s&lt;/b&gt;.</string>
<string name="auto_connect_legacy">Conexión automática (heredada)</string>
Expand Down
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-fi/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">Automaattisen yhdistämisen ja lukitustilan asetukset löytyvät Androidin järjestelmäasetuksista. Voit ottaa jommankumman tai molemmat käyttöön tämän oppaan ohjeilla.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. Ota automaattinen yhteyden muodostus käyttöön napsauttamalla &lt;b&gt;Aina päällä oleva VPN&lt;/b&gt; -kohdan vieressä olevaa valintapainiketta.</string>
<string name="auto_connect_carousel_second_slide_top_text">Automaattista yhdistämistä kutsutaan aina päällä olevaksi VPN-yhteydeksi Androidin järjestelmäasetuksissa. Se varmistaa, että olet jatkuvasti yhteydessä VPN-tunneliin, sekä muodostaa yhteyden automaattisesti aina uudelleenkäynnistyksen jälkeen.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. Ota lukitustila käyttöön napsauttamalla &lt;b&gt;Estä yhteydet ilman VPN:ää&lt;/b&gt; -kohdan vierestä löytyvää valintapainiketta.</string>
<string name="auto_connect_carousel_third_slide_top_text">Lukitustila estää kaikki verkkoyhteydet, jos yhteys VPN-tunneliin katkaistaan manuaalisesti. &lt;br/&gt;&lt;b&gt;Varoitus: asetus estää sovelluskohtaisesti yhdistettävät sovellukset ja paikallisen verkon jakamisominaisuuden&lt;/b&gt;.</string>
<string name="auto_connect_footer">Muodosta yhteys palvelimeen automaattisesti, kun sovellus avataan.</string>
<string name="auto_connect_footer_legacy">Käytä &lt;b&gt;aina käytössä&lt;/b&gt; -järjestelmäasetusta seuraamalla ylhäältä löytyvää opasta aiheesta &lt;b&gt;%1$s&lt;/b&gt;.</string>
<string name="auto_connect_legacy">Autom. yhdistäminen (vanha järjestelmä)</string>
Expand Down
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">Les paramètres de la connexion automatique et du mode Verrouillage se trouvent dans les paramètres du système Android, suivez ce guide pour activer l\'un, l\'autre ou les deux.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. Pour activer la connexion automatique, cliquez sur l\'interrupteur situé à côté de &lt;b&gt;VPN toujours actif&lt;/b&gt;.</string>
<string name="auto_connect_carousel_second_slide_top_text">La connexion automatique est appelée VPN toujours actif dans les paramètres du système Android et elle s\'assure que vous êtes constamment connecté au tunnel VPN et se connecte automatiquement après le redémarrage.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. Pour activer le mode Verrouillage, cliquez sur l\'interrupteur situé à côté de &lt;b&gt;Bloquer les connexions sans VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_third_slide_top_text">Le mode Verrouillage bloque tout accès à Internet si le tunnel VPN est déconnecté manuellement. &lt;br/&gt;&lt;b&gt;Avertissement : Ce paramètre bloque les applications fractionnées et la fonctionnalité de partage du réseau local&lt;/b&gt;.</string>
<string name="auto_connect_footer">Connexion automatique à un serveur dès le démarrage de l\'application.</string>
<string name="auto_connect_footer_legacy">Veuillez utiliser le paramètre système &lt;b&gt;Toujours activé&lt;/b&gt; en suivant le guide dans &lt;b&gt;%1$s&lt;/b&gt; ci-dessus.</string>
<string name="auto_connect_legacy">Connexion automatique (obsolète)</string>
Expand Down
2 changes: 0 additions & 2 deletions android/lib/resource/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
<string name="auto_connect_carousel_first_slide_top_text">Le impostazioni della modalità di Connessione automatica e di Blocco si trovano nelle impostazioni del sistema Android. Segui questa guida per abilitare una o entrambe.</string>
<string name="auto_connect_carousel_second_slide_bottom_text">2. Per abilitare la connessione automatica, clicca sull\'interruttore accanto a &lt;b&gt;VPN sempre attiva&lt;/b&gt;.</string>
<string name="auto_connect_carousel_second_slide_top_text">La connessione automatica è denominata VPN sempre attiva nelle impostazioni del sistema Android e garantisce di essere costantemente connessi al tunnel VPN e di connettersi automaticamente dopo il riavvio.</string>
<string name="auto_connect_carousel_third_slide_bottom_text">3. Per abilitare la modalità di blocco, clicca sull\'interruttore accanto a &lt;b&gt;Blocca connessioni senza VPN&lt;/b&gt;.</string>
<string name="auto_connect_carousel_third_slide_top_text">La modalità Blocco blocca tutti gli accessi a Internet se il tunnel VPN viene disconnesso manualmente. &lt;br/&gt;&lt;b&gt;Avviso: questa impostazione blocca le app divise e la funzione di condivisione della rete locale&lt;/b&gt;.</string>
<string name="auto_connect_footer">Connettiti automaticamente al server all\'avvio dell\'app.</string>
<string name="auto_connect_footer_legacy">Utilizza piuttosto l\'impostazione di sistema &lt;b&gt;Sempre attivo&lt;/b&gt; seguendo la guida in &lt;b&gt;%1$s&lt;/b&gt; sopra.</string>
<string name="auto_connect_legacy">Connessione automatica (precedente)</string>
Expand Down
Loading
Loading