From 0699fecd478d03d6ac904562a048992e92fda23c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Gaffie?= Date: Mon, 9 Jul 2018 14:35:10 +0200 Subject: [PATCH 1/2] AudioManager: add Audio Product Strategies introspection SystemAPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: 124767636 Test: dumpsys media.audio_policy Change-Id: I31b970d7439f76604079d4cffc67bc9373df08e1 Signed-off-by: François Gaffie --- api/system-current.txt | 1 + media/java/android/media/AudioManager.java | 25 +++++++++++++++++++ media/java/android/media/IAudioService.aidl | 3 +++ .../android/server/audio/AudioService.java | 14 +++++++++++ 4 files changed, 43 insertions(+) diff --git a/api/system-current.txt b/api/system-current.txt index 86a13bb13429f..c5b294ba0db2b 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); diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index bd828eea81792..3fb2365cb0065 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 571e67e1ccfcd..abdc3c9c834bb 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/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index afdfbe328ae29..a2d6508c509fc 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) { From f4f3bfe74779601c5e240892c847b785342d4901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Gaffie?= Date: Mon, 9 Jul 2018 16:49:12 +0200 Subject: [PATCH 2/2] Add API to retrieve Audio Product Strategy from a given Audio Attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to ensure only one matching algorithm is implemented in the audio policy engine, we cannot use the list of audio product strategy to let the client of this API inferring the product strategy to use. It shall request the audio policy manager which product strategy shall be followed by a given Audio Attributes. Bug: 124767636 Test: dumpsys media.audio_policy Change-Id: I372a47df4a35efd68a3ea327581af54823997dba Signed-off-by: François Gaffie --- api/system-current.txt | 1 + .../android_media_AudioProductStrategies.cpp | 22 +++++++++++++++++++ .../audiopolicy/AudioProductStrategies.java | 22 +++++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index c5b294ba0db2b..ec07a745a5d6d 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3648,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 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 a18e80a4e6e17..d7d31e59ad30f 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/audiopolicy/AudioProductStrategies.java b/media/java/android/media/audiopolicy/AudioProductStrategies.java index b8364091ff12a..6a2375fe153d4 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 strategies); + + private static native int native_get_product_strategies_from_audio_attributes( + AudioAttributes attributes); }