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:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
Reference in New Issue
Block a user