Merge "AudioService: reset volume ranges when requested by APM" into tm-dev am: 477f1a2821

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17842886

Change-Id: Iab8849cf91cf684dfb9726f46b5e1d93cbebc38b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Jean-Michel Trivi
2022-05-02 17:47:39 +00:00
committed by Automerger Merge Worker
4 changed files with 112 additions and 2 deletions

View File

@@ -180,6 +180,7 @@ static struct {
jmethodID postDynPolicyEventFromNative; jmethodID postDynPolicyEventFromNative;
jmethodID postRecordConfigEventFromNative; jmethodID postRecordConfigEventFromNative;
jmethodID postRoutingUpdatedFromNative; jmethodID postRoutingUpdatedFromNative;
jmethodID postVolRangeInitReqFromNative;
} gAudioPolicyEventHandlerMethods; } gAudioPolicyEventHandlerMethods;
jclass gListClass; jclass gListClass;
@@ -585,6 +586,20 @@ android_media_AudioSystem_routing_callback()
env->DeleteLocalRef(clazz); env->DeleteLocalRef(clazz);
} }
static void android_media_AudioSystem_vol_range_init_req_callback()
{
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (env == NULL) {
return;
}
// callback into java
jclass clazz = env->FindClass(kClassPathName);
env->CallStaticVoidMethod(clazz,
gAudioPolicyEventHandlerMethods.postVolRangeInitReqFromNative);
env->DeleteLocalRef(clazz);
}
static jint android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, static jint android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz,
jint state, jobject jParcel, jint state, jobject jParcel,
jint codec) { jint codec) {
@@ -2063,6 +2078,11 @@ android_media_AudioSystem_registerRoutingCallback(JNIEnv *env, jobject thiz)
AudioSystem::setRoutingCallback(android_media_AudioSystem_routing_callback); AudioSystem::setRoutingCallback(android_media_AudioSystem_routing_callback);
} }
static void android_media_AudioSystem_registerVolRangeInitReqCallback(JNIEnv *env, jobject thiz)
{
AudioSystem::setVolInitReqCallback(android_media_AudioSystem_vol_range_init_req_callback);
}
void javaAudioFormatToNativeAudioConfig(JNIEnv *env, audio_config_t *nConfig, void javaAudioFormatToNativeAudioConfig(JNIEnv *env, audio_config_t *nConfig,
const jobject jFormat, bool isInput) { const jobject jFormat, bool isInput) {
*nConfig = AUDIO_CONFIG_INITIALIZER; *nConfig = AUDIO_CONFIG_INITIALIZER;
@@ -2990,6 +3010,8 @@ static const JNINativeMethod gMethods[] =
(void *)android_media_AudioSystem_registerRecordingCallback}, (void *)android_media_AudioSystem_registerRecordingCallback},
{"native_register_routing_callback", "()V", {"native_register_routing_callback", "()V",
(void *)android_media_AudioSystem_registerRoutingCallback}, (void *)android_media_AudioSystem_registerRoutingCallback},
{"native_register_vol_range_init_req_callback", "()V",
(void *)android_media_AudioSystem_registerVolRangeInitReqCallback},
{"systemReady", "()I", (void *)android_media_AudioSystem_systemReady}, {"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
{"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB}, {"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
{"native_get_offload_support", "(IIIII)I", {"native_get_offload_support", "(IIIII)I",
@@ -3202,6 +3224,9 @@ int register_android_media_AudioSystem(JNIEnv *env)
gAudioPolicyEventHandlerMethods.postRoutingUpdatedFromNative = gAudioPolicyEventHandlerMethods.postRoutingUpdatedFromNative =
GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName), GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
"routingCallbackFromNative", "()V"); "routingCallbackFromNative", "()V");
gAudioPolicyEventHandlerMethods.postVolRangeInitReqFromNative =
GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
"volRangeInitReqCallbackFromNative", "()V");
jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix"); jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass); gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);

View File

