Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import android.media.session.MediaSessionManager
import android.media.session.PlaybackState
import android.os.Handler
import android.os.PowerManager
import android.os.UserHandle
import android.view.Display
import android.view.KeyEvent
import ru.hepolise.volumekeytrackcontrol.util.AppFilterType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getAppFilterType
import ru.hepolise.volumekeytrackcontrol.util.SharedPreferencesUtil.getApps

class MediaSessionManager(private val context: Context) {
companion object {
private const val USER_ALL = -1
}

lateinit var audioManager: AudioManager
private set
private lateinit var powerManager: PowerManager
Expand Down Expand Up @@ -46,22 +51,62 @@ class MediaSessionManager(private val context: Context) {
?: throw NullPointerException("Unable to get MediaSessionLegacyHelper")
}

@SuppressLint("BlockedPrivateApi")
fun refreshControllers() {
val method = MediaSessionManager::class.java.getDeclaredMethod(
"getActiveSessionsForUser",
ComponentName::class.java,
Int::class.javaPrimitiveType
)
mediaControllers = getActiveControllers()
}

@SuppressLint("BlockedPrivateApi")
private fun getActiveControllers(): List<MediaController>? {
try {
val legacy = MediaSessionManager::class.java.getDeclaredMethod(
"getActiveSessionsForUser",
ComponentName::class.java,
Int::class.javaPrimitiveType
)
legacy.isAccessible = true
val controllers = legacy.invoke(mediaSessionManager, null, USER_ALL)
@Suppress("UNCHECKED_CAST")
return controllers as List<MediaController>
} catch (_: Exception) {
}

method.isAccessible = true
getUserHandleAll()?.let { userHandle ->
try {
val perUser = MediaSessionManager::class.java.getDeclaredMethod(
"getActiveSessionsForUser",
ComponentName::class.java,
UserHandle::class.java
)
perUser.isAccessible = true
val controllers = perUser.invoke(mediaSessionManager, null, userHandle)
@Suppress("UNCHECKED_CAST")
return controllers as List<MediaController>
} catch (_: Exception) {
}
}

return try {
mediaSessionManager.getActiveSessions(null)
} catch (_: Exception) {
null
}
}

@Suppress("UNCHECKED_CAST")
mediaControllers = method.invoke(
mediaSessionManager,
null, // ComponentName
-1 // android.os.UserHandle.ALL
) as List<MediaController>
@SuppressLint("BlockedPrivateApi")
private fun getUserHandleAll(): UserHandle? {
val clazz = UserHandle::class.java
val candidates: List<() -> Any?> = listOf(
{ clazz.getField("ALL").get(null) },
{ clazz.getConstructor(Int::class.javaPrimitiveType).newInstance(USER_ALL) },
{ clazz.getMethod("of", Int::class.javaPrimitiveType).invoke(null, USER_ALL) }
)
for (candidate in candidates) {
try {
(candidate() as? UserHandle)?.let { return it }
} catch (_: Exception) {
}
}
return null
}

fun getActiveMediaController(prefs: android.content.SharedPreferences): MediaController? {
Expand Down Expand Up @@ -123,4 +168,4 @@ class MediaSessionManager(private val context: Context) {
audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, direction, 0)
}
}
}
}