1/*
2 * Nextcloud - Android Client
3 *
4 * SPDX-FileCopyrightText: 2019 Chris Narkiewicz <hello@ezaquarii.com>
5 * SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
6 */
7package com.nextcloud.client.media
8
9import android.media.AudioFocusRequest
10import android.media.AudioManager
11
12/**
13 * Wrapper around audio manager exposing simplified audio focus API and
14 * hiding platform API level differences.
15 *
16 * @param audioManger Platform audio manager
17 * @param onFocusChange Called when audio focus changes, including acquired and released focus states
18 */
19internal class AudioFocusManager(
20 private val audioManger: AudioManager,
21 private val onFocusChange: (AudioFocus) -> Unit,
22 requestBuilder: AudioFocusRequest.Builder = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
23) {
24 private val focusListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
25 val focus = when (focusChange) {
26 AudioManager.AUDIOFOCUS_GAIN,
27 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
28 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK -> AudioFocus.FOCUS
29 AudioManager.AUDIOFOCUS_LOSS,
30 AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> AudioFocus.LOST
31 AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> AudioFocus.DUCK
32 else -> null
33 }
34 focus?.let { onFocusChange(it) }
35 }
36
37 private val focusRequest = requestBuilder
38 .setWillPauseWhenDucked(true)
39 .setOnAudioFocusChangeListener(focusListener)
40 .build()
41
42 fun requestFocus() {
43 val requestResult = audioManger.requestAudioFocus(focusRequest)
44 if (requestResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
45 focusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN)
46 } else {
47 focusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS)
48 }
49 }
50
51 fun releaseFocus() {
52 audioManger.abandonAudioFocusRequest(focusRequest)
53 focusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_LOSS)
54 }
55}
56