Loading core/api/current.txt +18 −0 Original line number Diff line number Diff line Loading @@ -20178,8 +20178,10 @@ package android.media { method public int getAllowedCapturePolicy(); method public int getContentType(); method public int getFlags(); method public int getSpatializationBehavior(); method public int getUsage(); method public int getVolumeControlStream(); method public boolean isContentSpatialized(); method public void writeToParcel(android.os.Parcel, int); field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1 field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3 Loading @@ -20193,6 +20195,8 @@ package android.media { field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1 field public static final int FLAG_HW_AV_SYNC = 16; // 0x10 field @Deprecated public static final int FLAG_LOW_LATENCY = 256; // 0x100 field public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0; // 0x0 field public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1; // 0x1 field public static final int USAGE_ALARM = 4; // 0x4 field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc Loading @@ -20219,7 +20223,9 @@ package android.media { method public android.media.AudioAttributes.Builder setContentType(int); method public android.media.AudioAttributes.Builder setFlags(int); method @NonNull public android.media.AudioAttributes.Builder setHapticChannelsMuted(boolean); method @NonNull public android.media.AudioAttributes.Builder setIsContentSpatialized(boolean); method public android.media.AudioAttributes.Builder setLegacyStreamType(int); method @NonNull public android.media.AudioAttributes.Builder setSpatializationBehavior(int); method public android.media.AudioAttributes.Builder setUsage(int); } Loading Loading @@ -20444,6 +20450,7 @@ package android.media { method public String getProperty(String); method public int getRingerMode(); method @Deprecated public int getRouting(int); method @Nullable public android.media.Spatializer getSpatializer(); method public int getStreamMaxVolume(int); method public int getStreamMinVolume(int); method public int getStreamVolume(int); Loading Loading @@ -23840,6 +23847,17 @@ package android.media { method public void onLoadComplete(android.media.SoundPool, int, int); } public class Spatializer { method public void addOnSpatializerEnabledChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerEnabledChangedListener); method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat); method public boolean isEnabled(); method public void removeOnSpatializerEnabledChangedListener(@NonNull android.media.Spatializer.OnSpatializerEnabledChangedListener); } public static interface Spatializer.OnSpatializerEnabledChangedListener { method public void onSpatializerEnabledChanged(boolean); } public final class SubtitleData { ctor public SubtitleData(int, long, long, @NonNull byte[]); method @NonNull public byte[] getData(); core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -5372,6 +5372,12 @@ package android.media { field public static final android.media.RouteDiscoveryPreference EMPTY; } public class Spatializer { method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getCompatibleAudioDevices(); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); } } package android.media.audiofx { media/java/android/media/AudioAttributes.java +98 −1 Original line number Diff line number Diff line Loading @@ -447,13 +447,26 @@ public final class AudioAttributes implements Parcelable { */ public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13; /** * @hide * Flag indicating the audio content has been processed to provide a virtual multichannel * audio experience */ public static final int FLAG_CONTENT_SPATIALIZED = 0x1 << 14; /** * @hide * Flag indicating the audio content is to never be spatialized */ public static final int FLAG_NEVER_SPATIALIZE = 0x1 << 15; // Note that even though FLAG_MUTE_HAPTIC is stored as a flag bit, it is not here since // it is known as a boolean value outside of AudioAttributes. private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO | FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE; | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE | FLAG_CONTENT_SPATIALIZED | FLAG_NEVER_SPATIALIZE; private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY; /* mask of flags that can be set by SDK and System APIs through the Builder */ Loading Loading @@ -614,6 +627,49 @@ public final class AudioAttributes implements Parcelable { return (mFlags & FLAG_MUTE_HAPTIC) != 0; } /** * Return true if the audio content associated with these attributes has already been * spatialized, that is it has already been processed to offer a binaural or transaural * immersive audio experience. * @return {@code true} if the content has been processed */ public boolean isContentSpatialized() { return (mFlags & FLAG_CONTENT_SPATIALIZED) != 0; } /** @hide */ @IntDef(flag = false, value = { SPATIALIZATION_BEHAVIOR_AUTO, SPATIALIZATION_BEHAVIOR_NEVER, }) @Retention(RetentionPolicy.SOURCE) public @interface SpatializationBehavior {}; /** * Constant indicating the audio content associated with these attributes will follow the * default platform behavior with regards to which content will be spatialized or not. * @see #getSpatializationBehavior() * @see Spatializer */ public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0; /** * Constant indicating the audio content associated with these attributes should never * be virtualized. * @see #getSpatializationBehavior() * @see Spatializer */ public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1; /** * Return the behavior affecting whether spatialization will be used. * @return the spatialization behavior */ public @SpatializationBehavior int getSpatializationBehavior() { return ((mFlags & FLAG_NEVER_SPATIALIZE) != 0) ? SPATIALIZATION_BEHAVIOR_NEVER : SPATIALIZATION_BEHAVIOR_AUTO; } /** * Return the capture policy. * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or Loading Loading @@ -657,6 +713,8 @@ public final class AudioAttributes implements Parcelable { private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID; private int mFlags = 0x0; private boolean mMuteHapticChannels = true; private boolean mIsContentSpatialized = false; private int mSpatializationBehavior = SPATIALIZATION_BEHAVIOR_AUTO; private HashSet<String> mTags = new HashSet<String>(); private Bundle mBundle; private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT; Loading Loading @@ -687,6 +745,8 @@ public final class AudioAttributes implements Parcelable { mFlags = aa.getAllFlags(); mTags = (HashSet<String>) aa.mTags.clone(); mMuteHapticChannels = aa.areHapticChannelsMuted(); mIsContentSpatialized = aa.isContentSpatialized(); mSpatializationBehavior = aa.getSpatializationBehavior(); } /** Loading Loading @@ -719,6 +779,12 @@ public final class AudioAttributes implements Parcelable { if (mMuteHapticChannels) { aa.mFlags |= FLAG_MUTE_HAPTIC; } if (mIsContentSpatialized) { aa.mFlags |= FLAG_CONTENT_SPATIALIZED; } if (mSpatializationBehavior == SPATIALIZATION_BEHAVIOR_NEVER) { aa.mFlags |= FLAG_NEVER_SPATIALIZE; } if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) { // capturing for camcorder or communication is private by default to Loading Loading @@ -905,6 +971,35 @@ public final class AudioAttributes implements Parcelable { return this; } /** * Specifies whether the content has already been processed for spatialization. * If it has, setting this to true will prevent issues such as double-processing. * @param isSpatialized * @return the same Builder instance */ public @NonNull Builder setIsContentSpatialized(boolean isSpatialized) { mIsContentSpatialized = isSpatialized; return this; } /** * Sets the behavior affecting whether spatialization will be used. * @param sb the spatialization behavior * @return the same Builder instance * */ public @NonNull Builder setSpatializationBehavior(@SpatializationBehavior int sb) { switch (sb) { case SPATIALIZATION_BEHAVIOR_NEVER: case SPATIALIZATION_BEHAVIOR_AUTO: break; default: throw new IllegalArgumentException("Invalid spatialization behavior " + sb); } mSpatializationBehavior = sb; return this; } /** * @hide * Replaces flags. Loading Loading @@ -990,6 +1085,8 @@ public final class AudioAttributes implements Parcelable { mContentType = attributes.mContentType; mFlags = attributes.getAllFlags(); mMuteHapticChannels = attributes.areHapticChannelsMuted(); mIsContentSpatialized = attributes.isContentSpatialized(); mSpatializationBehavior = attributes.getSpatializationBehavior(); mTags = attributes.mTags; mBundle = attributes.mBundle; mSource = attributes.mSource; Loading media/java/android/media/AudioManager.java +144 −1 Original line number Diff line number Diff line Loading @@ -805,7 +805,7 @@ public class AudioManager { } @UnsupportedAppUsage private static IAudioService getService() static IAudioService getService() { if (sService != null) { return sService; Loading Loading @@ -2438,6 +2438,149 @@ public class AudioManager { return AudioSystem.getOffloadSupport(format, attributes); } //==================================================================== // Immersive audio /** * @hide * Returns the level of support for immersive audio from the {@link Spatializer} if * available. * @return the level of immersive audio support through spatialization * @see Spatializer#getImmersiveAudioLevel() */ @Spatializer.ImmersiveAudioLevel int getSpatializerImmersiveAudioLevel() { final IAudioService service = getService(); try { return service.getSpatializerImmersiveAudioLevel(); } catch (RemoteException e) { return Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; } } /** * Return a handle to the optional platform's {@link Spatializer} * @return {@code null} if spatialization is not supported, the {@code Spatializer} instance * otherwise. */ public @Nullable Spatializer getSpatializer() { if (getSpatializerImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) { return null; } return new Spatializer(this); } /** * @hide * @see Spatializer#isEnabled() * @return {@code true} if spatialization is enabled */ boolean isSpatializerEnabled() { final IAudioService service = getService(); try { return service.isSpatializerEnabled(); } catch (RemoteException e) { Log.e(TAG, "Error querying isSpatializerEnabled, returning false", e); return false; } } /** * @hide * @see Spatializer#setEnabled(boolean) * Enable/disable the spatialization wherever supported. * @param enabled {@code true} to enable */ void setSpatializerFeatureEnabled(boolean enabled) { final IAudioService service = getService(); try { service.setSpatializerFeatureEnabled(enabled); } catch (RemoteException e) { Log.e(TAG, "Error calling setSpatializerFeatureEnabled", e); } } /** * @hide * @see Spatializer#setEnabledForDevice(boolean, AudioDeviceAttributes) * @see Spatializer#setEnabled(boolean) * @param enabled enable/disable for a specific device. * @param device the device concerned with spatializer functionality. */ void setSpatializerEnabledForDevice(boolean enabled, @NonNull AudioDeviceAttributes device) { final IAudioService service = getService(); try { service.setSpatializerEnabledForDevice(enabled, device); } catch (RemoteException e) { Log.e(TAG, "Error calling setSpatializerEnabledForDevice", e); } } /** * @hide * @see Spatializer#canBeSpatialized(AudioAttributes, AudioFormat) * @param attributes the {@code AudioAttributes} of the content as used for playback * @param format the {@code AudioFormat} of the content as used for playback * @return true if the device is capable of spatializing the combination of audio * format and attributes. */ boolean canBeSpatialized( @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { final IAudioService service = getService(); try { return service.canBeSpatialized(attributes, format); } catch (RemoteException e) { Log.e(TAG, "Error querying canBeSpatialized for attr:" + attributes + " format:" + format + " returning false", e); return false; } } /** * @hide * @see Spatializer#getCompatibleAudioDevices() * @return a non-null list of the spatialization-compatible audio devices */ @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { final IAudioService service = getService(); try { return service.getSpatializerCompatibleAudioDevices(); } catch (RemoteException e) { Log.e(TAG, "Error querying getSpatializerCompatibleAudioDevices(), " + " returning empty list", e); return new ArrayList<AudioDeviceAttributes>(0); } } /** * @hide * @see Spatializer#addCompatibleAudioDevice(AudioDeviceAttributes) * @param ada the audio device compatible with spatialization */ void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { final IAudioService service = getService(); try { service.addSpatializerCompatibleAudioDevice(ada); } catch (RemoteException e) { Log.e(TAG, "Error calling addSpatializerCompatibleAudioDevice()", e); } } /** * @hide * @see Spatializer#removeCompatibleAudioDevice(AudioDeviceAttributes) * @param ada the audio device incompatible with spatialization */ void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { final IAudioService service = getService(); try { service.removeSpatializerCompatibleAudioDevice(ada); } catch (RemoteException e) { Log.e(TAG, "Error calling removeSpatializerCompatibleAudioDevice()", e); } } //==================================================================== // Bluetooth SCO control /** Loading media/java/android/media/IAudioService.aidl +22 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; import android.media.AudioFormat; import android.media.AudioFocusInfo; import android.media.AudioPlaybackConfiguration; import android.media.AudioRecordingConfiguration; Loading @@ -34,6 +35,7 @@ import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; Loading Loading @@ -392,4 +394,24 @@ interface IAudioService { void registerModeDispatcher(IAudioModeDispatcher dispatcher); oneway void unregisterModeDispatcher(IAudioModeDispatcher dispatcher); int getSpatializerImmersiveAudioLevel(); boolean isSpatializerEnabled(); void setSpatializerFeatureEnabled(boolean enabled); void setSpatializerEnabledForDevice(boolean enabled, in AudioDeviceAttributes device); boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af); void registerSpatializerCallback(in ISpatializerCallback callback); void unregisterSpatializerCallback(in ISpatializerCallback callback); List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices(); void addSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada); void removeSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada); } Loading
core/api/current.txt +18 −0 Original line number Diff line number Diff line Loading @@ -20178,8 +20178,10 @@ package android.media { method public int getAllowedCapturePolicy(); method public int getContentType(); method public int getFlags(); method public int getSpatializationBehavior(); method public int getUsage(); method public int getVolumeControlStream(); method public boolean isContentSpatialized(); method public void writeToParcel(android.os.Parcel, int); field public static final int ALLOW_CAPTURE_BY_ALL = 1; // 0x1 field public static final int ALLOW_CAPTURE_BY_NONE = 3; // 0x3 Loading @@ -20193,6 +20195,8 @@ package android.media { field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1 field public static final int FLAG_HW_AV_SYNC = 16; // 0x10 field @Deprecated public static final int FLAG_LOW_LATENCY = 256; // 0x100 field public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0; // 0x0 field public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1; // 0x1 field public static final int USAGE_ALARM = 4; // 0x4 field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc Loading @@ -20219,7 +20223,9 @@ package android.media { method public android.media.AudioAttributes.Builder setContentType(int); method public android.media.AudioAttributes.Builder setFlags(int); method @NonNull public android.media.AudioAttributes.Builder setHapticChannelsMuted(boolean); method @NonNull public android.media.AudioAttributes.Builder setIsContentSpatialized(boolean); method public android.media.AudioAttributes.Builder setLegacyStreamType(int); method @NonNull public android.media.AudioAttributes.Builder setSpatializationBehavior(int); method public android.media.AudioAttributes.Builder setUsage(int); } Loading Loading @@ -20444,6 +20450,7 @@ package android.media { method public String getProperty(String); method public int getRingerMode(); method @Deprecated public int getRouting(int); method @Nullable public android.media.Spatializer getSpatializer(); method public int getStreamMaxVolume(int); method public int getStreamMinVolume(int); method public int getStreamVolume(int); Loading Loading @@ -23840,6 +23847,17 @@ package android.media { method public void onLoadComplete(android.media.SoundPool, int, int); } public class Spatializer { method public void addOnSpatializerEnabledChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerEnabledChangedListener); method public boolean canBeSpatialized(@NonNull android.media.AudioAttributes, @NonNull android.media.AudioFormat); method public boolean isEnabled(); method public void removeOnSpatializerEnabledChangedListener(@NonNull android.media.Spatializer.OnSpatializerEnabledChangedListener); } public static interface Spatializer.OnSpatializerEnabledChangedListener { method public void onSpatializerEnabledChanged(boolean); } public final class SubtitleData { ctor public SubtitleData(int, long, long, @NonNull byte[]); method @NonNull public byte[] getData();
core/api/system-current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -5372,6 +5372,12 @@ package android.media { field public static final android.media.RouteDiscoveryPreference EMPTY; } public class Spatializer { method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<android.media.AudioDeviceAttributes> getCompatibleAudioDevices(); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes); } } package android.media.audiofx {
media/java/android/media/AudioAttributes.java +98 −1 Original line number Diff line number Diff line Loading @@ -447,13 +447,26 @@ public final class AudioAttributes implements Parcelable { */ public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13; /** * @hide * Flag indicating the audio content has been processed to provide a virtual multichannel * audio experience */ public static final int FLAG_CONTENT_SPATIALIZED = 0x1 << 14; /** * @hide * Flag indicating the audio content is to never be spatialized */ public static final int FLAG_NEVER_SPATIALIZE = 0x1 << 15; // Note that even though FLAG_MUTE_HAPTIC is stored as a flag bit, it is not here since // it is known as a boolean value outside of AudioAttributes. private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO | FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY | FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE; | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE | FLAG_CONTENT_SPATIALIZED | FLAG_NEVER_SPATIALIZE; private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY; /* mask of flags that can be set by SDK and System APIs through the Builder */ Loading Loading @@ -614,6 +627,49 @@ public final class AudioAttributes implements Parcelable { return (mFlags & FLAG_MUTE_HAPTIC) != 0; } /** * Return true if the audio content associated with these attributes has already been * spatialized, that is it has already been processed to offer a binaural or transaural * immersive audio experience. * @return {@code true} if the content has been processed */ public boolean isContentSpatialized() { return (mFlags & FLAG_CONTENT_SPATIALIZED) != 0; } /** @hide */ @IntDef(flag = false, value = { SPATIALIZATION_BEHAVIOR_AUTO, SPATIALIZATION_BEHAVIOR_NEVER, }) @Retention(RetentionPolicy.SOURCE) public @interface SpatializationBehavior {}; /** * Constant indicating the audio content associated with these attributes will follow the * default platform behavior with regards to which content will be spatialized or not. * @see #getSpatializationBehavior() * @see Spatializer */ public static final int SPATIALIZATION_BEHAVIOR_AUTO = 0; /** * Constant indicating the audio content associated with these attributes should never * be virtualized. * @see #getSpatializationBehavior() * @see Spatializer */ public static final int SPATIALIZATION_BEHAVIOR_NEVER = 1; /** * Return the behavior affecting whether spatialization will be used. * @return the spatialization behavior */ public @SpatializationBehavior int getSpatializationBehavior() { return ((mFlags & FLAG_NEVER_SPATIALIZE) != 0) ? SPATIALIZATION_BEHAVIOR_NEVER : SPATIALIZATION_BEHAVIOR_AUTO; } /** * Return the capture policy. * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or Loading Loading @@ -657,6 +713,8 @@ public final class AudioAttributes implements Parcelable { private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID; private int mFlags = 0x0; private boolean mMuteHapticChannels = true; private boolean mIsContentSpatialized = false; private int mSpatializationBehavior = SPATIALIZATION_BEHAVIOR_AUTO; private HashSet<String> mTags = new HashSet<String>(); private Bundle mBundle; private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT; Loading Loading @@ -687,6 +745,8 @@ public final class AudioAttributes implements Parcelable { mFlags = aa.getAllFlags(); mTags = (HashSet<String>) aa.mTags.clone(); mMuteHapticChannels = aa.areHapticChannelsMuted(); mIsContentSpatialized = aa.isContentSpatialized(); mSpatializationBehavior = aa.getSpatializationBehavior(); } /** Loading Loading @@ -719,6 +779,12 @@ public final class AudioAttributes implements Parcelable { if (mMuteHapticChannels) { aa.mFlags |= FLAG_MUTE_HAPTIC; } if (mIsContentSpatialized) { aa.mFlags |= FLAG_CONTENT_SPATIALIZED; } if (mSpatializationBehavior == SPATIALIZATION_BEHAVIOR_NEVER) { aa.mFlags |= FLAG_NEVER_SPATIALIZE; } if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) { // capturing for camcorder or communication is private by default to Loading Loading @@ -905,6 +971,35 @@ public final class AudioAttributes implements Parcelable { return this; } /** * Specifies whether the content has already been processed for spatialization. * If it has, setting this to true will prevent issues such as double-processing. * @param isSpatialized * @return the same Builder instance */ public @NonNull Builder setIsContentSpatialized(boolean isSpatialized) { mIsContentSpatialized = isSpatialized; return this; } /** * Sets the behavior affecting whether spatialization will be used. * @param sb the spatialization behavior * @return the same Builder instance * */ public @NonNull Builder setSpatializationBehavior(@SpatializationBehavior int sb) { switch (sb) { case SPATIALIZATION_BEHAVIOR_NEVER: case SPATIALIZATION_BEHAVIOR_AUTO: break; default: throw new IllegalArgumentException("Invalid spatialization behavior " + sb); } mSpatializationBehavior = sb; return this; } /** * @hide * Replaces flags. Loading Loading @@ -990,6 +1085,8 @@ public final class AudioAttributes implements Parcelable { mContentType = attributes.mContentType; mFlags = attributes.getAllFlags(); mMuteHapticChannels = attributes.areHapticChannelsMuted(); mIsContentSpatialized = attributes.isContentSpatialized(); mSpatializationBehavior = attributes.getSpatializationBehavior(); mTags = attributes.mTags; mBundle = attributes.mBundle; mSource = attributes.mSource; Loading
media/java/android/media/AudioManager.java +144 −1 Original line number Diff line number Diff line Loading @@ -805,7 +805,7 @@ public class AudioManager { } @UnsupportedAppUsage private static IAudioService getService() static IAudioService getService() { if (sService != null) { return sService; Loading Loading @@ -2438,6 +2438,149 @@ public class AudioManager { return AudioSystem.getOffloadSupport(format, attributes); } //==================================================================== // Immersive audio /** * @hide * Returns the level of support for immersive audio from the {@link Spatializer} if * available. * @return the level of immersive audio support through spatialization * @see Spatializer#getImmersiveAudioLevel() */ @Spatializer.ImmersiveAudioLevel int getSpatializerImmersiveAudioLevel() { final IAudioService service = getService(); try { return service.getSpatializerImmersiveAudioLevel(); } catch (RemoteException e) { return Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE; } } /** * Return a handle to the optional platform's {@link Spatializer} * @return {@code null} if spatialization is not supported, the {@code Spatializer} instance * otherwise. */ public @Nullable Spatializer getSpatializer() { if (getSpatializerImmersiveAudioLevel() == Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE) { return null; } return new Spatializer(this); } /** * @hide * @see Spatializer#isEnabled() * @return {@code true} if spatialization is enabled */ boolean isSpatializerEnabled() { final IAudioService service = getService(); try { return service.isSpatializerEnabled(); } catch (RemoteException e) { Log.e(TAG, "Error querying isSpatializerEnabled, returning false", e); return false; } } /** * @hide * @see Spatializer#setEnabled(boolean) * Enable/disable the spatialization wherever supported. * @param enabled {@code true} to enable */ void setSpatializerFeatureEnabled(boolean enabled) { final IAudioService service = getService(); try { service.setSpatializerFeatureEnabled(enabled); } catch (RemoteException e) { Log.e(TAG, "Error calling setSpatializerFeatureEnabled", e); } } /** * @hide * @see Spatializer#setEnabledForDevice(boolean, AudioDeviceAttributes) * @see Spatializer#setEnabled(boolean) * @param enabled enable/disable for a specific device. * @param device the device concerned with spatializer functionality. */ void setSpatializerEnabledForDevice(boolean enabled, @NonNull AudioDeviceAttributes device) { final IAudioService service = getService(); try { service.setSpatializerEnabledForDevice(enabled, device); } catch (RemoteException e) { Log.e(TAG, "Error calling setSpatializerEnabledForDevice", e); } } /** * @hide * @see Spatializer#canBeSpatialized(AudioAttributes, AudioFormat) * @param attributes the {@code AudioAttributes} of the content as used for playback * @param format the {@code AudioFormat} of the content as used for playback * @return true if the device is capable of spatializing the combination of audio * format and attributes. */ boolean canBeSpatialized( @NonNull AudioAttributes attributes, @NonNull AudioFormat format) { final IAudioService service = getService(); try { return service.canBeSpatialized(attributes, format); } catch (RemoteException e) { Log.e(TAG, "Error querying canBeSpatialized for attr:" + attributes + " format:" + format + " returning false", e); return false; } } /** * @hide * @see Spatializer#getCompatibleAudioDevices() * @return a non-null list of the spatialization-compatible audio devices */ @NonNull List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices() { final IAudioService service = getService(); try { return service.getSpatializerCompatibleAudioDevices(); } catch (RemoteException e) { Log.e(TAG, "Error querying getSpatializerCompatibleAudioDevices(), " + " returning empty list", e); return new ArrayList<AudioDeviceAttributes>(0); } } /** * @hide * @see Spatializer#addCompatibleAudioDevice(AudioDeviceAttributes) * @param ada the audio device compatible with spatialization */ void addSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { final IAudioService service = getService(); try { service.addSpatializerCompatibleAudioDevice(ada); } catch (RemoteException e) { Log.e(TAG, "Error calling addSpatializerCompatibleAudioDevice()", e); } } /** * @hide * @see Spatializer#removeCompatibleAudioDevice(AudioDeviceAttributes) * @param ada the audio device incompatible with spatialization */ void removeSpatializerCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) { final IAudioService service = getService(); try { service.removeSpatializerCompatibleAudioDevice(ada); } catch (RemoteException e) { Log.e(TAG, "Error calling removeSpatializerCompatibleAudioDevice()", e); } } //==================================================================== // Bluetooth SCO control /** Loading
media/java/android/media/IAudioService.aidl +22 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; import android.media.AudioFormat; import android.media.AudioFocusInfo; import android.media.AudioPlaybackConfiguration; import android.media.AudioRecordingConfiguration; Loading @@ -34,6 +35,7 @@ import android.media.IPlaybackConfigDispatcher; import android.media.IRecordingConfigDispatcher; import android.media.IRingtonePlayer; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.ISpatializerCallback; import android.media.IVolumeController; import android.media.IVolumeController; import android.media.PlayerBase; Loading Loading @@ -392,4 +394,24 @@ interface IAudioService { void registerModeDispatcher(IAudioModeDispatcher dispatcher); oneway void unregisterModeDispatcher(IAudioModeDispatcher dispatcher); int getSpatializerImmersiveAudioLevel(); boolean isSpatializerEnabled(); void setSpatializerFeatureEnabled(boolean enabled); void setSpatializerEnabledForDevice(boolean enabled, in AudioDeviceAttributes device); boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af); void registerSpatializerCallback(in ISpatializerCallback callback); void unregisterSpatializerCallback(in ISpatializerCallback callback); List<AudioDeviceAttributes> getSpatializerCompatibleAudioDevices(); void addSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada); void removeSpatializerCompatibleAudioDevice(in AudioDeviceAttributes ada); }