Loading core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2060,6 +2060,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> Loading core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading services/core/java/com/android/server/audio/AudioService.java +3 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading services/core/java/com/android/server/audio/SpatializerHelper.java +22 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -1502,18 +1513,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 Loading services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java +11 −4 Original line number Diff line number Diff line Loading @@ -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) { } } Loading @@ -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); Loading Loading
core/res/res/values/config.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2060,6 +2060,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> Loading
core/res/res/values/symbols.xml +1 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading
services/core/java/com/android/server/audio/AudioService.java +3 −1 Original line number Diff line number Diff line Loading @@ -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(); Loading
services/core/java/com/android/server/audio/SpatializerHelper.java +22 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -1502,18 +1513,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 Loading
services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java +11 −4 Original line number Diff line number Diff line Loading @@ -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) { } } Loading @@ -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); Loading