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 postRecordConfigEventFromNative;
jmethodID postRoutingUpdatedFromNative;
jmethodID postVolRangeInitReqFromNative;
} gAudioPolicyEventHandlerMethods;
jclass gListClass;
@@ -585,6 +586,20 @@ android_media_AudioSystem_routing_callback()
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,
jint state, jobject jParcel,
jint codec) {
@@ -2063,6 +2078,11 @@ android_media_AudioSystem_registerRoutingCallback(JNIEnv *env, jobject thiz)
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,
const jobject jFormat, bool isInput) {
*nConfig = AUDIO_CONFIG_INITIALIZER;
@@ -2990,6 +3010,8 @@ static const JNINativeMethod gMethods[] =
(void *)android_media_AudioSystem_registerRecordingCallback},
{"native_register_routing_callback", "()V",
(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},
{"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
{"native_get_offload_support", "(IIIII)I",
@@ -3202,6 +3224,9 @@ int register_android_media_AudioSystem(JNIEnv *env)
gAudioPolicyEventHandlerMethods.postRoutingUpdatedFromNative =
GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
"routingCallbackFromNative", "()V");
gAudioPolicyEventHandlerMethods.postVolRangeInitReqFromNative =
GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
"volRangeInitReqCallbackFromNative", "()V");
jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);

View File

@@ -828,6 +828,40 @@ public class AudioSystem
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 ...)
* 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();
// declare this instance as having a routing update callback handler
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
/** @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
implements AccessibilityManager.TouchExplorationStateChangeListener,
AccessibilityManager.AccessibilityServicesStateChangeListener,
AudioSystemAdapter.OnRoutingUpdatedListener {
AudioSystemAdapter.OnRoutingUpdatedListener,
AudioSystemAdapter.OnVolRangeInitRequestListener {
private static final String TAG = "AS.AudioService";
@@ -1137,6 +1138,9 @@ public class AudioService extends IAudioService.Stub
// monitor routing updates coming from native
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
queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
@@ -1357,6 +1361,14 @@ public class AudioService extends IAudioService.Stub
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;

View File

@@ -40,7 +40,8 @@ import java.util.concurrent.ConcurrentHashMap;
* Use the "real" AudioSystem through the default adapter.
* 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";
@@ -65,6 +66,9 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
private static final Object sRoutingListenerLock = new Object();
@GuardedBy("sRoutingListenerLock")
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
@@ -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
* forwarded to the AudioSystem class.
@@ -110,6 +138,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
if (sSingletonDefaultAdapter == null) {
sSingletonDefaultAdapter = new AudioSystemAdapter();
AudioSystem.setRoutingCallback(sSingletonDefaultAdapter);
AudioSystem.setVolumeRangeInitRequestCallback(sSingletonDefaultAdapter);
if (USE_CACHE_FOR_GETDEVICES) {
sSingletonDefaultAdapter.mDevicesForAttrCache =
new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes());
@@ -160,7 +189,15 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
synchronized (mDevicesForAttrCache) {
res = mDevicesForAttrCache.get(key);
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);
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);
if (DEBUG_CACHE) {
Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES]