Add expert option to save logs
This commit is contained in:
parent
374ba8b64f
commit
1a7fc5f028
6 changed files with 77 additions and 6 deletions
|
@ -54,6 +54,16 @@
|
|||
<!-- Used to authenticate saving a new recovery code -->
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
|
||||
<!-- This is needed to query content providers in other users -->
|
||||
<uses-permission
|
||||
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<!-- Used to get logcat for system part of backup API, gets permission dialog -->
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_LOGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<!-- Permission used to open settings -->
|
||||
<permission
|
||||
android:name="com.stevesoltys.seedvault.OPEN_SETTINGS"
|
||||
|
@ -64,11 +74,6 @@
|
|||
android:name="com.stevesoltys.seedvault.RESTORE_BACKUP"
|
||||
android:protectionLevel="system|signature" />
|
||||
|
||||
<!-- This is needed to query content providers in other users -->
|
||||
<uses-permission
|
||||
android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
|
|
|
@ -1,15 +1,35 @@
|
|||
package com.stevesoltys.seedvault.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.permitDiskReads
|
||||
import com.stevesoltys.seedvault.transport.backup.PackageService
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class ExpertSettingsFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private val viewModel: SettingsViewModel by sharedViewModel()
|
||||
private val packageService: PackageService by inject()
|
||||
// TODO set mimeType when upgrading androidx lib
|
||||
private val createFileLauncher = registerForActivityResult(CreateDocument()) { uri ->
|
||||
viewModel.onLogcatUriReceived(uri)
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
permitDiskReads {
|
||||
setPreferencesFromResource(R.xml.settings_expert, rootKey)
|
||||
}
|
||||
findPreference<Preference>("logcat")?.setOnPreferenceClickListener {
|
||||
val versionName = packageService.getVersionName(requireContext().packageName) ?: "ver"
|
||||
val timestamp = System.currentTimeMillis()
|
||||
val name = "seedvault-$versionName-$timestamp.txt"
|
||||
createFileLauncher.launch(name)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.net.Network
|
|||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import android.net.Uri
|
||||
import android.os.Process.myUid
|
||||
import android.provider.Settings
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
|
@ -35,8 +36,11 @@ import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel
|
|||
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.calyxos.backup.storage.api.StorageBackup
|
||||
import org.calyxos.backup.storage.backup.BackupJobService
|
||||
import java.io.IOException
|
||||
import java.lang.Runtime.getRuntime
|
||||
import java.util.concurrent.TimeUnit.HOURS
|
||||
|
||||
private const val TAG = "SettingsViewModel"
|
||||
|
@ -233,4 +237,28 @@ internal class SettingsViewModel(
|
|||
BackupJobService.cancelJob(app)
|
||||
}
|
||||
|
||||
fun onLogcatUriReceived(uri: Uri?) = viewModelScope.launch(Dispatchers.IO) {
|
||||
if (uri == null) {
|
||||
onLogcatError()
|
||||
return@launch
|
||||
}
|
||||
// 1000 is system uid, needed to get backup logs from the OS code.
|
||||
val command = "logcat -d --uid=1000,${myUid()} *:V"
|
||||
try {
|
||||
app.contentResolver.openOutputStream(uri, "wt")?.use { outputStream ->
|
||||
getRuntime().exec(command).inputStream.use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
} ?: throw IOException("OutputStream was null")
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error saving logcat ", e)
|
||||
onLogcatError()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun onLogcatError() = withContext(Dispatchers.Main) {
|
||||
val str = app.getString(R.string.settings_expert_logcat_error)
|
||||
Toast.makeText(app, str, LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/ic_bug_report.xml
Normal file
10
app/src/main/res/drawable/ic_bug_report.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z" />
|
||||
</vector>
|
|
@ -46,6 +46,9 @@
|
|||
<string name="settings_expert_title">Expert settings</string>
|
||||
<string name="settings_expert_quota_title">Unlimited app quota</string>
|
||||
<string name="settings_expert_quota_summary">Do not impose a limitation on the size of app backups.\n\nWarning: This can fill up your storage location quickly. Not needed for most apps.</string>
|
||||
<string name="settings_expert_logcat_title">Save app log</string>
|
||||
<string name="settings_expert_logcat_summary">Developers can diagnose bugs with these logs.\n\nWarning: The log file might contain personally identifiable information. Review before and delete after sharing!</string>
|
||||
<string name="settings_expert_logcat_error">Error: Could not save app log</string>
|
||||
|
||||
<!-- Storage Location -->
|
||||
<string name="storage_fragment_backup_title">Choose where to store backups</string>
|
||||
|
|
|
@ -5,4 +5,9 @@
|
|||
android:key="unlimited_quota"
|
||||
android:summary="@string/settings_expert_quota_summary"
|
||||
android:title="@string/settings_expert_quota_title" />
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
android:icon="@drawable/ic_bug_report"
|
||||
android:key="logcat"
|
||||
android:summary="@string/settings_expert_logcat_summary"
|
||||
android:title="@string/settings_expert_logcat_title" />
|
||||
</PreferenceScreen>
|
||||
|
|
Loading…
Reference in a new issue