Skip to content

Commit 9033fb7

Browse files
committed
bug fixes and other stuff
1 parent caabb02 commit 9033fb7

30 files changed

Lines changed: 263 additions & 136 deletions

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ android {
225225
}
226226

227227
baselineProfile {
228-
dexLayoutOptimization = true // TODO generate on every release using fastlane, or disable this
228+
dexLayoutOptimization = true // TODO(ASAP) generate on every release using fastlane, or disable this
229229
}
230230

231231
// https://stackoverflow.com/a/77745844

app/src/main/java/org/akanework/gramophone/logic/GramophoneApplication.kt

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,24 +129,23 @@ class GramophoneApplication : Application(), SingletonImageLoader.Factory,
129129
recentlyAddedFilterSecondFlow,
130130
MutableStateFlow(true), "gramophoneAlbumCover"
131131
)
132-
// This is a separate thread to avoid disk read on main thread and improve startup time
133-
CoroutineScope(Dispatchers.Default).launch {
134-
val prefs = PreferenceManager.getDefaultSharedPreferences(this@GramophoneApplication)
135-
// Set application theme when launching.
136-
when (prefs.getString("theme_mode", "0")) {
137-
"0" -> {
138-
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
139-
}
140-
141-
"1" -> {
142-
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
143-
}
132+
val prefs = PreferenceManager.getDefaultSharedPreferences(this@GramophoneApplication)
133+
// Set application theme when launching.
134+
when (prefs.getString("theme_mode", "0")) {
135+
"0" -> {
136+
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
137+
}
144138

145-
"2" -> {
146-
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
147-
}
139+
"1" -> {
140+
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
148141
}
149142

143+
"2" -> {
144+
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
145+
}
146+
}
147+
// This is a separate thread to avoid disk read on main thread and improve startup time
148+
CoroutineScope(Dispatchers.Default).launch {
150149
onSharedPreferenceChanged(prefs, null) // reload all values
151150
prefs.registerOnSharedPreferenceChangeListener(this@GramophoneApplication)
152151

@@ -285,7 +284,8 @@ class GramophoneApplication : Application(), SingletonImageLoader.Factory,
285284

286285
override fun uncaughtException(t: Thread, e: Throwable) {
287286
// TODO convert to notification that opens BugHandlerActivity on click, and let JVM
288-
// go through the normal exception process.
287+
// go through the normal exception process (to get stats from play). disadvantage: we can't
288+
// cheat the statistic that way
289289
val exceptionMessage = Log.getStackTraceString(e)
290290
val threadName = Thread.currentThread().name
291291
Log.e(TAG, "Error on thread $threadName:\n $exceptionMessage")

app/src/main/java/org/akanework/gramophone/logic/GramophonePlaybackService.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ import androidx.media3.common.Player.EVENT_SHUFFLE_MODE_ENABLED_CHANGED
5656
import androidx.media3.common.Tracks
5757
import androidx.media3.common.util.BitmapLoader
5858
import androidx.media3.common.util.UnstableApi
59-
import androidx.media3.common.util.Util
6059
import androidx.media3.common.util.Util.isBitmapFactorySupportedMimeType
6160
import androidx.media3.datasource.DefaultDataSource
6261
import androidx.media3.exoplayer.DefaultRenderersFactory
@@ -227,7 +226,6 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis
227226
}
228227

229228
private val btReceiver = object : BroadcastReceiver() {
230-
// TODO verify if stable
231229
override fun onReceive(context: Context, intent: Intent) {
232230
if (intent.action.equals("android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED") &&
233231
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O /* before 8, only sbc was supported */
@@ -353,10 +351,7 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis
353351
player.exoPlayer.addAnalyticsListener(EventLogger())
354352
player.exoPlayer.addAnalyticsListener(afFormatTracker)
355353
player.exoPlayer.addAnalyticsListener(this)
356-
player.exoPlayer.audioSessionId = Util.generateAudioSessionIdV21(this)
357-
lastSessionId = player.exoPlayer.audioSessionId
358354
player.setShuffleOrder { CircularShuffleOrder(it, 0, 0, Random.nextLong()) }
359-
broadcastAudioSession()
360355
lastPlayedManager = LastPlayedManager(this, player)
361356
lastPlayedManager.allowSavingState = false
362357

@@ -505,6 +500,7 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis
505500
lastPlayedManager.save()
506501
mediaSession!!.player.stop()
507502
broadcastAudioSessionClose()
503+
handler.removeCallbacks(timer)
508504
controller!!.release()
509505
controller = null
510506
mediaSession!!.release()
@@ -564,10 +560,11 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis
564560
}
565561

566562
override fun onAudioSessionIdChanged(audioSessionId: Int) {
567-
super<Player.Listener>.onAudioSessionIdChanged(audioSessionId)
568-
broadcastAudioSessionClose()
569-
lastSessionId = audioSessionId
570-
broadcastAudioSession()
563+
if (audioSessionId != lastSessionId) {
564+
broadcastAudioSessionClose()
565+
lastSessionId = audioSessionId
566+
broadcastAudioSession()
567+
}
571568
}
572569

573570
private fun broadcastAudioSession() {
@@ -588,6 +585,7 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis
588585
putExtra(AudioEffect.EXTRA_PACKAGE_NAME, packageName)
589586
putExtra(AudioEffect.EXTRA_AUDIO_SESSION, lastSessionId)
590587
})
588+
lastSessionId = 0
591589
}
592590
}
593591

app/src/main/java/org/akanework/gramophone/logic/ui/BugHandlerActivity.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ class BugHandlerActivity : AppCompatActivity() {
108108
.append(':')
109109
.append(' ')
110110
.append(gramophoneVersion)
111+
.append(" (")
112+
.append(packageName)
113+
.append(')')
111114
.append('\n')
112115
.append('\n')
113116
.append(getString(R.string.crash_rtype))

app/src/main/java/org/akanework/gramophone/logic/utils/BtCodecInfo.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ data class BtCodecInfo(val codec: String?, val sampleRateHz: Int?, val channelCo
116116
}.takeIf { !it.startsWith("UNKNOWN CODEC") }
117117
}
118118

119-
// TODO test stability
120119
@RequiresApi(Build.VERSION_CODES.O)
121120
fun getCodec(context: Context, callback: (BtCodecInfo?) -> Unit): Proxy? {
122121
val adapter = ContextCompat.getSystemService(context, BluetoothManager::class.java)?.adapter
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.akanework.gramophone.logic.utils
2+
3+
object Flags {
4+
const val NEW_LYRIC_UI = false
5+
const val FORMAT_INFO_DIALOG = false
6+
}

app/src/main/java/org/akanework/gramophone/logic/utils/SemanticLyrics.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ fun parseLrc(lyricText: String, trimEnabled: Boolean, multiLineEnabled: Boolean)
543543
while (out.firstOrNull()?.first?.isBlank() == true)
544544
out.removeAt(0)
545545
//while (out.lastOrNull()?.first?.isBlank() == true)
546-
// out.removeAt(out.lastIndex) TODO
546+
// out.removeAt(out.lastIndex) TODO this breaks unit tests, but blank lines are useless
547547
return UnsyncedLyrics(out.map { lyric ->
548548
if (defaultIsWalaokeM && lyric.second == null)
549549
lyric.copy(second = SpeakerEntity.Male)
@@ -726,7 +726,7 @@ fun parseLrc(lyricText: String, trimEnabled: Boolean, multiLineEnabled: Boolean)
726726
while (out.firstOrNull()?.text?.isBlank() == true)
727727
out.removeAt(0)
728728
//while (out.lastOrNull()?.text?.isBlank() == true)
729-
// out.removeAt(out.lastIndex) TODO
729+
// out.removeAt(out.lastIndex) TODO this breaks unit tests, but blank lines are useless
730730
return SyncedLyrics(out).also { splitBidirectionalWords(it) }
731731
}
732732

app/src/main/java/org/akanework/gramophone/logic/utils/flows/PauseableFlows.kt

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.combine
3030
import kotlinx.coroutines.flow.emptyFlow
3131
import kotlinx.coroutines.flow.first
3232
import kotlinx.coroutines.flow.flatMapLatest
33+
import kotlinx.coroutines.flow.flow
3334
import kotlinx.coroutines.flow.flowOf
3435
import kotlinx.coroutines.flow.map
3536
import kotlinx.coroutines.flow.mapLatest
@@ -48,10 +49,15 @@ interface PauseManager : CoroutineContext.Element {
4849
companion object Key : CoroutineContext.Key<PauseManager>
4950
}
5051

51-
class LifecyclePauseManager(scope: CoroutineScope, source: LifecycleOwner, minimumState: Lifecycle.State)
52-
: PauseManager {
53-
override val isPaused = source.lifecycle.currentStateFlow.map { !it.isAtLeast(minimumState) }
54-
.stateIn(scope, WhileSubscribed(), !source.lifecycle.currentState.isAtLeast(minimumState))
52+
class LifecyclePauseManager(
53+
scope: CoroutineScope, source: LifecycleOwner, minimumState: Lifecycle.State,
54+
bypassFlow: Flow<Boolean>
55+
) : PauseManager {
56+
@OptIn(ExperimentalCoroutinesApi::class)
57+
override val isPaused = bypassFlow.flatMapLatest {
58+
if (it || true) flowOf(false) else
59+
source.lifecycle.currentStateFlow.map { !it.isAtLeast(minimumState) } }
60+
.stateIn(scope, WhileSubscribed(), !source.lifecycle.currentState.isAtLeast(minimumState))
5561
}
5662

5763
object EmptyPauseManager : PauseManager {
@@ -186,14 +192,30 @@ suspend fun <T> repeatUntilDoneWhenUnpaused(block: suspend () -> T): T {
186192

187193
fun repeatPausingWithLifecycle(source: LifecycleOwner,
188194
context: CoroutineContext = EmptyCoroutineContext,
189-
minimumStateForCollect: Lifecycle.State = Lifecycle.State.CREATED,
195+
minimumStateForCollect: Lifecycle.State = Lifecycle.State.INITIALIZED,
190196
minimumStateForUnpause: Lifecycle.State = Lifecycle.State.RESUMED,
197+
initialUnpauseUntilResumeTimeoutMs: ULong = 2000U,
191198
block: suspend () -> Unit) {
192-
source.lifecycleScope.launch {
193-
source.repeatOnLifecycle(minimumStateForCollect) {
194-
withContext(context + LifecyclePauseManager(this, source, minimumStateForUnpause)) {
199+
val maxForceUnpausedTimestamp = System.currentTimeMillis() + initialUnpauseUntilResumeTimeoutMs.toLong()
200+
val bypass = flow {
201+
val timeLeft = maxForceUnpausedTimestamp - System.currentTimeMillis()
202+
if (timeLeft > 0) {
203+
emit(true)
204+
delay(timeLeft)
205+
}
206+
emit(false)
207+
}
208+
source.lifecycleScope.launch(context) {
209+
if (minimumStateForCollect == Lifecycle.State.INITIALIZED) {
210+
withContext(context + LifecyclePauseManager(this, source, minimumStateForUnpause, bypass)) {
195211
block()
196212
}
213+
} else {
214+
source.repeatOnLifecycle(minimumStateForCollect) {
215+
withContext(context + LifecyclePauseManager(this, source, minimumStateForUnpause, bypass)) {
216+
block()
217+
}
218+
}
197219
}
198220
}
199221
}

app/src/main/java/org/akanework/gramophone/ui/AudioPreviewActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class AudioPreviewActivity : AppCompatActivity(), View.OnClickListener {
9191
private var askedForPermissionInSettings = false
9292
private val updateSliderRunnable = object : Runnable {
9393
override fun run() {
94-
// TODO we may no longer need to poll duration after midi audio sink bugfix is released
94+
// TODO we may no longer need to poll duration because midi audio sink bugfix is released
9595
val duration = player.contentDuration.let { if (it == C.TIME_UNSET) null else it }
9696
?: player.mediaMetadata.durationMs
9797
if (duration != null) {

app/src/main/java/org/akanework/gramophone/ui/MainActivity.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,13 @@ class MainActivity : AppCompatActivity() {
332332
}
333333

334334
fun onLibraryLoaded() {
335-
if (!ready) reportFullyDrawn()
336335
doPlayFromIntent(intent)
337336
}
338337

338+
fun maybeReportFullyDrawn() {
339+
if (!ready) reportFullyDrawn()
340+
}
341+
339342
/**
340343
* onRequestPermissionResult:
341344
* Update library after permission is granted.

0 commit comments

Comments
 (0)