Merge "AudioService: properties for configuring head tracking default" into tm-qpr-dev

This commit is contained in:
TreeHugger Robot
2022-09-02 13:18:41 +00:00
committed by Android (Google) Code Review
5 changed files with 41 additions and 8 deletions

View File

@@ -2060,6 +2060,10 @@
<!-- The default volume for the ring stream --> <!-- The default volume for the ring stream -->
<integer name="config_audio_ring_vol_default">5</integer> <integer name="config_audio_ring_vol_default">5</integer>
<!-- The default value for whether head tracking for
spatial audio is enabled for a newly connected audio device -->
<bool name="config_spatial_audio_head_tracking_enabled_default">false</bool>
<!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions <!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions
on grouped devices. --> on grouped devices. -->
<bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool> <bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool>

View File

@@ -278,6 +278,7 @@
<java-symbol type="integer" name="config_audio_notif_vol_steps" /> <java-symbol type="integer" name="config_audio_notif_vol_steps" />
<java-symbol type="integer" name="config_audio_ring_vol_default" /> <java-symbol type="integer" name="config_audio_ring_vol_default" />
<java-symbol type="integer" name="config_audio_ring_vol_steps" /> <java-symbol type="integer" name="config_audio_ring_vol_steps" />
<java-symbol type="bool" name="config_spatial_audio_head_tracking_enabled_default" />
<java-symbol type="bool" name="config_avoidGfxAccel" /> <java-symbol type="bool" name="config_avoidGfxAccel" />
<java-symbol type="bool" name="config_bluetooth_address_validation" /> <java-symbol type="bool" name="config_bluetooth_address_validation" />
<java-symbol type="integer" name="config_chooser_max_targets_per_row" /> <java-symbol type="integer" name="config_chooser_max_targets_per_row" />

View File

@@ -1005,7 +1005,9 @@ public class AudioService extends IAudioService.Stub
mSfxHelper = new SoundEffectsHelper(mContext); mSfxHelper = new SoundEffectsHelper(mContext);
mSpatializerHelper = new SpatializerHelper(this, mAudioSystem); final boolean headTrackingDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, headTrackingDefault);
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();

View File

@@ -169,9 +169,20 @@ public class SpatializerHelper {
//------------------------------------------------------ //------------------------------------------------------
// initialization // initialization
SpatializerHelper(@NonNull AudioService mother, @NonNull AudioSystemAdapter asa) { @SuppressWarnings("StaticAssignmentInConstructor")
SpatializerHelper(@NonNull AudioService mother, @NonNull AudioSystemAdapter asa,
boolean headTrackingEnabledByDefault) {
mAudioService = mother; mAudioService = mother;
mASA = asa; mASA = asa;
// "StaticAssignmentInConstructor" warning is suppressed as the SpatializerHelper being
// constructed here is the factory for SADeviceState, thus SADeviceState and its
// private static field sHeadTrackingEnabledDefault should never be accessed directly.
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) {
@@ -1502,18 +1513,26 @@ public class SpatializerHelper {
} }
/*package*/ static final class SADeviceState { /*package*/ static final class SADeviceState {
private static boolean sHeadTrackingEnabledDefault = false;
final @AudioDeviceInfo.AudioDeviceType int mDeviceType; final @AudioDeviceInfo.AudioDeviceType int mDeviceType;
final @NonNull String mDeviceAddress; final @NonNull String mDeviceAddress;
boolean mEnabled = true; // by default, SA is enabled on any device boolean mEnabled = true; // by default, SA is enabled on any device
boolean mHasHeadTracker = false; boolean mHasHeadTracker = false;
boolean mHeadTrackerEnabled = true; // by default, if head tracker is present, use it boolean mHeadTrackerEnabled;
static final String SETTING_FIELD_SEPARATOR = ","; static final String SETTING_FIELD_SEPARATOR = ",";
static final String SETTING_DEVICE_SEPARATOR_CHAR = "|"; static final String SETTING_DEVICE_SEPARATOR_CHAR = "|";
static final String SETTING_DEVICE_SEPARATOR = "\\|"; static final String SETTING_DEVICE_SEPARATOR = "\\|";
SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @NonNull String address) { /**
* Constructor
* @param deviceType
* @param address must be non-null for wireless devices
* @throws NullPointerException if a null address is passed for a wireless device
*/
SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @Nullable String address) {
mDeviceType = deviceType; mDeviceType = deviceType;
mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : ""; mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : "";
mHeadTrackerEnabled = sHeadTrackingEnabledDefault;
} }
@Override @Override

View File

@@ -55,14 +55,20 @@ public class SpatializerHelperTest {
mMockAudioService = mock(AudioService.class); mMockAudioService = mock(AudioService.class);
mSpyAudioSystem = spy(new NoOpAudioSystemAdapter()); mSpyAudioSystem = spy(new NoOpAudioSystemAdapter());
mSpatHelper = new SpatializerHelper(mMockAudioService, mSpyAudioSystem); mSpatHelper = new SpatializerHelper(mMockAudioService, mSpyAudioSystem,
false /*headTrackingEnabledByDefault*/);
} }
/**
* Test that constructing an SADeviceState instance requires a non-null address for a
* wireless type, but can take null for a non-wireless type;
* @throws Exception
*/
@Test @Test
public void testSADeviceStateNullAddressCtor() throws Exception { public void testSADeviceStateNullAddressCtor() throws Exception {
try { try {
SADeviceState devState = new SADeviceState( SADeviceState devState = new SADeviceState(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, null);
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, null); devState = new SADeviceState(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, null);
Assert.fail(); Assert.fail();
} catch (NullPointerException e) { } } catch (NullPointerException e) { }
} }
@@ -88,11 +94,12 @@ public class SpatializerHelperTest {
final AudioDeviceAttributes dev1 = final AudioDeviceAttributes dev1 =
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, "");
final AudioDeviceAttributes dev2 = final AudioDeviceAttributes dev2 =
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "C3:P0:beep"); new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "C3:PO:beep");
final AudioDeviceAttributes dev3 = final AudioDeviceAttributes dev3 =
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "R2:D2:bloop"); new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "R2:D2:bloop");
doNothing().when(mMockAudioService).persistSpatialAudioDeviceSettings(); doNothing().when(mMockAudioService).persistSpatialAudioDeviceSettings();
mSpatHelper.initForTest(true /*binaural*/, true /*transaural*/);
// test with single device // test with single device
mSpatHelper.addCompatibleAudioDevice(dev1); mSpatHelper.addCompatibleAudioDevice(dev1);