@@ -828,6 +828,40 @@ public class AudioSystem
cb.onRoutingUpdated(); cb.onRoutingUpdated();
} }
/**
* @hide
* Handles requests from the audio policy manager to (re-)initialize the volume ranges
*/
public interface VolumeRangeInitRequestCallback {
/**
* Callback to notify volume ranges need to be initialized
*/
void onVolumeRangeInitializationRequested();
}
@GuardedBy("AudioSystem.class")
private static VolumeRangeInitRequestCallback sVolRangeInitReqCallback;
/** @hide */
public static void setVolumeRangeInitRequestCallback(VolumeRangeInitRequestCallback cb) {
synchronized (AudioSystem.class) {
sVolRangeInitReqCallback = cb;
native_register_vol_range_init_req_callback();
}
}
private static void volRangeInitReqCallbackFromNative() {
final VolumeRangeInitRequestCallback cb;
synchronized (AudioSystem.class) {
cb = sVolRangeInitReqCallback;
}
if (cb == null) {
Log.e(TAG, "APM requested volume range initialization, but no callback found");
return;
}
cb.onVolumeRangeInitializationRequested();
}
/* /*
* Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...) * Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...)
* Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h * Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h
@@ -1812,6 +1846,8 @@ public class AudioSystem
private static native final void native_register_recording_callback(); private static native final void native_register_recording_callback();
// declare this instance as having a routing update callback handler // declare this instance as having a routing update callback handler
private static native void native_register_routing_callback(); private static native void native_register_routing_callback();
// declare this instance as having a volume range init request handler
private static native void native_register_vol_range_init_req_callback();
// must be kept in sync with value in include/system/audio.h // must be kept in sync with value in include/system/audio.h
/** @hide */ public static final int AUDIO_HW_SYNC_INVALID = 0; /** @hide */ public static final int AUDIO_HW_SYNC_INVALID = 0;

View File

@@ -223,7 +223,8 @@ import java.util.stream.Collectors;
public class AudioService extends IAudioService.Stub public class AudioService extends IAudioService.Stub
implements AccessibilityManager.TouchExplorationStateChangeListener, implements AccessibilityManager.TouchExplorationStateChangeListener,
AccessibilityManager.AccessibilityServicesStateChangeListener, AccessibilityManager.AccessibilityServicesStateChangeListener,
AudioSystemAdapter.OnRoutingUpdatedListener { AudioSystemAdapter.OnRoutingUpdatedListener,
AudioSystemAdapter.OnVolRangeInitRequestListener {
private static final String TAG = "AS.AudioService"; private static final String TAG = "AS.AudioService";
@@ -1137,6 +1138,9 @@ public class AudioService extends IAudioService.Stub
// monitor routing updates coming from native // monitor routing updates coming from native
mAudioSystem.setRoutingListener(this); mAudioSystem.setRoutingListener(this);
// monitor requests for volume range initialization coming from native (typically when
// errors are found by AudioPolicyManager
mAudioSystem.setVolRangeInitReqListener(this);
// done with service initialization, continue additional work in our Handler thread // done with service initialization, continue additional work in our Handler thread
queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES, queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
@@ -1357,6 +1361,14 @@ public class AudioService extends IAudioService.Stub
checkMuteAwaitConnection(); checkMuteAwaitConnection();
} }
//-----------------------------------------------------------------
// monitoring requests for volume range initialization
@Override // AudioSystemAdapter.OnVolRangeInitRequestListener
public void onVolumeRangeInitRequestFromNative() {
sendMsg(mAudioHandler, MSG_REINIT_VOLUMES, SENDMSG_REPLACE, 0, 0,
"onVolumeRangeInitRequestFromNative" /*obj: caller, for dumpsys*/, /*delay*/ 0);
}
//----------------------------------------------------------------- //-----------------------------------------------------------------
RoleObserver mRoleObserver; RoleObserver mRoleObserver;

View File

