Merge "AudioPolicy/AudioFlinger: Track AudioRecords via Record IDs" into qt-dev

gugelfrei
TreeHugger Robot 5 years ago committed by Android (Google) Code Review
commit 66ea392903

@ -59,6 +59,7 @@ cc_library_shared {
"IEffectClient.cpp",
"ToneGenerator.cpp",
"PlayerBase.cpp",
"RecordingActivityTracker.cpp",
"TrackPlayerBase.cpp",
],
shared_libs: [

@ -22,7 +22,11 @@
#include <android-base/macros.h>
#include <sys/resource.h>
#include <audiomanager/AudioManager.h>
#include <audiomanager/IAudioManager.h>
#include <binder/Binder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <media/AudioRecord.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
@ -219,6 +223,8 @@ status_t AudioRecord::set(
inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
mTracker.reset(new RecordingActivityTracker());
mSelectedDeviceId = selectedDeviceId;
mSelectedMicDirection = selectedMicDirection;
mSelectedMicFieldDimension = microphoneFieldDimension;
@ -396,6 +402,7 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
// This is legacy behavior. This is not done in stop() to avoid a race condition
// where the last marker event is issued twice.
mMarkerReached = false;
// mActive is checked by restoreRecord_l
mActive = true;
status_t status = NO_ERROR;
@ -416,7 +423,9 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
if (status != NO_ERROR) {
mActive = false;
ALOGE("%s(%d): status %d", __func__, mPortId, status);
mMediaMetrics.markError(status, __FUNCTION__);
} else {
mTracker->recordingStarted();
sp<AudioRecordThread> t = mAudioRecordThread;
if (t != 0) {
t->resume();
@ -429,10 +438,6 @@ status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t tri
// we've successfully started, log that time
mMediaMetrics.logStart(systemTime());
}
if (status != NO_ERROR) {
mMediaMetrics.markError(status, __FUNCTION__);
}
return status;
}
@ -447,6 +452,7 @@ void AudioRecord::stop()
mActive = false;
mProxy->interrupt();
mAudioRecord->stop();
mTracker->recordingStopped();
// Note: legacy handling - stop does not clear record marker and
// periodic update position; we update those on start().
@ -711,6 +717,7 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
}
}
input.opPackageName = opPackageName;
input.riid = mTracker->getRiid();
input.flags = mFlags;
// The notification frame count is the period between callbacks, as suggested by the client

@ -428,6 +428,7 @@ uint32_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle)
audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use)
{
// Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
return af->newAudioUniqueId(use);
@ -924,6 +925,7 @@ void AudioSystem::releaseOutput(audio_port_handle_t portId)
status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,
@ -936,7 +938,7 @@ status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return NO_INIT;
return aps->getInputForAttr(
attr, input, session, pid, uid, opPackageName,
attr, input, riid, session, pid, uid, opPackageName,
config, flags, selectedDeviceId, portId);
}

