diff --git a/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt b/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt index 0cf08c11d..a21d602f8 100644 --- a/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt +++ b/android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt @@ -2571,14 +2571,19 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList return } - val shouldTakeOver = when (bleManager.getMostRecentStatus()?.connectionState) { + val airPodsState = bleManager.getMostRecentStatus()?.connectionState + Log.d(TAG, "AirPods state for takeover: $airPodsState") + val shouldTakeOver = when (airPodsState) { "Disconnected" -> config.takeoverWhenDisconnected "Idle" -> config.takeoverWhenIdle "Music" -> config.takeoverWhenMusic "Call" -> config.takeoverWhenCall "Ringing" -> config.takeoverWhenCall "Hanging Up" -> config.takeoverWhenCall - else -> false + // The first advertisement after the AirPods reappear often carries a state byte that + // isn't mapped (or there is no status yet). Refusing then means the takeover only + // happens on the next media change, so follow the media setting instead. + else -> config.takeoverWhenMusic } if (!shouldTakeOver) { diff --git a/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt b/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt index 400e0ff72..1c7738698 100644 --- a/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt +++ b/android/app/src/main/java/me/kavishdevar/librepods/utils/MediaController.kt @@ -140,7 +140,16 @@ object MediaController { Log.d("MediaController", "Current active content types: $currentActiveContentTypes") - val hasNewMusicOrMovie = currentActiveContentTypes.any { contentType -> + // Some players (e.g. Poweramp over OpenSL ES) leave the content type unknown, so a + // USAGE_MEDIA stream with no content type counts as music too. + val hasUntypedMedia = configs?.any { config -> + config.audioAttributes?.let { attrs -> + attrs.usage == android.media.AudioAttributes.USAGE_MEDIA && + attrs.contentType == android.media.AudioAttributes.CONTENT_TYPE_UNKNOWN + } ?: false + } ?: false + + val hasNewMusicOrMovie = hasUntypedMedia || currentActiveContentTypes.any { contentType -> contentType == android.media.AudioAttributes.CONTENT_TYPE_MUSIC || contentType == android.media.AudioAttributes.CONTENT_TYPE_MOVIE }