Detect audio device change from API 23 with AudioCapabilitiesReceiver

* Add AudioDeviceCallbackApi23 class which extends the AudioDeviceCallback.
* Add registerAudioDeviceCallback and unregisterAudioDeviceCallback methods for Api23.
* Modify the logics of AudioCapabilitiesReceiver constructor, register and unregister methods.

PiperOrigin-RevId: 516183997
This commit is contained in:
tianyifeng 2023-03-13 12:39:28 +00:00 committed by tonihei
parent ed4c3471f2
commit 01f04aac7f

View File

@ -15,17 +15,22 @@
*/ */
package com.google.android.exoplayer2.audio; package com.google.android.exoplayer2.audio;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager; import android.media.AudioManager;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.DoNotInline;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Assertions; import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
/** /**
@ -48,7 +53,8 @@ public final class AudioCapabilitiesReceiver {
private final Context context; private final Context context;
private final Listener listener; private final Listener listener;
private final Handler handler; private final Handler handler;
@Nullable private final BroadcastReceiver receiver; @Nullable private final AudioDeviceCallbackV23 audioDeviceCallback;
@Nullable private final BroadcastReceiver hdmiAudioPlugBroadcastReceiver;
@Nullable private final ExternalSurroundSoundSettingObserver externalSurroundSoundSettingObserver; @Nullable private final ExternalSurroundSoundSettingObserver externalSurroundSoundSettingObserver;
@Nullable /* package */ AudioCapabilities audioCapabilities; @Nullable /* package */ AudioCapabilities audioCapabilities;
@ -61,9 +67,11 @@ public final class AudioCapabilitiesReceiver {
public AudioCapabilitiesReceiver(Context context, Listener listener) { public AudioCapabilitiesReceiver(Context context, Listener listener) {
context = context.getApplicationContext(); context = context.getApplicationContext();
this.context = context; this.context = context;
this.listener = Assertions.checkNotNull(listener); this.listener = checkNotNull(listener);
handler = Util.createHandlerForCurrentOrMainLooper(); handler = Util.createHandlerForCurrentOrMainLooper();
receiver = Util.SDK_INT >= 21 ? new HdmiAudioPlugBroadcastReceiver() : null; audioDeviceCallback = Util.SDK_INT >= 23 ? new AudioDeviceCallbackV23() : null;
hdmiAudioPlugBroadcastReceiver =
Util.SDK_INT >= 21 ? new HdmiAudioPlugBroadcastReceiver() : null;
Uri externalSurroundSoundUri = AudioCapabilities.getExternalSurroundSoundGlobalSettingUri(); Uri externalSurroundSoundUri = AudioCapabilities.getExternalSurroundSoundGlobalSettingUri();
externalSurroundSoundSettingObserver = externalSurroundSoundSettingObserver =
externalSurroundSoundUri != null externalSurroundSoundUri != null
@ -82,18 +90,24 @@ public final class AudioCapabilitiesReceiver {
@SuppressWarnings("InlinedApi") @SuppressWarnings("InlinedApi")
public AudioCapabilities register() { public AudioCapabilities register() {
if (registered) { if (registered) {
return Assertions.checkNotNull(audioCapabilities); return checkNotNull(audioCapabilities);
} }
registered = true; registered = true;
if (externalSurroundSoundSettingObserver != null) { if (externalSurroundSoundSettingObserver != null) {
externalSurroundSoundSettingObserver.register(); externalSurroundSoundSettingObserver.register();
} }
if (Util.SDK_INT >= 23 && audioDeviceCallback != null) {
Api23.registerAudioDeviceCallback(context, audioDeviceCallback, handler);
}
@Nullable Intent stickyIntent = null; @Nullable Intent stickyIntent = null;
if (receiver != null) { if (hdmiAudioPlugBroadcastReceiver != null) {
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG); IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_HDMI_AUDIO_PLUG);
stickyIntent = stickyIntent =
context.registerReceiver( context.registerReceiver(
receiver, intentFilter, /* broadcastPermission= */ null, handler); hdmiAudioPlugBroadcastReceiver,
intentFilter,
/* broadcastPermission= */ null,
handler);
} }
audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent); audioCapabilities = AudioCapabilities.getCapabilities(context, stickyIntent);
return audioCapabilities; return audioCapabilities;
@ -108,8 +122,11 @@ public final class AudioCapabilitiesReceiver {
return; return;
} }
audioCapabilities = null; audioCapabilities = null;
if (receiver != null) { if (Util.SDK_INT >= 23 && audioDeviceCallback != null) {
context.unregisterReceiver(receiver); Api23.unregisterAudioDeviceCallback(context, audioDeviceCallback);
}
if (hdmiAudioPlugBroadcastReceiver != null) {
context.unregisterReceiver(hdmiAudioPlugBroadcastReceiver);
} }
if (externalSurroundSoundSettingObserver != null) { if (externalSurroundSoundSettingObserver != null) {
externalSurroundSoundSettingObserver.unregister(); externalSurroundSoundSettingObserver.unregister();
@ -159,4 +176,37 @@ public final class AudioCapabilitiesReceiver {
onNewAudioCapabilities(AudioCapabilities.getCapabilities(context)); onNewAudioCapabilities(AudioCapabilities.getCapabilities(context));
} }
} }
@RequiresApi(23)
private final class AudioDeviceCallbackV23 extends AudioDeviceCallback {
@Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
onNewAudioCapabilities(AudioCapabilities.getCapabilities(context));
}
@Override
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
onNewAudioCapabilities(AudioCapabilities.getCapabilities(context));
}
}
@RequiresApi(23)
private static final class Api23 {
@DoNotInline
public static void registerAudioDeviceCallback(
Context context, AudioDeviceCallback callback, Handler handler) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
checkNotNull(audioManager).registerAudioDeviceCallback(callback, handler);
}
@DoNotInline
public static void unregisterAudioDeviceCallback(
Context context, AudioDeviceCallback callback) {
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
checkNotNull(audioManager).unregisterAudioDeviceCallback(callback);
}
private Api23() {}
}
} }