|
|
|
@ -18,8 +18,11 @@
|
|
|
|
|
//#define LOG_NDEBUG 0
|
|
|
|
|
|
|
|
|
|
#include <utils/Log.h>
|
|
|
|
|
#include <media/MediaAnalyticsItem.h>
|
|
|
|
|
|
|
|
|
|
#include "AudioPolicyService.h"
|
|
|
|
|
#include "ServiceUtilities.h"
|
|
|
|
|
#include "TypeConverter.h"
|
|
|
|
|
|
|
|
|
|
namespace android {
|
|
|
|
|
|
|
|
|
@ -409,6 +412,35 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// this is replicated from frameworks/av/media/libaudioclient/AudioRecord.cpp
|
|
|
|
|
// XXX -- figure out how to put it into a common, shared location
|
|
|
|
|
|
|
|
|
|
static std::string audioSourceString(audio_source_t value) {
|
|
|
|
|
std::string source;
|
|
|
|
|
if (SourceTypeConverter::toString(value, source)) {
|
|
|
|
|
return source;
|
|
|
|
|
}
|
|
|
|
|
char rawbuffer[16]; // room for "%d"
|
|
|
|
|
snprintf(rawbuffer, sizeof(rawbuffer), "%d", value);
|
|
|
|
|
return rawbuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static std::string audioConcurrencyString(AudioPolicyInterface::concurrency_type__mask_t concurrency)
|
|
|
|
|
{
|
|
|
|
|
char buffer[64]; // oversized
|
|
|
|
|
if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_ALL) {
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "%s%s%s%s",
|
|
|
|
|
(concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CALL)? ",call":"",
|
|
|
|
|
(concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE)? ",capture":"",
|
|
|
|
|
(concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_HOTWORD)? ",hotword":"",
|
|
|
|
|
(concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_PREEMPT)? ",preempt":"");
|
|
|
|
|
} else {
|
|
|
|
|
snprintf(buffer, sizeof(buffer), ",none");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &buffer[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenced)
|
|
|
|
|
{
|
|
|
|
|
if (mAudioPolicyManager == NULL) {
|
|
|
|
@ -444,6 +476,57 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenc
|
|
|
|
|
AutoCallerClear acc;
|
|
|
|
|
status = mAudioPolicyManager->startInput(
|
|
|
|
|
client->input, client->session, *silenced, &concurrency);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// XXX log them all for a while, during some dogfooding.
|
|
|
|
|
if (1 || status != NO_ERROR) {
|
|
|
|
|
|
|
|
|
|
static constexpr char kAudioPolicy[] = "audiopolicy";
|
|
|
|
|
|
|
|
|
|
static constexpr char kAudioPolicyReason[] = "android.media.audiopolicy.reason";
|
|
|
|
|
static constexpr char kAudioPolicyStatus[] = "android.media.audiopolicy.status";
|
|
|
|
|
static constexpr char kAudioPolicyRqstSrc[] = "android.media.audiopolicy.rqst.src";
|
|
|
|
|
static constexpr char kAudioPolicyRqstPkg[] = "android.media.audiopolicy.rqst.pkg";
|
|
|
|
|
static constexpr char kAudioPolicyRqstSession[] = "android.media.audiopolicy.rqst.session";
|
|
|
|
|
static constexpr char kAudioPolicyActiveSrc[] = "android.media.audiopolicy.active.src";
|
|
|
|
|
static constexpr char kAudioPolicyActivePkg[] = "android.media.audiopolicy.active.pkg";
|
|
|
|
|
static constexpr char kAudioPolicyActiveSession[] = "android.media.audiopolicy.active.session";
|
|
|
|
|
|
|
|
|
|
MediaAnalyticsItem *item = new MediaAnalyticsItem(kAudioPolicy);
|
|
|
|
|
if (item != NULL) {
|
|
|
|
|
|
|
|
|
|
item->setCString(kAudioPolicyReason, audioConcurrencyString(concurrency).c_str());
|
|
|
|
|
item->setInt32(kAudioPolicyStatus, status);
|
|
|
|
|
|
|
|
|
|
item->setCString(kAudioPolicyRqstSrc, audioSourceString(client->attributes.source).c_str());
|
|
|
|
|
item->setCString(kAudioPolicyRqstPkg, std::string(String8(client->opPackageName).string()).c_str());
|
|
|
|
|
item->setInt32(kAudioPolicyRqstSession, client->session);
|
|
|
|
|
|
|
|
|
|
// figure out who is active
|
|
|
|
|
// NB: might the other party have given up the microphone since then? how sure.
|
|
|
|
|
// perhaps could have given up on it.
|
|
|
|
|
// we hold mLock, so perhaps we're safe for this looping
|
|
|
|
|
if (concurrency != AudioPolicyInterface::API_INPUT_CONCURRENCY_NONE) {
|
|
|
|
|
int count = mAudioRecordClients.size();
|
|
|
|
|
for (int i = 0; i<count ; i++) {
|
|
|
|
|
if (portId == mAudioRecordClients.keyAt(i)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
sp<AudioRecordClient> other = mAudioRecordClients.valueAt(i);
|
|
|
|
|
if (other->active) {
|
|
|
|
|
// keeps the last of the clients marked active
|
|
|
|
|
item->setCString(kAudioPolicyActiveSrc,
|
|
|
|
|
audioSourceString(other->attributes.source).c_str());
|
|
|
|
|
item->setCString(kAudioPolicyActivePkg, std::string(String8(other->opPackageName).string()).c_str());
|
|
|
|
|
item->setInt32(kAudioPolicyActiveSession, other->session);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
item->selfrecord();
|
|
|
|
|
delete item;
|
|
|
|
|
item = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status == NO_ERROR) {
|
|
|
|
@ -457,6 +540,8 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenc
|
|
|
|
|
if (concurrency & AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE) {
|
|
|
|
|
//TODO: check concurrent capture permission
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client->active = true;
|
|
|
|
|
} else {
|
|
|
|
|
finishRecording(client->opPackageName, client->uid);
|
|
|
|
|
}
|
|
|
|
@ -477,6 +562,8 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId)
|
|
|
|
|
}
|
|
|
|
|
sp<AudioRecordClient> client = mAudioRecordClients.valueAt(index);
|
|
|
|
|
|
|
|
|
|
client->active = false;
|
|
|
|
|
|
|
|
|
|
// finish the recording app op
|
|
|
|
|
finishRecording(client->opPackageName, client->uid);
|
|
|
|
|
AutoCallerClear acc;
|
|
|
|
|