Commit ccd3df3b authored by shyam's avatar shyam Committed by Commit Bot

[Chromecast] Backwards compatible AudioFocus

Creating an abstraction called CastAudioFocusRequest to handle backwards
compatibility of AudioFocus methods in AudioManager.

Merge-With: eureka-internal/191659
Bug: 112064938
Test: junit test
Change-Id: I914cec6a6bd2179f02ab5fd6959fcf3157b3e637
Reviewed-on: https://chromium-review.googlesource.com/1165884Reviewed-by: default avatarSimeon Anfinrud <sanfin@chromium.org>
Commit-Queue: Shyamsundar Parthasarathy <shyamsundarp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582347}
parent e6e258a1
...@@ -57,8 +57,10 @@ android_resources("cast_shell_android_resources") { ...@@ -57,8 +57,10 @@ android_resources("cast_shell_android_resources") {
android_library("cast_audio_manager_java") { android_library("cast_audio_manager_java") {
java_src_dir = "//chromecast/browser/android/apk/src" java_src_dir = "//chromecast/browser/android/apk/src"
java_files = java_files = [
[ "$java_src_dir/org/chromium/chromecast/shell/CastAudioManager.java" ] "$java_src_dir/org/chromium/chromecast/shell/CastAudioManager.java",
"$java_src_dir/org/chromium/chromecast/shell/CastAudioFocusRequest.java",
]
deps = [ deps = [
"//base:base_java", "//base:base_java",
"//chromecast/base:base_java", "//chromecast/base:base_java",
...@@ -162,6 +164,7 @@ junit_binary("cast_shell_junit_tests") { ...@@ -162,6 +164,7 @@ junit_binary("cast_shell_junit_tests") {
java_files = [ java_files = [
"junit/src/org/chromium/chromecast/shell/AsyncTaskRunnerTest.java", "junit/src/org/chromium/chromecast/shell/AsyncTaskRunnerTest.java",
"junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java", "junit/src/org/chromium/chromecast/shell/CastAudioManagerTest.java",
"junit/src/org/chromium/chromecast/shell/CastAudioFocusRequestTest.java",
"junit/src/org/chromium/chromecast/shell/CastCommandLineHelperTest.java", "junit/src/org/chromium/chromecast/shell/CastCommandLineHelperTest.java",
"junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java", "junit/src/org/chromium/chromecast/shell/CastWebContentsActivityTest.java",
"junit/src/org/chromium/chromecast/shell/CastWebContentsComponentTest.java", "junit/src/org/chromium/chromecast/shell/CastWebContentsComponentTest.java",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chromecast.shell;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import android.support.annotation.NonNull;
import org.chromium.base.Log;
import java.util.HashSet;
import java.util.Set;
/**
* Wrapper for Cast code to pass parameter to AudioFocus methods.
* This maintains backwards compatibility with old APIs - requestAudioFocus() and
* abandonAudioFocus()
*/
public class CastAudioFocusRequest {
private static final String TAG = "CastAudioFocus";
private AudioFocusRequest mAudioFocusRequest;
private AudioAttributes mAudioAttributes;
private int mFocusGain;
private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener;
CastAudioFocusRequest(AudioFocusRequest audioFocusRequest) {
mAudioFocusRequest = audioFocusRequest;
}
CastAudioFocusRequest(AudioAttributes audioAttributes, int focusGain,
AudioManager.OnAudioFocusChangeListener l) {
mAudioAttributes = audioAttributes;
mFocusGain = focusGain;
mAudioFocusChangeListener = l;
}
AudioFocusRequest getAudioFocusRequest() {
return mAudioFocusRequest;
}
private int getStreamType() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mAudioAttributes != null) {
switch (mAudioAttributes.getContentType()) {
case AudioAttributes.CONTENT_TYPE_MOVIE:
case AudioAttributes.CONTENT_TYPE_MUSIC:
return AudioManager.STREAM_MUSIC;
case AudioAttributes.CONTENT_TYPE_SONIFICATION:
return AudioManager.STREAM_ALARM;
case AudioAttributes.CONTENT_TYPE_SPEECH:
return AudioManager.STREAM_VOICE_CALL;
case AudioAttributes.CONTENT_TYPE_UNKNOWN:
default:
return AudioManager.STREAM_SYSTEM;
}
}
}
return 0;
}
void setAudioFocusChangeListener(AudioManager.OnAudioFocusChangeListener l) {
mAudioFocusChangeListener = l;
}
int request(AudioManager audioManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return audioManager.requestAudioFocus(mAudioFocusRequest);
} else {
return audioManager.requestAudioFocus(
mAudioFocusChangeListener, getStreamType(), mFocusGain);
}
}
int abandon(AudioManager audioManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return audioManager.abandonAudioFocusRequest(mAudioFocusRequest);
} else {
return audioManager.abandonAudioFocus(mAudioFocusChangeListener);
}
}
/**
* Backwards compatible builder method to create CastAudioFocusRequest object.
*/
public static class Builder {
private AudioAttributes mAudioAttributes;
private int mFocusGain;
private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener;
private Set<Integer> mValidFocusGainValues;
public Builder() {
mAudioAttributes = null;
mFocusGain = 0;
mAudioFocusChangeListener = null;
mValidFocusGainValues = new HashSet<Integer>();
mValidFocusGainValues.add(AudioManager.AUDIOFOCUS_GAIN);
mValidFocusGainValues.add(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
mValidFocusGainValues.add(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
mValidFocusGainValues.add(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
}
public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes audioAttributes) {
mAudioAttributes = audioAttributes;
return this;
}
public @NonNull Builder setFocusGain(int focusGain) {
if (mValidFocusGainValues.contains(focusGain)) {
mFocusGain = focusGain;
} else {
Log.e(TAG, "Invalid focus gain value " + focusGain);
mFocusGain = AudioManager.AUDIOFOCUS_GAIN;
}
return this;
}
public @NonNull Builder setAudioFocusChangeListener(
AudioManager.OnAudioFocusChangeListener l) {
mAudioFocusChangeListener = l;
return this;
}
public CastAudioFocusRequest build() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
AudioFocusRequest.Builder builder = new AudioFocusRequest.Builder(mFocusGain);
if (mAudioAttributes != null) {
builder = builder.setAudioAttributes(mAudioAttributes);
}
if (mAudioFocusChangeListener != null) {
builder = builder.setOnAudioFocusChangeListener(mAudioFocusChangeListener);
}
AudioFocusRequest audioFocusRequest = builder.build();
return new CastAudioFocusRequest(audioFocusRequest);
} else {
return new CastAudioFocusRequest(
mAudioAttributes, mFocusGain, mAudioFocusChangeListener);
}
}
}
}
...@@ -4,9 +4,7 @@ ...@@ -4,9 +4,7 @@
package org.chromium.chromecast.shell; package org.chromium.chromecast.shell;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.media.AudioFocusRequest;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Build; import android.os.Build;
...@@ -49,7 +47,7 @@ public class CastAudioManager { ...@@ -49,7 +47,7 @@ public class CastAudioManager {
* TODO(sanfin): Distinguish between transient, ducking, and full audio focus losses. * TODO(sanfin): Distinguish between transient, ducking, and full audio focus losses.
*/ */
public Observable<Unit> requestAudioFocusWhen( public Observable<Unit> requestAudioFocusWhen(
Observable<?> event, int streamType, int durationHint) { Observable<?> event, CastAudioFocusRequest castAudioFocusRequest) {
Controller<Unit> audioFocusState = new Controller<>(); Controller<Unit> audioFocusState = new Controller<>();
event.watch(x -> { event.watch(x -> {
AudioManager.OnAudioFocusChangeListener listener = (int focusChange) -> { AudioManager.OnAudioFocusChangeListener listener = (int focusChange) -> {
...@@ -62,14 +60,16 @@ public class CastAudioManager { ...@@ -62,14 +60,16 @@ public class CastAudioManager {
return; return;
} }
}; };
castAudioFocusRequest.setAudioFocusChangeListener(listener);
// Request audio focus when the source event is activated. // Request audio focus when the source event is activated.
if (requestAudioFocus(listener, streamType, durationHint) if (requestAudioFocus(castAudioFocusRequest)
!= AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.e(TAG, "Failed to get audio focus"); Log.e(TAG, "Failed to get audio focus");
} }
// Abandon audio focus when the source event is deactivated. // Abandon audio focus when the source event is deactivated.
return () -> { return () -> {
if (abandonAudioFocus(listener) != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { if (abandonAudioFocus(castAudioFocusRequest)
!= AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
Log.e(TAG, "Failed to abandon audio focus"); Log.e(TAG, "Failed to abandon audio focus");
} }
audioFocusState.reset(); audioFocusState.reset();
...@@ -107,25 +107,12 @@ public class CastAudioManager { ...@@ -107,25 +107,12 @@ public class CastAudioManager {
} }
} }
@SuppressLint("NewApi") public int requestAudioFocus(CastAudioFocusRequest castAudioFocusRequest) {
public int requestAudioFocus(AudioFocusRequest focusRequest) { return castAudioFocusRequest.request(mAudioManager);
return mAudioManager.requestAudioFocus(focusRequest);
} }
@SuppressWarnings("deprecation") public int abandonAudioFocus(CastAudioFocusRequest castAudioFocusRequest) {
public int requestAudioFocus( return castAudioFocusRequest.abandon(mAudioManager);
AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint) {
return mAudioManager.requestAudioFocus(l, streamType, durationHint);
}
@SuppressLint("NewApi")
public int abandonAudioFocusRequest(AudioFocusRequest focusRequest) {
return mAudioManager.abandonAudioFocusRequest(focusRequest);
}
@SuppressWarnings("deprecation")
public int abandonAudioFocus(AudioManager.OnAudioFocusChangeListener l) {
return mAudioManager.abandonAudioFocus(l);
} }
public int getStreamMaxVolume(int streamType) { public int getStreamMaxVolume(int streamType) {
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chromecast.shell;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.annotation.Config;
import org.chromium.testing.local.LocalRobolectricTestRunner;
/**
* Tests for CastAudioFocusRequest.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public final class CastAudioFocusRequestTest {
private @Mock AudioManager mAudioManager;
@Before
public void setUp() {
mAudioManager = mock(AudioManager.class);
}
@Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testOldAudioFocusRequest() {
AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioFocusChangeListener(null)
.setAudioAttributes(audioAttributes)
.build();
castAudioFocusRequest.request(mAudioManager);
verify(mAudioManager)
.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
@Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testOldAbandonAudioFocus() {
AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioFocusChangeListener(null)
.setAudioAttributes(audioAttributes)
.build();
castAudioFocusRequest.abandon(mAudioManager);
verify(mAudioManager).abandonAudioFocus(null);
}
@Test
@Config(sdk = Build.VERSION_CODES.O)
public void testNewAudioFocusRequest() {
AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioFocusChangeListener(null)
.setAudioAttributes(audioAttributes)
.build();
castAudioFocusRequest.request(mAudioManager);
verify(mAudioManager).requestAudioFocus(castAudioFocusRequest.getAudioFocusRequest());
}
@Test
@Config(sdk = Build.VERSION_CODES.O)
public void testNewAbandonAudioFocus() {
AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioFocusChangeListener(null)
.setAudioAttributes(audioAttributes)
.build();
castAudioFocusRequest.abandon(mAudioManager);
verify(mAudioManager)
.abandonAudioFocusRequest(castAudioFocusRequest.getAudioFocusRequest());
}
}
...@@ -10,6 +10,7 @@ import static org.junit.Assert.assertFalse; ...@@ -10,6 +10,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import android.media.AudioAttributes;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Build; import android.os.Build;
import android.util.SparseIntArray; import android.util.SparseIntArray;
...@@ -36,14 +37,26 @@ import java.util.List; ...@@ -36,14 +37,26 @@ import java.util.List;
@Config(manifest = Config.NONE) @Config(manifest = Config.NONE)
public class CastAudioManagerTest { public class CastAudioManagerTest {
@Test @Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testAudioFocusScopeActivatedWhenRequestGranted() { public void testAudioFocusScopeActivatedWhenRequestGranted() {
CastAudioManager audioManager = CastAudioManager audioManager =
CastAudioManager.getAudioManager(RuntimeEnvironment.application); CastAudioManager.getAudioManager(RuntimeEnvironment.application);
ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal()); ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal());
Controller<Unit> requestAudioFocusState = new Controller<>(); Controller<Unit> requestAudioFocusState = new Controller<>();
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Observable<Unit> gotAudioFocusState = audioManager.requestAudioFocusWhen(
requestAudioFocusState, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); AudioAttributes audioAttributes =
new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build();
Observable<Unit> gotAudioFocusState =
audioManager.requestAudioFocusWhen(requestAudioFocusState, castAudioFocusRequest);
gotAudioFocusState.watch(x -> { gotAudioFocusState.watch(x -> {
result.add("Got audio focus"); result.add("Got audio focus");
return () -> result.add("Lost audio focus"); return () -> result.add("Lost audio focus");
...@@ -55,14 +68,25 @@ public class CastAudioManagerTest { ...@@ -55,14 +68,25 @@ public class CastAudioManagerTest {
} }
@Test @Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testAudioFocusScopeDeactivatedWhenFocusRequestStateIsReset() { public void testAudioFocusScopeDeactivatedWhenFocusRequestStateIsReset() {
CastAudioManager audioManager = CastAudioManager audioManager =
CastAudioManager.getAudioManager(RuntimeEnvironment.application); CastAudioManager.getAudioManager(RuntimeEnvironment.application);
ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal()); ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal());
Controller<Unit> requestAudioFocusState = new Controller<>(); Controller<Unit> requestAudioFocusState = new Controller<>();
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Observable<Unit> gotAudioFocusState = audioManager.requestAudioFocusWhen( AudioAttributes audioAttributes =
requestAudioFocusState, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build();
Observable<Unit> gotAudioFocusState =
audioManager.requestAudioFocusWhen(requestAudioFocusState, castAudioFocusRequest);
gotAudioFocusState.watch(x -> { gotAudioFocusState.watch(x -> {
result.add("Got audio focus"); result.add("Got audio focus");
return () -> result.add("Lost audio focus"); return () -> result.add("Lost audio focus");
...@@ -75,14 +99,25 @@ public class CastAudioManagerTest { ...@@ -75,14 +99,25 @@ public class CastAudioManagerTest {
} }
@Test @Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testAudioFocusScopeDeactivatedWhenAudioFocusIsLostButRequestStillActive() { public void testAudioFocusScopeDeactivatedWhenAudioFocusIsLostButRequestStillActive() {
CastAudioManager audioManager = CastAudioManager audioManager =
CastAudioManager.getAudioManager(RuntimeEnvironment.application); CastAudioManager.getAudioManager(RuntimeEnvironment.application);
ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal()); ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal());
Controller<Unit> requestAudioFocusState = new Controller<>(); Controller<Unit> requestAudioFocusState = new Controller<>();
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Observable<Unit> gotAudioFocusState = audioManager.requestAudioFocusWhen( AudioAttributes audioAttributes =
requestAudioFocusState, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build();
Observable<Unit> gotAudioFocusState =
audioManager.requestAudioFocusWhen(requestAudioFocusState, castAudioFocusRequest);
gotAudioFocusState.watch(x -> { gotAudioFocusState.watch(x -> {
result.add("Got audio focus"); result.add("Got audio focus");
return () -> result.add("Lost audio focus"); return () -> result.add("Lost audio focus");
...@@ -96,14 +131,25 @@ public class CastAudioManagerTest { ...@@ -96,14 +131,25 @@ public class CastAudioManagerTest {
} }
@Test @Test
@Config(sdk = Build.VERSION_CODES.N_MR1)
public void testAudioFocusScopeReactivatedWhenAudioFocusIsLostAndRegained() { public void testAudioFocusScopeReactivatedWhenAudioFocusIsLostAndRegained() {
CastAudioManager audioManager = CastAudioManager audioManager =
CastAudioManager.getAudioManager(RuntimeEnvironment.application); CastAudioManager.getAudioManager(RuntimeEnvironment.application);
ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal()); ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal());
Controller<Unit> requestAudioFocusState = new Controller<>(); Controller<Unit> requestAudioFocusState = new Controller<>();
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Observable<Unit> gotAudioFocusState = audioManager.requestAudioFocusWhen( AudioAttributes audioAttributes =
requestAudioFocusState, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build();
Observable<Unit> gotAudioFocusState =
audioManager.requestAudioFocusWhen(requestAudioFocusState, castAudioFocusRequest);
gotAudioFocusState.watch(x -> { gotAudioFocusState.watch(x -> {
result.add("Got audio focus"); result.add("Got audio focus");
return () -> result.add("Lost audio focus"); return () -> result.add("Lost audio focus");
...@@ -124,8 +170,18 @@ public class CastAudioManagerTest { ...@@ -124,8 +170,18 @@ public class CastAudioManagerTest {
ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal()); ShadowAudioManager shadowAudioManager = Shadows.shadowOf(audioManager.getInternal());
Controller<Unit> requestAudioFocusState = new Controller<>(); Controller<Unit> requestAudioFocusState = new Controller<>();
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Observable<Unit> gotAudioFocusState = audioManager.requestAudioFocusWhen( AudioAttributes audioAttributes =
requestAudioFocusState, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
CastAudioFocusRequest castAudioFocusRequest =
new CastAudioFocusRequest.Builder()
.setFocusGain(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(audioAttributes)
.build();
Observable<Unit> gotAudioFocusState =
audioManager.requestAudioFocusWhen(requestAudioFocusState, castAudioFocusRequest);
gotAudioFocusState.watch(x -> { gotAudioFocusState.watch(x -> {
result.add("Got audio focus"); result.add("Got audio focus");
return () -> result.add("Lost audio focus"); return () -> result.add("Lost audio focus");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment