summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-11-27 16:21:00 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-11-27 16:21:00 +0100
commit851b1343afa7dfd93547e7836d90e6eb73330d3a (patch)
tree097bc548014714045bf5f497b45e5655bac898bd /android
parenta062df8ccda8ae473fc4bbf0f85840f8b872643c (diff)
parent90689b3f1cdb0ca2aab522a0f007ecd0812bf538 (diff)
downloadmullvadvpn-851b1343afa7dfd93547e7836d90e6eb73330d3a.tar.xz
mullvadvpn-851b1343afa7dfd93547e7836d90e6eb73330d3a.zip
Merge branch 'crash-when-clicking-share-button-droid-518'
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/AndroidManifest.xml7
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt41
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/provider/MullvadFileProvider.kt59
-rw-r--r--android/app/src/main/res/xml/provider_paths.xml8
-rw-r--r--android/lib/resource/src/main/res/values/strings.xml1
5 files changed, 105 insertions, 11 deletions
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 10b40b9347..8998ff7d7c 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -90,5 +90,12 @@
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
+ <provider android:name="net.mullvad.mullvadvpn.provider.MullvadFileProvider"
+ android:authorities="net.mullvad.mullvadvpn.FileProvider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/provider_paths" />
+ </provider>
</application>
</manifest>
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
index cbe1f6d0b3..7ff8aa11aa 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
@@ -1,7 +1,6 @@
package net.mullvad.mullvadvpn.compose.screen
import android.content.Context
-import android.content.Intent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -15,21 +14,30 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SnackbarHost
+import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
+import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.component.MullvadCircularProgressIndicatorMedium
import net.mullvad.mullvadvpn.compose.component.MullvadMediumTopBar
+import net.mullvad.mullvadvpn.compose.component.MullvadSnackbar
import net.mullvad.mullvadvpn.compose.component.NavigateBackIconButton
import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar
+import net.mullvad.mullvadvpn.compose.util.createCopyToClipboardHandle
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.lib.theme.Dimens
import net.mullvad.mullvadvpn.lib.theme.color.AlphaScrollbar
+import net.mullvad.mullvadvpn.provider.getLogsShareIntent
import net.mullvad.mullvadvpn.viewmodel.ViewLogsUiState
@Preview
@@ -52,13 +60,31 @@ fun ViewLogsScreen(
) {
val context = LocalContext.current
+ val snackbarHostState = remember { SnackbarHostState() }
+ val scope = rememberCoroutineScope()
+ val clipboardHandle = createCopyToClipboardHandle(snackbarHostState = snackbarHostState)
Scaffold(
+ snackbarHost = {
+ SnackbarHost(
+ snackbarHostState,
+ snackbar = { snackbarData -> MullvadSnackbar(snackbarData = snackbarData) }
+ )
+ },
topBar = {
MullvadMediumTopBar(
title = stringResource(id = R.string.view_logs),
navigationIcon = { NavigateBackIconButton(onBackClick) },
actions = {
- IconButton(onClick = { shareText(context, uiState.text()) }) {
+ val clipboardToastMessage = stringResource(R.string.copied_logs_to_clipboard)
+ IconButton(
+ onClick = { clipboardHandle(uiState.text(), clipboardToastMessage) }
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.icon_copy),
+ contentDescription = null
+ )
+ }
+ IconButton(onClick = { scope.launch { shareText(context, uiState.text()) } }) {
Icon(imageVector = Icons.Default.Share, contentDescription = null)
}
}
@@ -101,14 +127,7 @@ fun ViewLogsScreen(
}
}
-private fun shareText(context: Context, text: String) {
- val sendIntent: Intent =
- Intent().apply {
- action = Intent.ACTION_SEND
- putExtra(Intent.EXTRA_TEXT, text)
- type = "text/plain"
- }
- val shareIntent = Intent.createChooser(sendIntent, null)
-
+private fun shareText(context: Context, logContent: String) {
+ val shareIntent = context.getLogsShareIntent("Share logs", logContent)
context.startActivity(shareIntent)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/provider/MullvadFileProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/provider/MullvadFileProvider.kt
new file mode 100644
index 0000000000..c9e7bbe214
--- /dev/null
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/provider/MullvadFileProvider.kt
@@ -0,0 +1,59 @@
+package net.mullvad.mullvadvpn.provider
+
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import androidx.core.content.FileProvider
+import java.io.File
+import net.mullvad.mullvadvpn.R
+import org.joda.time.DateTime
+import org.joda.time.format.ISODateTimeFormat
+
+// https://developer.android.com/reference/androidx/core/content/FileProvider
+// From link: It is possible to use FileProvider directly instead of extending it. However, this is
+// not reliable and will causes crashes on some devices.
+class MullvadFileProvider : FileProvider(R.xml.provider_paths) {
+ companion object {
+ fun uriForFile(context: Context, file: File): Uri {
+ return getUriForFile(context, "net.mullvad.mullvadvpn.FileProvider", file)
+ }
+ }
+}
+
+enum class ProviderCacheDirectory(val directoryName: String) {
+ LOGS("logs")
+}
+
+fun Context.getLogsShareIntent(shareTitle: String, logContent: String): Intent {
+ val fileName = createShareLogFileName()
+ val cacheFile = createCacheFile(ProviderCacheDirectory.LOGS, fileName)
+ cacheFile.writeText(logContent)
+ val logsUri = MullvadFileProvider.uriForFile(this, cacheFile)
+
+ val sendIntent: Intent =
+ Intent().apply {
+ action = Intent.ACTION_SEND
+ type = "text/plain"
+ putExtra(Intent.EXTRA_STREAM, logsUri)
+ addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ }
+ return Intent.createChooser(sendIntent, null)
+}
+
+fun Context.createCacheFile(
+ directory: ProviderCacheDirectory,
+ fileName: String,
+): File {
+ // Path to log file
+ val logsPath = File(cacheDir, directory.directoryName)
+
+ // Ensure path is created
+ logsPath.mkdirs()
+
+ return File(logsPath, fileName)
+}
+
+fun createShareLogFileName(): String {
+ val datetime = ISODateTimeFormat.basicOrdinalDateTimeNoMillis().print(DateTime.now())
+ return "mullvad_log-${datetime}.txt"
+}
diff --git a/android/app/src/main/res/xml/provider_paths.xml b/android/app/src/main/res/xml/provider_paths.xml
new file mode 100644
index 0000000000..921d92f8dd
--- /dev/null
+++ b/android/app/src/main/res/xml/provider_paths.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths>
+ <cache-path
+ name="logs"
+ path="logs/" />
+</paths>
+
+
diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml
index f3b0b0d157..b10dd68ce3 100644
--- a/android/lib/resource/src/main/res/values/strings.xml
+++ b/android/lib/resource/src/main/res/values/strings.xml
@@ -243,4 +243,5 @@
<string name="payment_pending_dialog_message">We are currently verifying your purchase, this might take some time. Your time will be added if the verification is successful.</string>
<string name="loading_connecting">Connecting...</string>
<string name="loading_verifying">Verifying purchase...</string>
+ <string name="copied_logs_to_clipboard">Copied logs to clipboard</string>
</resources>