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 7d8e06df2185..d689aab96ce9 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1987,6 +1987,10 @@ STREAM_MUSIC as if it's on TV platform. --> <bool name="config_single_volume">false</bool> + <!-- 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 60d847e59368..e2f29ef5f326 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -273,6 +273,7 @@ <java-symbol type="attr" name="autofillSaveCustomSubtitleMaxHeight"/> <java-symbol type="bool" name="action_bar_embed_tabs" /> <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" /> + <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 f2c50c570ccb..75bc63ec56bd 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -965,7 +965,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 164f5c67837d..192075358c94 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) { @@ -1486,18 +1497,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); |