@ -305,6 +305,7 @@ public:
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,
@ -334,6 +335,7 @@ public:
}
data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(*input);
data.writeInt32(riid);
data.writeInt32(session);
data.writeInt32(pid);
data.writeInt32(uid);
@ -1511,6 +1513,7 @@ status_t BnAudioPolicyService::onTransact(
data.read(&attr, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attr);
audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
audio_unique_id_t riid = (audio_unique_id_t)data.readInt32();
audio_session_t session = (audio_session_t)data.readInt32();
pid_t pid = (pid_t)data.readInt32();
uid_t uid = (uid_t)data.readInt32();
@ -1521,7 +1524,7 @@ status_t BnAudioPolicyService::onTransact(
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
status_t status = getInputForAttr(&attr, &input, session, pid, uid,
status_t status = getInputForAttr(&attr, &input, riid, session, pid, uid,
opPackageName, &config,
flags, &selectedDeviceId, &portId);
reply->writeInt32(status);

@ -50,6 +50,7 @@ inline void writeAudioConfigBaseToParcel(Parcel& data, const audio_config_base_t
}
inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
clientInfo->riid = (audio_unique_id_t) data.readInt32();
clientInfo->uid = (uid_t) data.readUint32();
clientInfo->session = (audio_session_t) data.readInt32();
clientInfo->source = (audio_source_t) data.readInt32();
@ -58,6 +59,7 @@ inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_inf
}
inline void writeRecordClientInfoToParcel(Parcel& data, const record_client_info_t *clientInfo) {
data.writeInt32((int32_t) clientInfo->riid);
data.writeUint32((uint32_t) clientInfo->uid);
data.writeInt32((int32_t) clientInfo->session);
data.writeInt32((int32_t) clientInfo->source);

@ -0,0 +1,63 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <audiomanager/AudioManager.h>
#include <audiomanager/IAudioManager.h>
#include <binder/Binder.h>
#include <binder/IServiceManager.h>
#include <media/RecordingActivityTracker.h>
namespace android {
RecordingActivityTracker::RecordingActivityTracker()
: mRIId(RECORD_RIID_INVALID), mToken(new BBinder())
{
// use checkService() to avoid blocking if audio service is not up yet
sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
if (binder != 0) {
mAudioManager = interface_cast<IAudioManager>(binder);
} else {
ALOGE("RecordingActivityTracker(): binding to audio service failed, service up?");
}
}
RecordingActivityTracker::~RecordingActivityTracker()
{
}
audio_unique_id_t RecordingActivityTracker::getRiid()
{
if (mRIId == RECORD_RIID_INVALID && mAudioManager) {
mRIId = mAudioManager->trackRecorder(mToken);
}
return mRIId;
}
void RecordingActivityTracker::recordingStarted()
{
if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STARTED);
}
}
void RecordingActivityTracker::recordingStopped()
{
if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STOPPED);
}
}
} // namespace android

@ -119,11 +119,11 @@ public:
};
// definitions for audio recording configuration updates
// which update type is reported
#define RECORD_CONFIG_EVENT_NONE -1
#define RECORD_CONFIG_EVENT_START 1
#define RECORD_CONFIG_EVENT_STOP 0
// definitions for audio recording configuration updates;
// keep in sync with AudioManager.java for values used from native code
#define RECORD_CONFIG_EVENT_START 0
#define RECORD_CONFIG_EVENT_STOP 1
#define RECORD_CONFIG_EVENT_UPDATE 2
static inline bool is_mix_loopback_render(uint32_t routeFlags) {
return (routeFlags & MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER)

@ -17,6 +17,9 @@
#ifndef ANDROID_AUDIORECORD_H
#define ANDROID_AUDIORECORD_H
#include <memory>
#include <vector>
#include <binder/IMemory.h>
#include <cutils/sched_policy.h>
#include <media/AudioSystem.h>
@ -24,9 +27,9 @@
#include <media/MediaAnalyticsItem.h>
#include <media/Modulo.h>
#include <media/MicrophoneInfo.h>
#include <media/RecordingActivityTracker.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <vector>
#include "android/media/IAudioRecord.h"
@ -618,6 +621,8 @@ private:
sp<AudioRecordThread> mAudioRecordThread;
mutable Mutex mLock;
std::unique_ptr<RecordingActivityTracker> mTracker;
// Current client state: false = stopped, true = active. Protected by mLock. If more states
// are added, consider changing this to enum State { ... } mState as in AudioTrack.
bool mActive;

@ -242,6 +242,7 @@ public:
// or release it with releaseInput().
static status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,

@ -205,6 +205,9 @@ public:
return DEAD_OBJECT;
}
opPackageName = parcel->readString16();
if (parcel->read(&riid, sizeof(audio_unique_id_t)) != NO_ERROR) {
return DEAD_OBJECT;
}
/* input/output arguments*/
(void)parcel->read(&flags, sizeof(audio_input_flags_t));
@ -221,6 +224,7 @@ public:
(void)parcel->write(&config, sizeof(audio_config_base_t));
(void)clientInfo.writeToParcel(parcel);
(void)parcel->writeString16(opPackageName);
(void)parcel->write(&riid, sizeof(audio_unique_id_t));
/* input/output arguments*/
(void)parcel->write(&flags, sizeof(audio_input_flags_t));
@ -236,6 +240,7 @@ public:
audio_config_base_t config;
AudioClient clientInfo;
String16 opPackageName;
audio_unique_id_t riid;
/* input/output */
audio_input_flags_t flags;

