Skip to content

Commit e892f8d

Browse files
authored
Merge branch 'abdallahmehiz:main' into p1
2 parents 44726b1 + 837d4d6 commit e892f8d

File tree

7 files changed

+106
-79
lines changed

7 files changed

+106
-79
lines changed

.github/workflows/nightlies.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
keyStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
4040
keyPassword: ${{ secrets.KEY_PASSWORD }}
4141
env:
42-
BUILD_TOOLS_VERSION: "34.0.0"
42+
BUILD_TOOLS_VERSION: "35.0.0"
4343

4444
- name: Copy build artifacts
4545
run: |
@@ -56,25 +56,25 @@ jobs:
5656
- name: Upload the universal artifact
5757
uses: actions/upload-artifact@v4
5858
with:
59-
path: ./mpvKt-universal*
59+
path: ./mpvKt-universal.apk
6060
name: universal-r${{ env.COMMIT_COUNT }}
6161
- name: Upload the arm64-v8a artifact
6262
uses: actions/upload-artifact@v4
6363
with:
64-
path: ./mpvKt-arm64-v8a*
64+
path: ./mpvKt-arm64-v8a.apk
6565
name: arm64-v8a-r${{ env.COMMIT_COUNT }}
6666
- name: Upload the armeabi-v7a artifact
6767
uses: actions/upload-artifact@v4
6868
with:
69-
path: ./mpvKt-armeabi-v7a*
69+
path: ./mpvKt-armeabi-v7a.apk
7070
name: armeabi-v7a-r${{ env.COMMIT_COUNT }}
7171
- name: Upload the x86 artifact
7272
uses: actions/upload-artifact@v4
7373
with:
74-
path: ./mpvKt-x86*
74+
path: ./mpvKt-x86.apk
7575
name: x86-r${{ env.COMMIT_COUNT }}
7676
- name: Upload the x86_64 artifact
7777
uses: actions/upload-artifact@v4
7878
with:
79-
path: ./mpvKt-x86_64*
79+
path: ./mpvKt-x86_64.apk
8080
name: x86_64-r${{ env.COMMIT_COUNT }}

app/src/main/java/live/mehiz/mpvkt/presentation/crash/CrashActivity.kt

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package live.mehiz.mpvkt.presentation.crash
22

3+
import android.app.Activity
34
import android.content.ClipData
45
import android.content.ClipboardManager
56
import android.content.Context
@@ -80,55 +81,72 @@ class CrashActivity : ComponentActivity() {
8081
}
8182
}
8283

