summaryrefslogtreecommitdiffstats
path: root/media/libmedia
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-04-22 18:32:39 -0700
committerSteve Kondik <steve@cyngn.com>2016-04-27 13:28:15 -0700
commit3f9eb321481de3e118632a594bf1b0c9001c281c (patch)
treea5a0f5a1771e780f32aa4212eeac20e68ba8857c /media/libmedia
parent244deea89aaf3c5dfa8bd369a845276ae501cb5a (diff)
downloadframeworks_av-3f9eb321481de3e118632a594bf1b0c9001c281c.zip
frameworks_av-3f9eb321481de3e118632a594bf1b0c9001c281c.tar.gz
frameworks_av-3f9eb321481de3e118632a594bf1b0c9001c281c.tar.bz2
audiopolicy: Add AudioSessionInfo API
* This patch introduces a new API which allows applications to query the state of the audio effects system, and receive callbacks with the necessary information to attach effects to any stream. * In the future, this may come as part of the AudioPort system, but since that's an active area of development by Google, we will dodge it for now. * The policy now simply keeps a refcounted list of objects which hold various bits of stream metadata. Callbacks are sent on stream open/close to applications which might be listening for them. Change-Id: I2d554d36e1378f4eb7b276010a3bfe8345c22ecd
Diffstat (limited to 'media/libmedia')
-rw-r--r--media/libmedia/AudioSystem.cpp39
-rw-r--r--media/libmedia/IAudioPolicyService.cpp42
-rw-r--r--media/libmedia/IAudioPolicyServiceClient.cpp30
3 files changed, 109 insertions, 2 deletions
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9d645f0..2e9fca9 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -37,7 +37,7 @@ sp<IAudioFlinger> AudioSystem::gAudioFlinger;
sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;
-
+audio_session_callback AudioSystem::gAudioSessionCallback = NULL;
// establish binder interface to AudioFlinger service
const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
@@ -652,6 +652,17 @@ status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
gDynPolicyCallback = cb;
}
+/*static*/ status_t AudioSystem::setAudioSessionCallback(audio_session_callback cb)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+
+ Mutex::Autolock _l(gLock);
+ gAudioSessionCallback = cb;
+
+ return NO_ERROR;
+}
+
// client singleton for AudioPolicyService binder interface
// protected by gLockAPS
sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;
@@ -1223,6 +1234,32 @@ void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(
}
}
+// ---------------------------------------------------------------------------
+
+status_t AudioSystem::listAudioSessions(audio_stream_type_t stream,
+ Vector< sp<AudioSessionInfo>> &sessions)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->listAudioSessions(stream, sessions);
+}
+
+void AudioSystem::AudioPolicyServiceClient::onOutputSessionEffectsUpdate(
+ sp<AudioSessionInfo>& info, bool added)
+{
+ ALOGV("AudioPolicyServiceClient::onOutputSessionEffectsUpdate(%d, %d, %d)",
+ info->mStream, info->mSessionId, added);
+ audio_session_callback cb = NULL;
+ {
+ Mutex::Autolock _l(AudioSystem::gLock);
+ cb = gAudioSessionCallback;
+ }
+
+ if (cb != NULL) {
+ cb(AUDIO_OUTPUT_SESSION_EFFECTS_UPDATE, info, added);
+ }
+}
+
void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
{
{
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 76b5924..abae614 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -74,6 +74,7 @@ enum {
START_AUDIO_SOURCE,
STOP_AUDIO_SOURCE,
SET_AUDIO_PORT_CALLBACK_ENABLED,
+ LIST_AUDIO_SESSIONS,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -767,6 +768,30 @@ public:
status = (status_t)reply.readInt32();
return status;
}
+
+ virtual status_t listAudioSessions(audio_stream_type_t streams,
+ Vector< sp<AudioSessionInfo>> &sessions)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(streams);
+ status_t status = remote()->transact(LIST_AUDIO_SESSIONS, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ size_t size = (size_t)reply.readUint32();
+ for (size_t i = 0; i < size && reply.dataAvail() > 0; i++) {
+ sp<AudioSessionInfo> info = new AudioSessionInfo();
+ info->readFromParcel(reply);
+ sessions.push_back(info);
+ }
+ }
+ return status;
+ }
+
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -1238,6 +1263,23 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
+ case LIST_AUDIO_SESSIONS: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ audio_stream_type_t streams = (audio_stream_type_t)data.readInt32();
+
+ Vector< sp<AudioSessionInfo>> sessions;
+ status_t status = listAudioSessions(streams, sessions);
+
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeUint32(static_cast<uint32_t>(sessions.size()));
+ for (size_t i = 0; i < sessions.size(); i++) {
+ sessions[i]->writeToParcel(reply);
+ }
+ }
+ return NO_ERROR;
+ }
+
case ACQUIRE_SOUNDTRIGGER_SESSION: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
diff --git a/media/libmedia/IAudioPolicyServiceClient.cpp b/media/libmedia/IAudioPolicyServiceClient.cpp
index 65cc7d6..a325996 100644
--- a/media/libmedia/IAudioPolicyServiceClient.cpp
+++ b/media/libmedia/IAudioPolicyServiceClient.cpp
@@ -30,7 +30,8 @@ namespace android {
enum {
PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
PATCH_LIST_UPDATE,
- MIX_STATE_UPDATE
+ MIX_STATE_UPDATE,
+ OUTPUT_SESSION_EFFECTS_UPDATE
};
class BpAudioPolicyServiceClient : public BpInterface<IAudioPolicyServiceClient>
@@ -63,6 +64,19 @@ public:
data.writeInt32(state);
remote()->transact(MIX_STATE_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+ void onOutputSessionEffectsUpdate(sp<AudioSessionInfo>& info, bool added)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
+ data.writeInt32(info->mStream);
+ data.writeInt32(info->mSessionId);
+ data.writeInt32(info->mFlags);
+ data.writeInt32(info->mChannelMask);
+ data.writeInt32(info->mUid);
+ data.writeInt32(added ? 1 : 0);
+ remote()->transact(OUTPUT_SESSION_EFFECTS_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
+ }
};
IMPLEMENT_META_INTERFACE(AudioPolicyServiceClient, "android.media.IAudioPolicyServiceClient");
@@ -90,6 +104,20 @@ status_t BnAudioPolicyServiceClient::onTransact(
onDynamicPolicyMixStateUpdate(regId, state);
return NO_ERROR;
}
+ case OUTPUT_SESSION_EFFECTS_UPDATE: {
+ CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
+ audio_stream_type_t stream = static_cast<audio_stream_type_t>(data.readInt32());
+ audio_session_t sessionId = static_cast<audio_session_t>(data.readInt32());
+ audio_output_flags_t flags = static_cast<audio_output_flags_t>(data.readInt32());
+ audio_channel_mask_t channelMask = static_cast<audio_channel_mask_t>(data.readInt32());
+ uid_t uid = static_cast<uid_t>(data.readInt32());
+ bool added = data.readInt32() > 0;
+
+ sp<AudioSessionInfo> info = new AudioSessionInfo(
+ sessionId, stream, flags, channelMask, uid);
+ onOutputSessionEffectsUpdate(info, added);
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}