diff options
5 files changed, 41 insertions, 8 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8152b79c8659..d95a5cece3ae 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2058,6 +2058,10 @@ <!-- The default volume for the ring stream --> <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 on grouped devices. --> <bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index c96e45265897..2f311f336b08 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -278,6 +278,7 @@ <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_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_bluetooth_address_validation" /> <java-symbol type="integer" name="config_chooser_max_targets_per_row" /> diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 0a081bfbee96..0c4ea9764f51 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -1005,7 +1005,9 @@ public class AudioService extends IAudioService.Stub 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); mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java index b7e817e15452..2187cecee9a3 100644 --- a/services/core/java/com/android/server/audio/SpatializerHelper.java +++ b/services/core/java/com/android/server/audio/SpatializerHelper.java @@ -169,9 +169,20 @@ public class SpatializerHelper { //------------------------------------------------------ // initialization - SpatializerHelper(@NonNull AudioService mother, @NonNull AudioSystemAdapter asa) { + @SuppressWarnings("StaticAssignmentInConstructor") + SpatializerHelper(@NonNull AudioService mother, @NonNull AudioSystemAdapter asa, + boolean headTrackingEnabledByDefault) { mAudioService = mother; 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) { @@ -1499,18 +1510,26 @@ public class SpatializerHelper { } /*package*/ static final class SADeviceState { + private static boolean sHeadTrackingEnabledDefault = false; final @AudioDeviceInfo.AudioDeviceType int mDeviceType; final @NonNull String mDeviceAddress; boolean mEnabled = true; // by default, SA is enabled on any device 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_DEVICE_SEPARATOR_CHAR = "|"; 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; mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : ""; + mHeadTrackerEnabled = sHeadTrackingEnabledDefault; } @Override diff --git a/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java index b17c3a18d89e..428eaff9e5bc 100644 --- a/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java +++ b/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java @@ -55,14 +55,20 @@ public class SpatializerHelperTest { mMockAudioService = mock(AudioService.class); 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 public void testSADeviceStateNullAddressCtor() throws Exception { 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); Assert.fail(); } catch (NullPointerException e) { } } @@ -88,11 +94,12 @@ public class SpatializerHelperTest { final AudioDeviceAttributes dev1 = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); 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 = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, "R2:D2:bloop"); doNothing().when(mMockAudioService).persistSpatialAudioDeviceSettings(); + mSpatHelper.initForTest(true /*binaural*/, true /*transaural*/); // test with single device mSpatHelper.addCompatibleAudioDevice(dev1); |