diff options
| -rw-r--r-- | api/system-current.txt | 2 | ||||
| -rw-r--r-- | core/jni/android_media_AudioProductStrategies.cpp | 22 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 25 | ||||
| -rw-r--r-- | media/java/android/media/IAudioService.aidl | 3 | ||||
| -rw-r--r-- | media/java/android/media/audiopolicy/AudioProductStrategies.java | 22 | ||||
| -rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 14 |
6 files changed, 86 insertions, 2 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 86a13bb13429..ec07a745a5d6 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3455,6 +3455,7 @@ package android.media { method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes); method public void clearAudioServerStateCallback(); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public android.media.audiopolicy.AudioProductStrategies getAudioProductStrategies(); method public boolean isAudioServerRunning(); method public boolean isHdmiSystemAudioSupported(); method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy); @@ -3647,6 +3648,7 @@ package android.media.audiopolicy { method @NonNull public android.media.AudioAttributes getAudioAttributesForProductStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy); method @Nullable public android.media.audiopolicy.AudioProductStrategy getById(int); method public int getLegacyStreamTypeForAudioAttributes(@NonNull android.media.AudioAttributes); + method @Nullable public android.media.audiopolicy.AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull android.media.AudioAttributes); method public java.util.Iterator<android.media.audiopolicy.AudioProductStrategy> iterator(); method public int size(); method public void writeToParcel(@NonNull android.os.Parcel, int); diff --git a/core/jni/android_media_AudioProductStrategies.cpp b/core/jni/android_media_AudioProductStrategies.cpp index a18e80a4e6e1..d7d31e59ad30 100644 --- a/core/jni/android_media_AudioProductStrategies.cpp +++ b/core/jni/android_media_AudioProductStrategies.cpp @@ -194,12 +194,34 @@ exit: return jStatus; } +static jint +android_media_AudioSystem_getProductStrategyFromAudioAttributes(JNIEnv *env, jobject clazz, + jobject jAudioAttributes) +{ + JNIAudioAttributeHelper::UniqueAaPtr attributes = JNIAudioAttributeHelper::makeUnique(); + jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env, + jAudioAttributes, + attributes.get()); + if (jStatus != (jint)AUDIO_JAVA_SUCCESS) { + return jStatus; + } + product_strategy_t psId; + status_t status = AudioSystem::getProductStrategyFromAudioAttributes( + AudioAttributes(*attributes.get()), psId); + if (status != NO_ERROR) { + return nativeToJavaStatus(status); + } + return psId; +} + /* * JNI registration. */ static const JNINativeMethod gMethods[] = { {"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_listAudioProductStrategies}, + {"native_get_product_strategies_from_audio_attributes", "(Landroid/media/AudioAttributes;)I", + (void *)android_media_AudioSystem_getProductStrategyFromAudioAttributes}, }; int register_android_media_AudioProductStrategies(JNIEnv *env) diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index bd828eea8179..3fb2365cb006 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -36,6 +36,7 @@ import android.content.Context; import android.content.Intent; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener; +import android.media.audiopolicy.AudioProductStrategies; import android.media.projection.MediaProjection; import android.media.session.MediaController; import android.media.session.MediaSession; @@ -5221,6 +5222,30 @@ public class AudioManager { return AudioSystem.isHapticPlaybackSupported(); } + /** + * @hide + * Introspection API to retrieve audio product strategies. + * When implementing {Car|Oem}AudioManager, use this method to retrieve the collection of + * audio product strategies, which is indexed by a weakly typed index in order to be extended + * by OEM without any needs of AOSP patches. + * The {Car|Oem}AudioManager can expose API to build {@link AudioAttributes} for a given product + * strategy refered either by its index or human readable string. It will allow clients + * application to start streaming data using these {@link AudioAttributes} on the selected + * device by Audio Policy Engine. + * @return a (possibly zero-length) array of + * {@see android.media.audiopolicy.AudioProductStrategy} objects. + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) + public @NonNull AudioProductStrategies getAudioProductStrategies() { + final IAudioService service = getService(); + try { + return service.getAudioProductStrategies(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + //--------------------------------------------------------- // Inner classes diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 571e67e1ccfc..abdc3c9c834b 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -33,6 +33,7 @@ import android.media.IVolumeController; import android.media.PlayerBase; import android.media.VolumePolicy; import android.media.audiopolicy.AudioPolicyConfig; +import android.media.audiopolicy.AudioProductStrategies; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; @@ -82,6 +83,8 @@ interface IAudioService { int getLastAudibleStreamVolume(int streamType); + AudioProductStrategies getAudioProductStrategies(); + void setMicrophoneMute(boolean on, String callingPackage, int userId); void setRingerModeExternal(int ringerMode, String caller); diff --git a/media/java/android/media/audiopolicy/AudioProductStrategies.java b/media/java/android/media/audiopolicy/AudioProductStrategies.java index b8364091ff12..6a2375fe153d 100644 --- a/media/java/android/media/audiopolicy/AudioProductStrategies.java +++ b/media/java/android/media/audiopolicy/AudioProductStrategies.java @@ -144,8 +144,10 @@ public final class AudioProductStrategies implements Iterable<AudioProductStrate * @hide * @param aa the {@link AudioAttributes} for which stream type is requested * @return the legacy stream type relevant for the given {@link AudioAttributes}. - * If the product strategy is not associated to any stream, it returns STREAM_MUSIC. - * If no product strategy supports the stream type, it returns STREAM_MUSIC. + * If the product strategy is not associated to any stream, it returns + * {@link AudioSystem#STREAM_MUSIC}. + * If no product strategy supports the stream type, it returns + * {@link AudioSystem#STREAM_MUSIC}. */ @SystemApi public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) { @@ -165,6 +167,19 @@ public final class AudioProductStrategies implements Iterable<AudioProductStrate return AudioSystem.STREAM_MUSIC; } + /** + * @hide + * @param aa the {@link AudioAttributes} to be considered + * @return {@link AudioProductStrategy} supporting the given {@link AudioAttributes}. + * null is returned if no match with given attributes. + */ + @SystemApi + @Nullable + public AudioProductStrategy getProductStrategyForAudioAttributes(@NonNull AudioAttributes aa) { + Preconditions.checkNotNull(aa, "attributes must not be null"); + return getById(native_get_product_strategies_from_audio_attributes(aa)); + } + @Override public int describeContents() { return 0; @@ -198,4 +213,7 @@ public final class AudioProductStrategies implements Iterable<AudioProductStrate private static native int native_list_audio_product_strategies( ArrayList<AudioProductStrategy> strategies); + + private static native int native_get_product_strategies_from_audio_attributes( + AudioAttributes attributes); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index afdfbe328ae2..a2d6508c509f 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -88,6 +88,7 @@ import android.media.audiofx.AudioEffect; import android.media.audiopolicy.AudioMix; import android.media.audiopolicy.AudioPolicy; import android.media.audiopolicy.AudioPolicyConfig; +import android.media.audiopolicy.AudioProductStrategies; import android.media.audiopolicy.IAudioPolicyCallback; import android.media.projection.IMediaProjection; import android.media.projection.IMediaProjectionManager; @@ -274,6 +275,9 @@ public class AudioService extends IAudioService.Stub private SettingsObserver mSettingsObserver; + /** @see AudioProductStrategies */ + private static AudioProductStrategies sAudioProductStrategies; + private int mMode = AudioSystem.MODE_NORMAL; // protects mRingerMode private final Object mSettingsLock = new Object(); @@ -624,6 +628,8 @@ public class AudioService extends IAudioService.Stub mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator(); + sAudioProductStrategies = new AudioProductStrategies(); + // Initialize volume int maxCallVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", -1); if (maxCallVolume != -1) { @@ -988,6 +994,14 @@ public class AudioService extends IAudioService.Stub } } + /** + * @return the {@link android.media.audiopolicy.AudioProductStrategies} discovered from the + * platform configuration file. + */ + public @NonNull AudioProductStrategies getAudioProductStrategies() { + return sAudioProductStrategies; + } + private void checkAllAliasStreamVolumes() { synchronized (mSettingsLock) { synchronized (VolumeStreamState.class) { |