83-
private fun collectLogcat(): String {
84-
val process = Runtime.getRuntime()
85-
val reader = BufferedReader(InputStreamReader(process.exec("logcat -d").inputStream))
86-
val logcat = StringBuilder()
87-
// reader.lines() looks much nicer so why not use it on devices that support it?
88-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
89-
reader.lines().forEach(logcat::appendLine)
90-
} else {
91-
reader.readLines().forEach(logcat::appendLine)
84+
companion object {
85+
suspend fun shareLogs(
86+
deviceInfo: String,
87+
exceptionString: String? = null,
88+
logcat: String,
89+
activity: Activity,
90+
) {
91+
withContext(NonCancellable) {
92+
val file = File(activity.cacheDir, "mpvKt_logs.txt")
93+
if (file.exists()) file.delete()
94+
file.createNewFile()
95+
file.appendText(concatLogs(deviceInfo, exceptionString, logcat))
96+
val uri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", file)
97+
val intent = Intent(Intent.ACTION_SEND)
98+
intent.putExtra(Intent.EXTRA_STREAM, uri)
99+
intent.clipData = ClipData.newRawUri(null, uri)
100+
intent.type = "text/plain"
101+
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
102+
activity.startActivity(
103+
Intent.createChooser(intent, activity.getString(R.string.crash_screen_share)),
104+
)
105+
}
92106
}
93-
// clear logcat so it doesn't pollute subsequent crashes
94-
process.exec("logcat -c")
95-
return logcat.toString()
96-
}
97107

98-
private fun concatLogs(
99-
deviceInfo: String,
100-
crashLogs: String,
101-
logcat: String,
102-
): String {
103-
return """
104-
$deviceInfo
105-
106-
Exception:
107-
$crashLogs
108-
109-
Logcat:
110-
$logcat
111-
""".trimIndent()
112-
}
108+
fun concatLogs(
109+
deviceInfo: String,
110+
crashLogs: String? = null,
111+
logcat: String,
112+
): String {
113+
return StringBuilder().apply {
114+
appendLine(deviceInfo)
115+
appendLine()
116+
if (!crashLogs.isNullOrBlank()) {
117+
appendLine("Exception:")
118+
appendLine(crashLogs)
119+
appendLine()
120+
}
121+
appendLine("Logcat:")
122+
appendLine(logcat)
123+
}.toString()
124+
}
113125

114-
private suspend fun dumpLogs(
115-
exceptionString: String,
116-
logcat: String,
117-
) {
118-
withContext(NonCancellable) {
119-
val file = File(applicationContext.cacheDir, "mpvKt_logs.txt")
120-
if (file.exists()) file.delete()
121-
file.createNewFile()
122-
file.appendText(concatLogs(collectDeviceInfo(), exceptionString, logcat))
123-
val uri = FileProvider.getUriForFile(applicationContext, BuildConfig.APPLICATION_ID + ".provider", file)
124-
val intent = Intent(Intent.ACTION_SEND)
125-
intent.putExtra(Intent.EXTRA_STREAM, uri)
126-
intent.clipData = ClipData.newRawUri(null, uri)
127-
intent.type = "text/plain"
128-
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
129-
this@CrashActivity.startActivity(
130-
Intent.createChooser(intent, applicationContext.getString(R.string.crash_screen_share)),
131-
)
126+
fun collectLogcat(): String {
127+
val process = Runtime.getRuntime()
128+
val reader = BufferedReader(InputStreamReader(process.exec("logcat -d").inputStream))
129+
val logcat = StringBuilder()
130+
// reader.lines() looks much nicer so why not use it on devices that support it?
131+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
132+
reader.lines().forEach(logcat::appendLine)
133+
} else {
134+
reader.readLines().forEach(logcat::appendLine)
135+
}
136+
return logcat.toString()
137+
}
138+
139+
fun collectDeviceInfo(): String {
140+
return """
141+
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.GIT_SHA})
142+
Android version: ${Build.VERSION.RELEASE} (${Build.VERSION.SDK_INT})
143+
Device brand: ${Build.BRAND}
144+
Device manufacturer: ${Build.MANUFACTURER}
145+
Device model: ${Build.MODEL} (${Build.DEVICE})
146+
MPV version: ${Utils.VERSIONS.mpv}
147+
ffmpeg version: ${Utils.VERSIONS.ffmpeg}
148+
libplacebo version: ${Utils.VERSIONS.libPlacebo}
149+
""".trimIndent()
132150
}
133151
}
134152

@@ -162,7 +180,7 @@ class CrashActivity : ComponentActivity() {
162180
Button(
163181
onClick = {
164182
scope.launch(Dispatchers.IO) {
165-
dumpLogs(exceptionString, logcat)
183+
shareLogs(collectDeviceInfo(), exceptionString, logcat, this@CrashActivity)
166184
}
167185
},
168186
modifier = Modifier.weight(1f),
@@ -252,16 +270,3 @@ class CrashActivity : ComponentActivity() {
252270
}
253271
}
254272
}
255-
256-
fun collectDeviceInfo(): String {
257-
return """
258-
App version: ${BuildConfig.VERSION_NAME} (${BuildConfig.GIT_SHA})
259-
Android version: ${Build.VERSION.RELEASE} (${Build.VERSION.SDK_INT})
260-
Device brand: ${Build.BRAND}
261-
Device manufacturer: ${Build.MANUFACTURER}
262-
Device model: ${Build.MODEL} (${Build.DEVICE})
263-
MPV version: ${Utils.VERSIONS.mpv}
264-
ffmpeg version: ${Utils.VERSIONS.ffmpeg}
265-
libplacebo version: ${Utils.VERSIONS.libPlacebo}
266-
""".trimIndent()
267-
}

app/src/main/java/live/mehiz/mpvkt/ui/player/PlayerActivity.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ class PlayerActivity : AppCompatActivity() {
142142
}
143143

144144
player.isExiting = true
145+
if (isFinishing) {
146+
MPVLib.command(arrayOf("stop"))
147+
}
145148
MPVLib.removeObserver(playerObserver)
146149
MPVLib.destroy()
147150

app/src/main/java/live/mehiz/mpvkt/ui/preferences/AboutScreen.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package live.mehiz.mpvkt.ui.preferences
22

3-
import android.content.ClipData
4-
import android.content.ClipboardManager
5-
import android.content.Context
63
import android.content.Intent
74
import android.net.Uri
85
import androidx.compose.foundation.Image
@@ -27,9 +24,11 @@ import androidx.compose.material3.TopAppBar
2724
import androidx.compose.runtime.Composable
2825
import androidx.compose.ui.Alignment
2926
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.platform.LocalClipboardManager
3028
import androidx.compose.ui.platform.LocalContext
3129
import androidx.compose.ui.res.painterResource
3230
import androidx.compose.ui.res.stringResource
31+
import androidx.compose.ui.text.AnnotatedString
3332
import androidx.compose.ui.unit.dp
3433
import cafe.adriel.voyager.navigator.LocalNavigator
3534
import cafe.adriel.voyager.navigator.currentOrThrow
@@ -39,7 +38,7 @@ import compose.icons.simpleicons.Github
3938
import live.mehiz.mpvkt.BuildConfig
4039
import live.mehiz.mpvkt.R
4140
import live.mehiz.mpvkt.presentation.Screen
42-
import live.mehiz.mpvkt.presentation.crash.collectDeviceInfo
41+
import live.mehiz.mpvkt.presentation.crash.CrashActivity.Companion.collectDeviceInfo
4342
import live.mehiz.mpvkt.ui.theme.spacing
4443
import me.zhanghai.compose.preference.Preference
4544
import me.zhanghai.compose.preference.ProvidePreferenceLocals
@@ -49,6 +48,7 @@ object AboutScreen : Screen() {
4948
@Composable
5049
override fun Content() {
5150
val context = LocalContext.current
51+
val clipboard = LocalClipboardManager.current
5252
val navigator = LocalNavigator.currentOrThrow
5353
Scaffold(
5454
topBar = {
@@ -97,8 +97,7 @@ object AboutScreen : Screen() {
9797
)
9898
},
9999
onClick = {
100-
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
101-
clipboardManager.setPrimaryClip(ClipData.newPlainText("app_version_data", collectDeviceInfo()))
100+
clipboard.setText(AnnotatedString(collectDeviceInfo()))
102101
},
103102
)
104103
Preference(

app/src/main/java/live/mehiz/mpvkt/ui/preferences/AdvancedPreferencesScreen.kt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Intent
44
import android.net.Uri
55
import android.os.Environment
66
import android.widget.Toast
7+
import androidx.activity.compose.LocalActivity
78
import androidx.activity.compose.rememberLauncherForActivityResult
89
import androidx.activity.result.contract.ActivityResultContracts
910
import androidx.compose.foundation.layout.Column
@@ -30,8 +31,10 @@ import androidx.compose.runtime.remember
3031
import androidx.compose.runtime.rememberCoroutineScope
3132
import androidx.compose.runtime.setValue
3233
import androidx.compose.ui.Modifier
34+
import androidx.compose.ui.platform.LocalClipboardManager
3335
import androidx.compose.ui.platform.LocalContext
3436
import androidx.compose.ui.res.stringResource
37+
import androidx.compose.ui.text.AnnotatedString
3538
import androidx.compose.ui.util.fastJoinToString
3639
import androidx.documentfile.provider.DocumentFile
3740
import cafe.adriel.voyager.navigator.LocalNavigator
@@ -46,6 +49,7 @@ import live.mehiz.mpvkt.preferences.AdvancedPreferences
4649
import live.mehiz.mpvkt.preferences.preference.collectAsState
4750
import live.mehiz.mpvkt.presentation.Screen
4851
import live.mehiz.mpvkt.presentation.components.ConfirmDialog
52+
import live.mehiz.mpvkt.presentation.crash.CrashActivity
4953
import me.zhanghai.compose.preference.Preference
5054
import me.zhanghai.compose.preference.ProvidePreferenceLocals
5155
import me.zhanghai.compose.preference.SwitchPreference
@@ -65,7 +69,7 @@ object AdvancedPreferencesScreen : Screen() {
6569
val navigator = LocalNavigator.currentOrThrow
6670
val preferences = koinInject<AdvancedPreferences>()
6771
val fileManager = koinInject<FileManager>()
68-
72+
val scope = rememberCoroutineScope()
6973
Scaffold(
7074
topBar = {
7175
TopAppBar(
@@ -207,6 +211,21 @@ object AdvancedPreferencesScreen : Screen() {
207211
},
208212
summary = { if (inputConf.isNotBlank()) Text(inputConf.lines()[0]) },
209213
)
214+
val activity = LocalActivity.currentOrThrow
215+
val clipboard = LocalClipboardManager.current
216+
Preference(
217+
title = { Text(stringResource(R.string.pref_advanced_dump_logs_title)) },
218+
summary = { Text(stringResource(R.string.pref_advanced_dump_logs_summary)) },
219+
onClick = {
220+
scope.launch(Dispatchers.IO) {
221+
val deviceInfo = CrashActivity.collectDeviceInfo()
222+
val logcat = CrashActivity.collectLogcat()
223+
224+
clipboard.setText(AnnotatedString(CrashActivity.concatLogs(deviceInfo, null, logcat)))
225+
CrashActivity.shareLogs(deviceInfo, null, logcat, activity)
226+
}
227+
},
228+
)
210229
val verboseLogging by preferences.verboseLogging.collectAsState()
211230
SwitchPreference(
212231
value = verboseLogging,
@@ -216,7 +235,6 @@ object AdvancedPreferencesScreen : Screen() {
216235
)
217236
var isConfirmDialogShown by remember { mutableStateOf(false) }
218237
val mpvKtDatabase = koinInject<MpvKtDatabase>()
219-
val scope = rememberCoroutineScope()
220238
Preference(
221239
title = { Text(stringResource(R.string.pref_advanced_clear_playback_history)) },
222240
onClick = { isConfirmDialogShown = true },

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@
122122
<string name="pref_advanced_mpv_conf_storage_location">Pick configuration storage location</string>
123123
<string name="pref_advanced_mpv_conf">Edit mpv.conf</string>
124124
<string name="pref_advanced_input_conf">Edit input.conf</string>
125+
<string name="pref_advanced_dump_logs_title">Dump logs</string>
126+
<string name="pref_advanced_dump_logs_summary">Dumps and copies the logs to be shared with the developers</string>
125127
<string name="pref_advanced_verbose_logging_title">Verbose logging</string>
126128
<string name="pref_advanced_verbose_logging_summary">Helps in debugging but may hinder performance</string>
127129
<string name="pref_advanced_clear_playback_history">Clear playback history</string>

gradle/libs.versions.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
[versions]
2-
agp = "8.8.0"
2+
agp = "8.8.2"
33
kotlin = "2.1.10"
44
coreKtx = "1.15.0"
55
lifecycleRuntimeKtx = "2.8.7"
6-
composeBom = "2025.01.01"
7-
activityCompose = "1.10.0"
6+
composeBom = "2025.03.00"
7+
activityCompose = "1.10.1"
88
koin = "4.0.2"
99
voyager = "1.1.0-beta03"
1010
room = "2.6.1"
@@ -22,8 +22,8 @@ androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
2222
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
2323
androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version = "1.3.1" }
2424
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version = "1.7.0" }
25-
androidx-material3-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version = "1.7.7" }
26-
androidx-compose-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version = "1.1.0" }
25+
androidx-material3-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version = "1.7.8" }
26+
androidx-compose-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version = "1.1.1" }
2727
androidx-compose-animation-graphics = { group = "androidx.compose.animation", name = "animation-graphics-android" }
2828
androidx-preferences-ktx = { group = "androidx.preference", name = "preference-ktx", version = "1.2.1" }
2929
mediasession = "androidx.media:media:1.7.0"

0 commit comments

Comments
 (0)