@@ -40,7 +40,8 @@ import java.util.concurrent.ConcurrentHashMap;
* Use the "real" AudioSystem through the default adapter. * Use the "real" AudioSystem through the default adapter.
* Use the "always ok" adapter to avoid dealing with the APM behaviors during a test. * Use the "always ok" adapter to avoid dealing with the APM behaviors during a test.
*/ */
public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback { public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
AudioSystem.VolumeRangeInitRequestCallback {
private static final String TAG = "AudioSystemAdapter"; private static final String TAG = "AudioSystemAdapter";
@@ -65,6 +66,9 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
private static final Object sRoutingListenerLock = new Object(); private static final Object sRoutingListenerLock = new Object();
@GuardedBy("sRoutingListenerLock") @GuardedBy("sRoutingListenerLock")
private static @Nullable OnRoutingUpdatedListener sRoutingListener; private static @Nullable OnRoutingUpdatedListener sRoutingListener;
private static final Object sVolRangeInitReqListenerLock = new Object();
@GuardedBy("sVolRangeInitReqListenerLock")
private static @Nullable OnVolRangeInitRequestListener sVolRangeInitReqListener;
/** /**
* should be false except when trying to debug caching errors. When true, the value retrieved * should be false except when trying to debug caching errors. When true, the value retrieved
@@ -101,6 +105,30 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
} }
} }
/**
* Implementation of AudioSystem.VolumeRangeInitRequestCallback
*/
@Override
public void onVolumeRangeInitializationRequested() {
final OnVolRangeInitRequestListener listener;
synchronized (sVolRangeInitReqListenerLock) {
listener = sVolRangeInitReqListener;
}
if (listener != null) {
listener.onVolumeRangeInitRequestFromNative();
}
}
interface OnVolRangeInitRequestListener {
void onVolumeRangeInitRequestFromNative();
}
static void setVolRangeInitReqListener(@Nullable OnVolRangeInitRequestListener listener) {
synchronized (sVolRangeInitReqListenerLock) {
sVolRangeInitReqListener = listener;
}
}
/** /**
* Create a wrapper around the {@link AudioSystem} static methods, all functions are directly * Create a wrapper around the {@link AudioSystem} static methods, all functions are directly
* forwarded to the AudioSystem class. * forwarded to the AudioSystem class.
@@ -110,6 +138,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
if (sSingletonDefaultAdapter == null) { if (sSingletonDefaultAdapter == null) {
sSingletonDefaultAdapter = new AudioSystemAdapter(); sSingletonDefaultAdapter = new AudioSystemAdapter();
AudioSystem.setRoutingCallback(sSingletonDefaultAdapter); AudioSystem.setRoutingCallback(sSingletonDefaultAdapter);
AudioSystem.setVolumeRangeInitRequestCallback(sSingletonDefaultAdapter);
if (USE_CACHE_FOR_GETDEVICES) { if (USE_CACHE_FOR_GETDEVICES) {
sSingletonDefaultAdapter.mDevicesForAttrCache = sSingletonDefaultAdapter.mDevicesForAttrCache =
new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes()); new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes());
@@ -160,7 +189,15 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
synchronized (mDevicesForAttrCache) { synchronized (mDevicesForAttrCache) {
res = mDevicesForAttrCache.get(key); res = mDevicesForAttrCache.get(key);
if (res == null) { if (res == null) {
// result from AudioSystem guaranteed non-null, but could be invalid
// if there is a failure to talk to APM
res = AudioSystem.getDevicesForAttributes(attributes, forVolume); res = AudioSystem.getDevicesForAttributes(attributes, forVolume);
if (res.size() > 1 && res.get(0) != null
&& res.get(0).getInternalType() == AudioSystem.DEVICE_NONE) {
Log.e(TAG, "unable to get devices for " + attributes);
// return now, do not put invalid value in cache
return res;
}
mDevicesForAttrCache.put(key, res); mDevicesForAttrCache.put(key, res);
if (DEBUG_CACHE) { if (DEBUG_CACHE) {
Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES] Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES]