SpatializerHelper: fix canBeSpatializedOnDevice NPE
Check whether routing is known when calling
canBeSpatializedOnDevice. Unknown routing is defined
by an empty list of devices for the requested
AudioAttributes.
Add test method in SpatializerHelper to force state.
Implement a unit test covering failure modes when
querying routing.
Test: atest com.android.server.audio.SpatializerHelperTest#testNoRoutingCanBeSpatialized
Bug: 267963974
Change-Id: Ib6d73fec4d57cf372361762b5c1d85329794de92
Merged-In: Ib6d73fec4d57cf372361762b5c1d85329794de92
(cherry picked from commit af85e232b7)
This commit is contained in:
@@ -107,12 +107,12 @@ public class SpatializerHelper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Spatializer state machine
|
// Spatializer state machine
|
||||||
private static final int STATE_UNINITIALIZED = 0;
|
/*package*/ static final int STATE_UNINITIALIZED = 0;
|
||||||
private static final int STATE_NOT_SUPPORTED = 1;
|
/*package*/ static final int STATE_NOT_SUPPORTED = 1;
|
||||||
private static final int STATE_DISABLED_UNAVAILABLE = 3;
|
/*package*/ static final int STATE_DISABLED_UNAVAILABLE = 3;
|
||||||
private static final int STATE_ENABLED_UNAVAILABLE = 4;
|
/*package*/ static final int STATE_ENABLED_UNAVAILABLE = 4;
|
||||||
private static final int STATE_ENABLED_AVAILABLE = 5;
|
/*package*/ static final int STATE_ENABLED_AVAILABLE = 5;
|
||||||
private static final int STATE_DISABLED_AVAILABLE = 6;
|
/*package*/ static final int STATE_DISABLED_AVAILABLE = 6;
|
||||||
private int mState = STATE_UNINITIALIZED;
|
private int mState = STATE_UNINITIALIZED;
|
||||||
|
|
||||||
private boolean mFeatureEnabled = false;
|
private boolean mFeatureEnabled = false;
|
||||||
@@ -148,9 +148,9 @@ public class SpatializerHelper {
|
|||||||
.setSampleRate(48000)
|
.setSampleRate(48000)
|
||||||
.setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
|
.setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
|
||||||
.build();
|
.build();
|
||||||
// device array to store the routing for the default attributes and format, size 1 because
|
// device array to store the routing for the default attributes and format, initialized to
|
||||||
// media is never expected to be duplicated
|
// an empty list as routing hasn't been established yet
|
||||||
private static final AudioDeviceAttributes[] ROUTING_DEVICES = new AudioDeviceAttributes[1];
|
private static ArrayList<AudioDeviceAttributes> sRoutingDevices = new ArrayList<>(0);
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// audio device compatibility / enabled
|
// audio device compatibility / enabled
|
||||||
@@ -181,11 +181,6 @@ public class SpatializerHelper {
|
|||||||
SADeviceState.sHeadTrackingEnabledDefault = headTrackingEnabledByDefault;
|
SADeviceState.sHeadTrackingEnabledDefault = headTrackingEnabledByDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void initForTest(boolean hasBinaural, boolean hasTransaural) {
|
|
||||||
mBinauralSupported = hasBinaural;
|
|
||||||
mTransauralSupported = hasTransaural;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized void init(boolean effectExpected, @Nullable String settings) {
|
synchronized void init(boolean effectExpected, @Nullable String settings) {
|
||||||
loglogi("init effectExpected=" + effectExpected);
|
loglogi("init effectExpected=" + effectExpected);
|
||||||
if (!effectExpected) {
|
if (!effectExpected) {
|
||||||
@@ -319,8 +314,7 @@ public class SpatializerHelper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mState = STATE_DISABLED_UNAVAILABLE;
|
mState = STATE_DISABLED_UNAVAILABLE;
|
||||||
mASA.getDevicesForAttributes(
|
sRoutingDevices = getRoutingDevices(DEFAULT_ATTRIBUTES);
|
||||||
DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
|
|
||||||
// note at this point mSpat is still not instantiated
|
// note at this point mSpat is still not instantiated
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,34 +356,35 @@ public class SpatializerHelper {
|
|||||||
case STATE_DISABLED_AVAILABLE:
|
case STATE_DISABLED_AVAILABLE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mASA.getDevicesForAttributes(
|
|
||||||
DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
|
sRoutingDevices = getRoutingDevices(DEFAULT_ATTRIBUTES);
|
||||||
|
|
||||||
// check validity of routing information
|
// check validity of routing information
|
||||||
if (ROUTING_DEVICES[0] == null) {
|
if (sRoutingDevices.isEmpty()) {
|
||||||
logloge("onRoutingUpdated: device is null, no Spatial Audio");
|
logloge("onRoutingUpdated: no device, no Spatial Audio");
|
||||||
setDispatchAvailableState(false);
|
setDispatchAvailableState(false);
|
||||||
// not changing the spatializer level as this is likely a transient state
|
// not changing the spatializer level as this is likely a transient state
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final AudioDeviceAttributes currentDevice = sRoutingDevices.get(0);
|
||||||
|
|
||||||
// is media routed to a new device?
|
// is media routed to a new device?
|
||||||
if (isWireless(ROUTING_DEVICES[0].getType())) {
|
if (isWireless(currentDevice.getType())) {
|
||||||
addWirelessDeviceIfNew(ROUTING_DEVICES[0]);
|
addWirelessDeviceIfNew(currentDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find if media device enabled / available
|
// find if media device enabled / available
|
||||||
final Pair<Boolean, Boolean> enabledAvailable = evaluateState(ROUTING_DEVICES[0]);
|
final Pair<Boolean, Boolean> enabledAvailable = evaluateState(currentDevice);
|
||||||
|
|
||||||
boolean able = false;
|
boolean able = false;
|
||||||
if (enabledAvailable.second) {
|
if (enabledAvailable.second) {
|
||||||
// available for Spatial audio, check w/ effect
|
// available for Spatial audio, check w/ effect
|
||||||
able = canBeSpatializedOnDevice(DEFAULT_ATTRIBUTES, DEFAULT_FORMAT, ROUTING_DEVICES);
|
able = canBeSpatializedOnDevice(DEFAULT_ATTRIBUTES, DEFAULT_FORMAT, sRoutingDevices);
|
||||||
loglogi("onRoutingUpdated: can spatialize media 5.1:" + able
|
loglogi("onRoutingUpdated: can spatialize media 5.1:" + able
|
||||||
+ " on device:" + ROUTING_DEVICES[0]);
|
+ " on device:" + currentDevice);
|
||||||
setDispatchAvailableState(able);
|
setDispatchAvailableState(able);
|
||||||
} else {
|
} else {
|
||||||
loglogi("onRoutingUpdated: device:" + ROUTING_DEVICES[0]
|
loglogi("onRoutingUpdated: device:" + currentDevice
|
||||||
+ " not available for Spatial Audio");
|
+ " not available for Spatial Audio");
|
||||||
setDispatchAvailableState(false);
|
setDispatchAvailableState(false);
|
||||||
}
|
}
|
||||||
@@ -397,10 +392,10 @@ public class SpatializerHelper {
|
|||||||
boolean enabled = able && enabledAvailable.first;
|
boolean enabled = able && enabledAvailable.first;
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
loglogi("Enabling Spatial Audio since enabled for media device:"
|
loglogi("Enabling Spatial Audio since enabled for media device:"
|
||||||
+ ROUTING_DEVICES[0]);
|
+ currentDevice);
|
||||||
} else {
|
} else {
|
||||||
loglogi("Disabling Spatial Audio since disabled for media device:"
|
loglogi("Disabling Spatial Audio since disabled for media device:"
|
||||||
+ ROUTING_DEVICES[0]);
|
+ currentDevice);
|
||||||
}
|
}
|
||||||
if (mSpat != null) {
|
if (mSpat != null) {
|
||||||
byte level = enabled ? (byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL
|
byte level = enabled ? (byte) Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL
|
||||||
@@ -733,9 +728,13 @@ public class SpatializerHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,
|
private synchronized boolean canBeSpatializedOnDevice(@NonNull AudioAttributes attributes,
|
||||||
@NonNull AudioFormat format, @NonNull AudioDeviceAttributes[] devices) {
|
@NonNull AudioFormat format, @NonNull ArrayList<AudioDeviceAttributes> devices) {
|
||||||
if (isDeviceCompatibleWithSpatializationModes(devices[0])) {
|
if (devices.isEmpty()) {
|
||||||
return AudioSystem.canBeSpatialized(attributes, format, devices);
|
return false;
|
||||||
|
}
|
||||||
|
if (isDeviceCompatibleWithSpatializationModes(devices.get(0))) {
|
||||||
|
AudioDeviceAttributes[] devArray = new AudioDeviceAttributes[devices.size()];
|
||||||
|
return AudioSystem.canBeSpatialized(attributes, format, devices.toArray(devArray));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1011,10 +1010,13 @@ public class SpatializerHelper {
|
|||||||
logd("canBeSpatialized false due to usage:" + attributes.getUsage());
|
logd("canBeSpatialized false due to usage:" + attributes.getUsage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AudioDeviceAttributes[] devices = new AudioDeviceAttributes[1];
|
|
||||||
// going through adapter to take advantage of routing cache
|
// going through adapter to take advantage of routing cache
|
||||||
mASA.getDevicesForAttributes(
|
final ArrayList<AudioDeviceAttributes> devices = getRoutingDevices(attributes);
|
||||||
attributes, false /* forVolume */).toArray(devices);
|
if (devices.isEmpty()) {
|
||||||
|
logloge("canBeSpatialized got no device for " + attributes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
|
final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
|
||||||
logd("canBeSpatialized usage:" + attributes.getUsage()
|
logd("canBeSpatialized usage:" + attributes.getUsage()
|
||||||
+ " format:" + format.toLogFriendlyString() + " returning " + able);
|
+ " format:" + format.toLogFriendlyString() + " returning " + able);
|
||||||
@@ -1123,8 +1125,13 @@ public class SpatializerHelper {
|
|||||||
logDeviceState(deviceState, "setHeadTrackerEnabled");
|
logDeviceState(deviceState, "setHeadTrackerEnabled");
|
||||||
|
|
||||||
// check current routing to see if it affects the headtracking mode
|
// check current routing to see if it affects the headtracking mode
|
||||||
if (ROUTING_DEVICES[0] != null && ROUTING_DEVICES[0].getType() == ada.getType()
|
if (sRoutingDevices.isEmpty()) {
|
||||||
&& ROUTING_DEVICES[0].getAddress().equals(ada.getAddress())) {
|
logloge("setHeadTrackerEnabled: no device, bailing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final AudioDeviceAttributes currentDevice = sRoutingDevices.get(0);
|
||||||
|
if (currentDevice.getType() == ada.getType()
|
||||||
|
&& currentDevice.getAddress().equals(ada.getAddress())) {
|
||||||
setDesiredHeadTrackingMode(enabled ? mDesiredHeadTrackingModeWhenEnabled
|
setDesiredHeadTrackingMode(enabled ? mDesiredHeadTrackingModeWhenEnabled
|
||||||
: Spatializer.HEAD_TRACKING_MODE_DISABLED);
|
: Spatializer.HEAD_TRACKING_MODE_DISABLED);
|
||||||
if (enabled && !mHeadTrackerAvailable) {
|
if (enabled && !mHeadTrackerAvailable) {
|
||||||
@@ -1669,10 +1676,11 @@ public class SpatializerHelper {
|
|||||||
|
|
||||||
private int getHeadSensorHandleUpdateTracker() {
|
private int getHeadSensorHandleUpdateTracker() {
|
||||||
int headHandle = -1;
|
int headHandle = -1;
|
||||||
final AudioDeviceAttributes currentDevice = ROUTING_DEVICES[0];
|
if (sRoutingDevices.isEmpty()) {
|
||||||
if (currentDevice == null) {
|
logloge("getHeadSensorHandleUpdateTracker: no device, no head tracker");
|
||||||
return headHandle;
|
return headHandle;
|
||||||
}
|
}
|
||||||
|
final AudioDeviceAttributes currentDevice = sRoutingDevices.get(0);
|
||||||
UUID routingDeviceUuid = mAudioService.getDeviceSensorUuid(currentDevice);
|
UUID routingDeviceUuid = mAudioService.getDeviceSensorUuid(currentDevice);
|
||||||
// We limit only to Sensor.TYPE_HEAD_TRACKER here to avoid confusion
|
// We limit only to Sensor.TYPE_HEAD_TRACKER here to avoid confusion
|
||||||
// with gaming sensors. (Note that Sensor.TYPE_ROTATION_VECTOR
|
// with gaming sensors. (Note that Sensor.TYPE_ROTATION_VECTOR
|
||||||
@@ -1706,6 +1714,23 @@ public class SpatializerHelper {
|
|||||||
return screenHandle;
|
return screenHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns routing for the given attributes
|
||||||
|
* @param aa AudioAttributes whose routing is being queried
|
||||||
|
* @return a non-null never-empty list of devices. If the routing query failed, the list
|
||||||
|
* will contain null.
|
||||||
|
*/
|
||||||
|
private @NonNull ArrayList<AudioDeviceAttributes> getRoutingDevices(AudioAttributes aa) {
|
||||||
|
final ArrayList<AudioDeviceAttributes> devices = mASA.getDevicesForAttributes(
|
||||||
|
aa, false /* forVolume */);
|
||||||
|
for (AudioDeviceAttributes ada : devices) {
|
||||||
|
if (ada == null) {
|
||||||
|
// invalid entry, reject this routing query by returning an empty list
|
||||||
|
return new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
private static void loglogi(String msg) {
|
private static void loglogi(String msg) {
|
||||||
AudioService.sSpatialLogger.enqueueAndLog(msg, EventLogger.Event.ALOGI, TAG);
|
AudioService.sSpatialLogger.enqueueAndLog(msg, EventLogger.Event.ALOGI, TAG);
|
||||||
@@ -1722,4 +1747,13 @@ public class SpatializerHelper {
|
|||||||
/*package*/ void clearSADevices() {
|
/*package*/ void clearSADevices() {
|
||||||
mSADevices.clear();
|
mSADevices.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*package*/ synchronized void forceStateForTest(int state) {
|
||||||
|
mState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ synchronized void initForTest(boolean hasBinaural, boolean hasTransaural) {
|
||||||
|
mBinauralSupported = hasBinaural;
|
||||||
|
mTransauralSupported = hasTransaural;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,17 @@ package com.android.server.audio;
|
|||||||
|
|
||||||
import com.android.server.audio.SpatializerHelper.SADeviceState;
|
import com.android.server.audio.SpatializerHelper.SADeviceState;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.media.AudioAttributes;
|
||||||
import android.media.AudioDeviceAttributes;
|
import android.media.AudioDeviceAttributes;
|
||||||
import android.media.AudioDeviceInfo;
|
import android.media.AudioDeviceInfo;
|
||||||
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioSystem;
|
import android.media.AudioSystem;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -36,6 +41,7 @@ import org.junit.runner.RunWith;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@MediumTest
|
@MediumTest
|
||||||
@@ -49,14 +55,33 @@ public class SpatializerHelperTest {
|
|||||||
|
|
||||||
@Mock private AudioService mMockAudioService;
|
@Mock private AudioService mMockAudioService;
|
||||||
@Spy private AudioSystemAdapter mSpyAudioSystem;
|
@Spy private AudioSystemAdapter mSpyAudioSystem;
|
||||||
|
@Mock private AudioSystemAdapter mMockAudioSystem;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mMockAudioService = mock(AudioService.class);
|
mMockAudioService = mock(AudioService.class);
|
||||||
mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
|
}
|
||||||
|
|
||||||
mSpatHelper = new SpatializerHelper(mMockAudioService, mSpyAudioSystem,
|
/**
|
||||||
|
* Initializes mSpatHelper, the SpatizerHelper instance under test, to use the mock or spy
|
||||||
|
* AudioSystemAdapter
|
||||||
|
* @param useSpyAudioSystem true to use the spy adapter, mSpyAudioSystem, or false to use
|
||||||
|
* the mock adapter, mMockAudioSystem.
|
||||||
|
*/
|
||||||
|
private void setUpSpatHelper(boolean useSpyAudioSystem) {
|
||||||
|
final AudioSystemAdapter asAdapter;
|
||||||
|
if (useSpyAudioSystem) {
|
||||||
|
mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
|
||||||
|
asAdapter = mSpyAudioSystem;
|
||||||
|
mMockAudioSystem = null;
|
||||||
|
} else {
|
||||||
|
mSpyAudioSystem = null;
|
||||||
|
mMockAudioSystem = mock(NoOpAudioSystemAdapter.class);
|
||||||
|
asAdapter = mMockAudioSystem;
|
||||||
|
}
|
||||||
|
mSpatHelper = new SpatializerHelper(mMockAudioService, asAdapter,
|
||||||
false /*headTrackingEnabledByDefault*/);
|
false /*headTrackingEnabledByDefault*/);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +91,7 @@ public class SpatializerHelperTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSADeviceStateNullAddressCtor() throws Exception {
|
public void testSADeviceStateNullAddressCtor() throws Exception {
|
||||||
|
setUpSpatHelper(true /*useSpyAudioSystem*/);
|
||||||
try {
|
try {
|
||||||
SADeviceState devState = new SADeviceState(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, null);
|
SADeviceState devState = new SADeviceState(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, null);
|
||||||
devState = new SADeviceState(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, null);
|
devState = new SADeviceState(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, null);
|
||||||
@@ -76,6 +102,7 @@ public class SpatializerHelperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSADeviceStateStringSerialization() throws Exception {
|
public void testSADeviceStateStringSerialization() throws Exception {
|
||||||
Log.i(TAG, "starting testSADeviceStateStringSerialization");
|
Log.i(TAG, "starting testSADeviceStateStringSerialization");
|
||||||
|
setUpSpatHelper(true /*useSpyAudioSystem*/);
|
||||||
final SADeviceState devState = new SADeviceState(
|
final SADeviceState devState = new SADeviceState(
|
||||||
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "bla");
|
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "bla");
|
||||||
devState.mHasHeadTracker = false;
|
devState.mHasHeadTracker = false;
|
||||||
@@ -91,6 +118,7 @@ public class SpatializerHelperTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSADeviceSettings() throws Exception {
|
public void testSADeviceSettings() throws Exception {
|
||||||
Log.i(TAG, "starting testSADeviceSettings");
|
Log.i(TAG, "starting testSADeviceSettings");
|
||||||
|
setUpSpatHelper(true /*useSpyAudioSystem*/);
|
||||||
final AudioDeviceAttributes dev1 =
|
final AudioDeviceAttributes dev1 =
|
||||||
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, "");
|
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, "");
|
||||||
final AudioDeviceAttributes dev2 =
|
final AudioDeviceAttributes dev2 =
|
||||||
@@ -141,4 +169,34 @@ public class SpatializerHelperTest {
|
|||||||
Log.i(TAG, "device settingsRestored: " + settingsRestored);
|
Log.i(TAG, "device settingsRestored: " + settingsRestored);
|
||||||
Assert.assertEquals(settings, settingsRestored);
|
Assert.assertEquals(settings, settingsRestored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that null devices for routing do not break canBeSpatialized
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNoRoutingCanBeSpatialized() throws Exception {
|
||||||
|
Log.i(TAG, "Starting testNoRoutingCanBeSpatialized");
|
||||||
|
setUpSpatHelper(false /*useSpyAudioSystem*/);
|
||||||
|
mSpatHelper.forceStateForTest(SpatializerHelper.STATE_ENABLED_AVAILABLE);
|
||||||
|
|
||||||
|
final ArrayList<AudioDeviceAttributes> emptyList = new ArrayList<>(0);
|
||||||
|
final ArrayList<AudioDeviceAttributes> listWithNull = new ArrayList<>(1);
|
||||||
|
listWithNull.add(null);
|
||||||
|
final AudioAttributes media = new AudioAttributes.Builder()
|
||||||
|
.setUsage(AudioAttributes.USAGE_MEDIA).build();
|
||||||
|
final AudioFormat spatialFormat = new AudioFormat.Builder()
|
||||||
|
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
|
||||||
|
.setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1).build();
|
||||||
|
|
||||||
|
when(mMockAudioSystem.getDevicesForAttributes(any(AudioAttributes.class), anyBoolean()))
|
||||||
|
.thenReturn(emptyList);
|
||||||
|
Assert.assertFalse("can be spatialized on empty routing",
|
||||||
|
mSpatHelper.canBeSpatialized(media, spatialFormat));
|
||||||
|
|
||||||
|
when(mMockAudioSystem.getDevicesForAttributes(any(AudioAttributes.class), anyBoolean()))
|
||||||
|
.thenReturn(listWithNull);
|
||||||
|
Assert.assertFalse("can be spatialized on null routing",
|
||||||
|
mSpatHelper.canBeSpatialized(media, spatialFormat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user