@ -73,6 +73,7 @@ public:
virtual void releaseOutput(audio_port_handle_t portId) = 0;
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,

@ -31,6 +31,7 @@ namespace android {
// ----------------------------------------------------------------------------
struct record_client_info {
audio_unique_id_t riid;
uid_t uid;
audio_session_t session;
audio_source_t source;

@ -0,0 +1,44 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
#define __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
#include <utils/StrongPointer.h>
namespace android {
class IAudioManager;
class IBinder;
class RecordingActivityTracker
{
public:
RecordingActivityTracker();
~RecordingActivityTracker();
audio_unique_id_t getRiid();
void recordingStarted();
void recordingStopped();
private:
sp<IAudioManager> mAudioManager;
audio_unique_id_t mRIId;
sp<IBinder> mToken;
};
} // namespace android
#endif // __ANDROID_RECORDING_ACTIVITY_TRACKER_H__

@ -46,6 +46,7 @@
#include <cutils/properties.h>
#include <system/audio.h>
#include <audiomanager/AudioManager.h>
#include "AudioFlinger.h"
#include "NBAIO_Tee.h"
@ -312,6 +313,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
"%s does not support secondary outputs, ignoring them", __func__);
} else {
ret = AudioSystem::getInputForAttr(attr, &io,
RECORD_RIID_INVALID,
actualSessionId,
client.clientPid,
client.clientUid,
@ -1889,6 +1891,7 @@ sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& inpu
portId = AUDIO_PORT_HANDLE_NONE;
}
lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
input.riid,
sessionId,
// FIXME compare to AudioTrack
clientPid,

@ -59,6 +59,7 @@
#include <media/nbaio/SourceAudioBufferProvider.h>
#include <mediautils/BatteryNotifier.h>
#include <audiomanager/AudioManager.h>
#include <powermanager/PowerManager.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
@ -8561,6 +8562,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
config.format = mFormat;
audio_port_handle_t deviceId = mDeviceId;
ret = AudioSystem::getInputForAttr(&mAttr, &io,
RECORD_RIID_INVALID,
mSessionId,
client.clientPid,
client.clientUid,

@ -124,6 +124,7 @@ public:
// request an input appropriate for record from the supplied device with supplied parameters.
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
uid_t uid,
const audio_config_base_t *config,

@ -22,6 +22,7 @@
#include <sys/types.h>
#include <system/audio.h>
#include <audiomanager/AudioManager.h>
#include <media/AudioProductStrategy.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
@ -146,20 +147,23 @@ private:
class RecordClientDescriptor: public ClientDescriptor
{
public:
RecordClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
audio_attributes_t attributes, audio_config_base_t config,
audio_port_handle_t preferredDeviceId,
RecordClientDescriptor(audio_port_handle_t portId, audio_unique_id_t riid, uid_t uid,
audio_session_t sessionId, audio_attributes_t attributes,
audio_config_base_t config, audio_port_handle_t preferredDeviceId,
audio_source_t source, audio_input_flags_t flags, bool isSoundTrigger) :
ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger), mAppState(APP_STATE_IDLE) {}
mRIId(riid), mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger),
mAppState(APP_STATE_IDLE) {}
~RecordClientDescriptor() override = default;
using ClientDescriptor::dump;
void dump(String8 *dst, int spaces, int index) const override;
audio_unique_id_t riid() const { return mRIId; }
audio_source_t source() const { return mSource; }
audio_input_flags_t flags() const { return mFlags; }
bool isSoundTrigger() const { return mIsSoundTrigger; }
bool isLowLevel() const { return mRIId == RECORD_RIID_INVALID; }
void setAppState(app_state_t appState) { mAppState = appState; }
app_state_t appState() { return mAppState; }
bool isSilenced() const { return mAppState == APP_STATE_IDLE; }
@ -167,6 +171,7 @@ public:
EffectDescriptorCollection getEnabledEffects() const { return mEnabledEffects; }
private:
const audio_unique_id_t mRIId;
const audio_source_t mSource;
const audio_input_flags_t mFlags;
const bool mIsSoundTrigger;

@ -17,6 +17,7 @@
#define LOG_TAG "APM::AudioInputDescriptor"
//#define LOG_NDEBUG 0
#include <audiomanager/AudioManager.h>
#include <media/AudioPolicy.h>
#include <policy.h>
#include <AudioPolicyInterface.h>
@ -179,7 +180,9 @@ void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
mPatchHandle = handle;
for (const auto &client : getClientIterable()) {
if (client->active()) {
updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
updateClientRecordingConfiguration(
client->isLowLevel() ? RECORD_CONFIG_EVENT_START : RECORD_CONFIG_EVENT_UPDATE,
client);
}
}
}
@ -342,15 +345,19 @@ void AudioInputDescriptor::setClientActive(const sp<RecordClientDescriptor>& cli
void AudioInputDescriptor::updateClientRecordingConfiguration(
int event, const sp<RecordClientDescriptor>& client)
{
ALOGV("%s riid %d uid %d port %d session %d event %d",
__func__, client->riid(), client->uid(), client->portId(), client->session(), event);
// do not send callback if starting and no device is selected yet to avoid
// double callbacks from startInput() before and after the device is selected
if (event == RECORD_CONFIG_EVENT_START
&& mPatchHandle == AUDIO_PATCH_HANDLE_NONE) {
// "start" and "stop" events for "high level" clients (AudioRecord) are sent by the client side
if ((event == RECORD_CONFIG_EVENT_START && mPatchHandle == AUDIO_PATCH_HANDLE_NONE)
|| (!client->isLowLevel()
&& (event == RECORD_CONFIG_EVENT_START || event == RECORD_CONFIG_EVENT_STOP))) {
return;
}
const audio_config_base_t sessionConfig = client->config();
const record_client_info_t recordClientInfo{client->uid(), client->session(),
const record_client_info_t recordClientInfo{client->riid(), client->uid(), client->session(),
client->source(), client->portId(),
client->isSilenced()};
const audio_config_base_t config = getConfig();
@ -429,7 +436,7 @@ void AudioInputDescriptor::trackEffectEnabled(const sp<EffectDescriptor> &effect
checkSuspendEffects();
for (const auto& client : updatedClients) {
updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
}
}
@ -462,7 +469,7 @@ void AudioInputDescriptor::setAppState(uid_t uid, app_state_t state)
checkSuspendEffects();
for (const auto& client : updatedClients) {
updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
}
}

@ -1884,6 +1884,7 @@ void AudioPolicyManager::releaseOutput(audio_port_handle_t portId)
status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
uid_t uid,
const audio_config_base_t *config,
@ -2027,7 +2028,7 @@ exit:
mSoundTriggerSessions.indexOfKey(session) > 0;
*portId = AudioPort::getNextUniqueId();
clientDesc = new RecordClientDescriptor(*portId, uid, session, attributes, *config,
clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
requestedDeviceId, attributes.source, flags,
isSoundTrigger);
inputDesc = mInputs.valueFor(*input);

@ -128,6 +128,7 @@ public:
virtual void releaseOutput(audio_port_handle_t portId);
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
uid_t uid,
const audio_config_base_t *config,

@ -334,6 +334,7 @@ void AudioPolicyService::doReleaseOutput(audio_port_handle_t portId)
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,
@ -403,7 +404,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
{
AutoCallerClear acc;
// the audio_in_acoustics_t parameter is ignored by get_input()
status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
status = mAudioPolicyManager->getInputForAttr(attr, input, riid, session, uid,
config,
flags, selectedDeviceId,
&inputType, portId);

@ -91,6 +91,7 @@ public:
virtual void releaseOutput(audio_port_handle_t portId);
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_unique_id_t riid,
audio_session_t session,
pid_t pid,
uid_t uid,

Loading…
Cancel
Save