Merge "AudioService: reset volume ranges when requested by APM" into tm-dev am: 477f1a2821 am: bd0482e409
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17842886 Change-Id: I4931e5c42a2f469f7d7603c669e3736c9ba6fbc9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user