Added a feature to save logs to local storage (#1741)

- Added export logs to local storage
[1664](https://github.com/tiann/KernelSU/issues/1664)

---------

Co-authored-by: weishu <twsxtd@gmail.com>
This commit is contained in:
Alex
2024-05-23 08:16:44 +05:30
committed by GitHub
parent 4e3f03ae96
commit d6860160e8
46 changed files with 203 additions and 28 deletions

View File

@@ -1,11 +1,17 @@
package me.weishu.kernelsu.ui.screen
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.provider.OpenableColumns
import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -20,25 +26,34 @@ import androidx.compose.material.icons.filled.DeleteForever
import androidx.compose.material.icons.filled.DeveloperMode
import androidx.compose.material.icons.filled.Fence
import androidx.compose.material.icons.filled.RemoveModerator
import androidx.compose.material.icons.filled.Save
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.filled.Update
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.FileProvider
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
@@ -65,12 +80,16 @@ import me.weishu.kernelsu.ui.component.rememberLoadingDialog
import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination
import me.weishu.kernelsu.ui.screen.destinations.FlashScreenDestination
import me.weishu.kernelsu.ui.util.getBugreportFile
import me.weishu.kernelsu.ui.util.getFileNameFromUri
import me.weishu.kernelsu.ui.util.shrinkModules
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
/**
* @author weishu
* @date 2023/1/1.
*/
@OptIn(ExperimentalMaterial3Api::class)
@Destination
@Composable
fun SettingScreen(navigator: DestinationsNavigator) {
@@ -151,6 +170,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
enableWebDebugging = it
}
var showBottomsheet by remember { mutableStateOf(false) }
ListItem(
leadingContent = {
@@ -161,6 +181,74 @@ fun SettingScreen(navigator: DestinationsNavigator) {
},
headlineContent = { Text(stringResource(id = R.string.send_log)) },
modifier = Modifier.clickable {
showBottomsheet = true
}
)
if (showBottomsheet){
ModalBottomSheet(
onDismissRequest = { showBottomsheet = false },
content = {
Row(modifier = Modifier.padding(10.dp)
.align(Alignment.CenterHorizontally)
) {
Box{
Column(
modifier = Modifier.padding(16.dp)
.clickable {
scope.launch {
val bugreport = loadingDialog.withLoading {
withContext(Dispatchers.IO) {
getBugreportFile(context)
}
}
val uri: Uri =
FileProvider.getUriForFile(
context,
"${BuildConfig.APPLICATION_ID}.fileprovider",
bugreport
)
val filename = getFileNameFromUri(context , uri)
val savefile = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/zip"
putExtra(Intent.EXTRA_STREAM, uri)
putExtra(Intent.EXTRA_TITLE, filename)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}
context.startActivity(
Intent.createChooser(
savefile,
context.getString(R.string.save_log)
)
)
}
}
) {
Icon(
Icons.Filled.Save,
contentDescription = null,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Text(
text = stringResource(id = R.string.save_log),
modifier = Modifier.padding(top = 16.dp),
textAlign = TextAlign.Center.also {
LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None
)
}
)
}
}
Box{
Column(
modifier = Modifier.padding(16.dp)
.clickable {
scope.launch {
val bugreport = loadingDialog.withLoading {
withContext(Dispatchers.IO) {
@@ -188,7 +276,32 @@ fun SettingScreen(navigator: DestinationsNavigator) {
)
}
}
) {
Icon(
Icons.Filled.Share,
contentDescription = null,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
Text(
text = stringResource(id = R.string.send_log),
modifier = Modifier.padding(top = 16.dp),
textAlign = TextAlign.Center.also {
LineHeightStyle(
alignment = LineHeightStyle.Alignment.Center,
trim = LineHeightStyle.Trim.None
)
}
)
}
}
}
}
)
}
val shrink = stringResource(id = R.string.shrink_sparse_image)
val shrinkMessage = stringResource(id = R.string.shrink_sparse_image_message)
@@ -237,7 +350,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
}
}
@Composable
fun UninstallItem(
navigator: DestinationsNavigator,

View File

@@ -1,10 +1,14 @@
package me.weishu.kernelsu.ui.util
import android.content.ContentResolver
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Parcelable
import android.os.SystemClock
import android.provider.OpenableColumns
import android.util.Log
import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
@@ -48,6 +52,18 @@ inline fun <T> withNewRootShell(
return createRootShell(globalMnt).use(block)
}
fun getFileNameFromUri(context: Context, uri: Uri): String? {
var fileName: String? = null
val contentResolver: ContentResolver = context.contentResolver
val cursor: Cursor? = contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
fileName = it.getString(it.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME))
}
}
return fileName
}
fun createRootShell(globalMnt: Boolean = false): Shell {
Shell.enableVerboseLogging = BuildConfig.DEBUG
val builder = Shell.Builder.create()

View File

@@ -1,12 +1,16 @@
package me.weishu.kernelsu.ui.util
import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.os.Build
import android.os.ParcelFileDescriptor
import android.system.Os
import com.topjohnwu.superuser.ShellUtils
import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.ui.screen.getManagerVersion
import java.io.File
import java.io.FileOutputStream
import java.io.FileWriter
import java.io.PrintWriter
import java.time.LocalDateTime
@@ -108,3 +112,4 @@ fun getBugreportFile(context: Context): File {
return targetFile
}

View File

@@ -130,4 +130,5 @@
<string name="selected_lkm">صورة lkm المحددة: %s</string>
<string name="settings_restore_stock_image_message">استعادة صورة المصنع المخزنة (في حالة وجود نسخة احتياطية)، والتي تُستخدم عادة قبل OTA؛ إذا كنت بحاجة إلى إلغاء تثبيت KernelSU، فيرجى استخدام \"إلغاء التثبيت الدائم\".</string>
<string name="settings_uninstall_temporary_message">قم بإلغاء تثبيت KernelSU مؤقتًا، واستعد إلى حالته الأصلية بعد إعادة التشغيل التالية.</string>
<string name="save_log">حفظ السجلات</string>
</resources>

View File

@@ -78,4 +78,5 @@
<string name="force_stop_app">Məcburi dayandır</string>
<string name="restart_app">Yenidən başlat</string>
<string name="failed_to_update_sepolicy">%s görə SELinux qaydalarını güncəlləmək mümkün olmadı</string>
<string name="save_log">Girişləri Saxla</string>
</resources>

View File

@@ -48,4 +48,5 @@
<string name="module_uninstall_failed">%s আনইনস্টল করা যায়নি</string>
<string name="module_version">ভার্সন</string>
<string name="module_author">অথার</string>
<string name="save_log">লগ সংরক্ষণ করুন</string>
</resources>

View File

@@ -64,4 +64,5 @@
<string name="profile_namespace_individual">আলাদাভাবে</string>
<string name="profile_umount_modules">আনমাউন্ট মোডিউল</string>
<string name="require_kernel_version">ম্যানেজার সঠিকভাবে কাজ করার জন্য বর্তমান KernelSU সংস্করণ %d খুবই কম। অনুগ্রহ করে %d বা উচ্চতর সংস্করণে আপগ্রেড করুন!</string>
<string name="save_log">লগ সংরক্ষণ করুন</string>
</resources>

View File

@@ -79,4 +79,5 @@
<string name="profile_template">Šablon</string>
<string name="profile_custom">Prilagođeno</string>
<string name="profile_name">Naziv profila</string>
<string name="save_log">Sačuvaj Dnevnike</string>
</resources>

View File

@@ -79,4 +79,5 @@
<string name="profile_selinux_rules">Regler</string>
<string name="restart_app">Genstart</string>
<string name="require_kernel_version">Den nuværende KernelSU version %d er for lav til manageren for at fungere ordentligt. Opgrader til version %d eller højere!</string>
<string name="save_log">Gem Logfiler</string>
</resources>

View File

@@ -117,4 +117,5 @@
<string name="open">Öffnen</string>
<string name="settings_check_update">Updates suchen</string>
<string name="settings_check_update_summary">Automatisch nach Updates suchen beim Öffnen der App</string>
<string name="save_log">Protokolle Speichern</string>
</resources>

View File

@@ -103,4 +103,5 @@
<string name="app_profile_template_delete">Eliminar</string>
<string name="app_profile_template_import_empty">El portapapeles esta vacio!</string>
<string name="app_profile_template_view">Ver plantilla</string>
<string name="save_log">Guardar Registros</string>
</resources>

View File

@@ -108,4 +108,5 @@
<string name="settings_check_update_summary">Rakenduse avamisel kontrolli automaatselt uuendusi</string>
<string name="open">Ava</string>
<string name="enable_web_debugging">Luba WebView silumine</string>
<string name="save_log">Salvesta Logid</string>
</resources>

View File

@@ -63,4 +63,5 @@
<string name="profile_namespace_global">گلوبال</string>
<string name="profile_namespace_individual">تکی</string>
<string name="profile_umount_modules">جداکردن ماژول ها</string>
<string name="save_log">ذخیره گزارش‌ها</string>
</resources>

View File

@@ -66,4 +66,5 @@
<string name="profile_name">Pangalan ng profile</string>
<string name="profile_namespace_inherited">Minana</string>
<string name="settings_umount_modules_default_summary">Ang pangkalahatang default na halaga para sa \"Umount modules\" sa Mga Profile ng App. Kung pinagana, aalisin nito ang lahat ng mga pagbabago sa modyul sa system para sa mga aplikasyon na walang hanay ng Profile.</string>
<string name="save_log">I-save ang mga Log</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="selected_lkm">lkm sélectionné: %s</string>
<string name="settings_uninstall_permanent_message">Désinstallation complète et permanente de KernelSU (root et tous les modules).</string>
<string name="settings_uninstall_temporary_message">Désinstaller KernelSU temporairement et rétablir l\'état original au redémarrage suivant.</string>
<string name="save_log">Enregistrer les Journaux</string>
</resources>

View File

@@ -80,4 +80,5 @@
<string name="about_source_code">%1$s पर स्रोत कोड देखें<br/>हमारे %2$s चैनल से जुड़ें</string>
<string name="home_manager_version">मैनेजर वर्जन</string>
<string name="new_version_available">नया वर्जन: %s उपलब्ध है,अपग्रेड के लिए क्लिक करें</string>
<string name="save_log">लॉग सहेजें</string>
</resources>

View File

@@ -79,4 +79,5 @@
<string name="launch_app">Pokrenite</string>
<string name="force_stop_app">Prisilno Zaustavite</string>
<string name="restart_app">Resetujte</string>
<string name="save_log">Spremi Zapise</string>
</resources>

View File

@@ -102,4 +102,5 @@
<string name="app_profile_template_delete">Törlés</string>
<string name="app_profile_template_import_empty">A vágólap üres!</string>
<string name="app_profile_template_view">Sablon megnézése</string>
<string name="save_log">Naplók Mentése</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="selected_lkm">LKM dipilih: %s</string>
<string name="flashing">Pasang</string>
<string name="flash_failed">Pemasangan Gagal</string>
<string name="save_log">Simpan Log</string>
</resources>

View File

@@ -130,4 +130,5 @@
<string name="flash_failed">Installazione fallita</string>
<string name="selected_lkm">LKM selezionato: %s</string>
<string name="settings_restore_stock_image_message">Ripristina l\'immagine di fabbrica del produttore (se il backup è presente), solitamente usato prima di applicare l\'OTA; se devi disinstallare KernelSU, utilizza invece \"Disinstalla Permanentemente\".</string>
<string name="save_log">Salva Registri</string>
</resources>

View File

@@ -80,4 +80,5 @@
<string name="about_source_code">ראה את קוד המקור ב%1$s<br/>הצטרף אלינו %2$s בערוץ</string>
<string name="home_manager_version">גרסת מנהל</string>
<string name="new_version_available">גרסה חדשה עבור: %s זמינה, לחץ כדי לשדרג</string>
<string name="save_log">שמור יומנים</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="flash_success">フラッシュ成功</string>
<string name="flash_failed">フラッシュ失敗</string>
<string name="selected_lkm">選択された lkm: %s</string>
<string name="save_log">ログを保存</string>
</resources>

View File

@@ -66,4 +66,5 @@
<string name="about_source_code">%1$s ನಲ್ಲಿ ಮೂಲ ಕೋಡ್ ಅನ್ನು ವೀಕ್ಷಿಸಿ<br/>ನಮ್ಮ %2$s ಚಾನಲ್‌ಗೆ ಸೇರಿ</string>
<string name="home_manager_version">ಮ್ಯಾನೇಜರ್ ವರ್ಷನ್</string>
<string name="new_version_available">ಹೊಸ ಆವೃತ್ತಿ: %s ಲಭ್ಯವಿದೆ, ಅಪ್‌ಗ್ರೇಡ್ ಮಾಡಲು ಕ್ಲಿಕ್ ಮಾಡಿ</string>
<string name="save_log">ಲಾಗ್ಗಳನ್ನು ಉಳಿಸಿ</string>
</resources>

View File

@@ -78,4 +78,5 @@
<string name="profile_selinux_domain">도메인</string>
<string name="launch_app">실행</string>
<string name="failed_to_update_sepolicy">다음 앱에 대한 SELinux 규칙 업데이트 실패: %s</string>
<string name="save_log">로그 저장</string>
</resources>

View File

@@ -80,4 +80,5 @@
<string name="settings_umount_modules_default_summary">Visuotinė numatytoji „Modulių atjungimo“ reikšmė programų profiliuose. Jei įjungta, ji pašalins visus sistemos modulio pakeitimus programoms, kurios neturi profilio.</string>
<string name="module_changelog">Keitimų žurnalas</string>
<string name="require_kernel_version">Ši KernelSU versija %d yra per žema, kad šis vadybininkas galėtų tinkamai funkcionuoti. Prašome atsinaujinti į versiją %d ar aukščiau!</string>
<string name="save_log">Saglabāt Žurnālus</string>
</resources>

View File

@@ -130,4 +130,5 @@
<string name="flash_failed">Instalēšana neizdevās</string>
<string name="shrink_sparse_image">Samazināt reto attēlu</string>
<string name="shrink_sparse_image_message">Mainīt retā attēla izmēru, kurā atrodas modulis, līdz tā faktiskajam izmēram. Ņemiet vērā, ka tas var izraisīt moduļa neparastu darbību, tāpēc, lūdzu, izmantojiet tikai nepieciešamības gadījumā (piemēram, dublēšanai)</string>
<string name="save_log">Išsaugoti Žurnalus</string>
</resources>

View File

@@ -78,4 +78,5 @@
<string name="force_stop_app">सक्तीने थांबा</string>
<string name="launch_app">लाँच करा</string>
<string name="restart_app">पुन्हा सुरू करा</string>
<string name="save_log">लॉग जतन करा</string>
</resources>

View File

@@ -34,4 +34,5 @@
<string name="home_not_installed">Tidak terpasang</string>
<string name="reboot_bootloader">Mulakan semula ke bootloader</string>
<string name="home_manager_version">Versi Manager</string>
<string name="save_log">Simpan Log</string>
</resources>

View File

@@ -125,4 +125,5 @@
<string name="settings_uninstall_permanent">Permanent verwijderen</string>
<string name="settings_restore_stock_image">Herstel stockafbeelding</string>
<string name="settings_uninstall_temporary_message">Verwijder KernelSU tijdelijk en herstel het naar de oorspronkelijke staat na de volgende herstart.</string>
<string name="save_log">Logboeken Opslaan</string>
</resources>

View File

@@ -132,4 +132,5 @@
<string name="flash_success">Flashowanie ukończone pomyślnie</string>
<string name="flash_failed">Flashowanie nieudane</string>
<string name="selected_lkm">Wybrano lkm: %s</string>
<string name="save_log">Zapisz Dzienniki</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="flash_failed">Flash falhou</string>
<string name="flashing">Flashando</string>
<string name="flash_success">Flash bem-sucedido</string>
<string name="save_log">Salvar Logs</string>
</resources>

View File

@@ -79,4 +79,5 @@
<string name="force_stop_app">Forçar parada</string>
<string name="new_version_available">Nova versão: %s está disponível, clique para baixar</string>
<string name="require_kernel_version">A versão atual do KernelSU %d é muito baixa para o gerenciador funcionar corretamente. Atualize para a versão %d ou superior!</string>
<string name="save_log">Salvar Registros</string>
</resources>

View File

@@ -128,4 +128,5 @@
<string name="flashing">Instalare</string>
<string name="flash_success">Instalare reușită</string>
<string name="flash_failed">Instalarea a eșuat</string>
<string name="save_log">Salvează Jurnale</string>
</resources>

View File

@@ -134,4 +134,5 @@
<string name="flashing">Установка</string>
<string name="flash_failed">Установка не выполнена</string>
<string name="selected_lkm">Выбран lkm: %s</string>
<string name="save_log">Сохранить Журналы</string>
</resources>

View File

@@ -102,4 +102,5 @@
<string name="app_profile_template_sync">Sinhroniziraj predloge iz spleta</string>
<string name="app_profile_import_export">Uvoz/Izvoz</string>
<string name="module_changelog_failed">Napaka pri pridobivanju dnevnika sprememb: %s</string>
<string name="save_log">Shrani Dnevnike</string>
</resources>

View File

@@ -7,4 +7,5 @@
<string name="home_not_installed">Није инсталирано</string>
<string name="home_working_version">Верзија: %d</string>
<string name="home_working">Ради</string>
<string name="save_log">Сачувај Дневнике</string>
</resources>

View File

@@ -17,4 +17,5 @@
<string name="home_working_version">వెర్షన్: %d</string>
<string name="home_superuser_count">సూపర్‌యూజర్‌లు: %d</string>
<string name="home_module_count">మాడ్యూల్స్: %d</string>
<string name="save_log">లాగ్‌లు సేవ్ చేయండి</string>
</resources>

View File

@@ -130,4 +130,5 @@
<string name="settings_uninstall_temporary">ถอนการติดตั้งชั่วคราว</string>
<string name="settings_uninstall_permanent_message">การถอนการติดตั้ง KernelSU (การรูทและโมดูลทั้งหมด) อย่างสมบูรณ์โดยถาวร</string>
<string name="settings_restore_stock_image_message">คืนค่าโรงงานอิมเมจดั้งเดิม (หากมีข้อมูลสำรอง) ส่วนใหญ่มักใช้ก่อนทำการ OTA ซึ่งหากคุณต้องการถอนการติดตั้ง KernelSU โปรดใช้ \"ถอนการติดตั้งถาวร\"</string>
<string name="save_log">บันทึกบันทึก</string>
</resources>

View File

@@ -132,4 +132,5 @@
<string name="selected_lkm">Seçili lkm: %s</string>
<string name="flashing">Flaşlanıyor</string>
<string name="flash_failed">Flaşlama başarısız</string>
<string name="save_log">Günlükleri Kaydet</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="selected_lkm">Обрано lkm: %s</string>
<string name="settings_uninstall_permanent_message">Видалити KernelSU (Root і всі модулі) повністю і назавжди.</string>
<string name="settings_restore_stock_image_message">Відновити стоковий заводський образ (якщо є резервна копія), зазвичай використовується перед OTA; якщо вам потрібно видалити KernelSU, використовуйте \"Назавжди видалити\".</string>
<string name="save_log">Зберегти Журнали</string>
</resources>

View File

@@ -131,4 +131,5 @@
<string name="select_file_tip">Nên sử dụng hình ảnh phân vùng %1$s</string>
<string name="shrink_sparse_image">Giảm thiểu hình ảnh thưa thớt</string>
<string name="shrink_sparse_image_message">Thay đổi kích thước hình ảnh thưa nơi đặt mô-đun theo kích thước thực tế của nó. Lưu ý điều này có thể khiến module hoạt động không bình thường nên vui lòng chỉ sử dụng khi cần thiết (chẳng hạn như để sao lưu)</string>
<string name="save_log">Lưu Nhật Ký</string>
</resources>

View File

@@ -128,4 +128,5 @@
<string name="flash_success">刷写完成</string>
<string name="flash_failed">刷写失败</string>
<string name="selected_lkm">选择的 LKM %s</string>
<string name="save_log">保存日志保存日志</string>
</resources>

View File

@@ -120,4 +120,5 @@
<string name="shrink_sparse_image">最小化稀疏影像</string>
<string name="shrink_sparse_image_message">將模組所在的稀疏影像調整為實際大小。 請注意,這可能會導致模組工作異常,因此請僅在必要時使用(例如備份)</string>
<string name="settings_uninstall">解除安裝</string>
<string name="save_log">保存日志</string>
</resources>

View File

@@ -130,4 +130,5 @@
<string name="settings_restore_stock_image_message">恢復原廠映像如果有備份通常在OTA之前使用如果需要解除安裝KernelSU請使用「永久解除安裝」。</string>
<string name="flash_failed">寫入失敗</string>
<string name="selected_lkm">選擇的 LKM %s</string>
<string name="save_log">儲存日誌</string>
</resources>

View File

@@ -130,4 +130,5 @@
<string name="flash_success">Flash success</string>
<string name="flash_failed">Flash failed</string>
<string name="selected_lkm">Selected lkm: %s</string>
<string name="save_log">Save Logs</string>
</resources>