DO NOT MERGE - Merge QQ1A.191205.011 into stage-aosp-master

Bug: 144955631
Merged-In: I242aebe71ffe7d348eca213252f1691fd444703e
Change-Id: I40ae7732b4435dc9aa9a3edb57275505e4112a4c
gugelfrei
Xin Li 5 years ago
commit 4f3ac4d055

@ -1960,7 +1960,8 @@ sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& inpu
&output.notificationFrameCount,
callingPid, clientUid, &output.flags,
input.clientInfo.clientTid,
&lStatus, portId);
&lStatus, portId,
input.opPackageName);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
// lStatus == BAD_TYPE means FAST flag was rejected: request a new input from

@ -19,6 +19,39 @@
#error This header file should only be included from AudioFlinger.h
#endif
// Checks and monitors OP_RECORD_AUDIO
class OpRecordAudioMonitor : public RefBase {
public:
~OpRecordAudioMonitor() override;
bool hasOpRecordAudio() const;
static sp<OpRecordAudioMonitor> createIfNeeded(uid_t uid, const String16& opPackageName);
private:
OpRecordAudioMonitor(uid_t uid, const String16& opPackageName);
void onFirstRef() override;
AppOpsManager mAppOpsManager;
class RecordAudioOpCallback : public BnAppOpsCallback {
public:
explicit RecordAudioOpCallback(const wp<OpRecordAudioMonitor>& monitor);
void opChanged(int32_t op, const String16& packageName) override;
private:
const wp<OpRecordAudioMonitor> mMonitor;
};
sp<RecordAudioOpCallback> mOpCallback;
// called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
// and in onFirstRef()
void checkRecordAudio();
std::atomic_bool mHasOpRecordAudio;
const uid_t mUid;
const String16 mPackage;
};
// record track
class RecordTrack : public TrackBase {
public:
@ -36,6 +69,7 @@ public:
uid_t uid,
audio_input_flags_t flags,
track_type type,
const String16& opPackageName,
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
virtual ~RecordTrack();
virtual status_t initCheck() const;
@ -68,7 +102,7 @@ public:
{ return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }
void setSilenced(bool silenced) { if (!isPatchTrack()) mSilenced = silenced; }
bool isSilenced() const { return mSilenced; }
bool isSilenced() const;
status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
@ -111,6 +145,11 @@ private:
audio_input_flags_t mFlags;
bool mSilenced;
// used to enforce OP_RECORD_AUDIO
uid_t mUid;
String16 mOpPackageName;
sp<OpRecordAudioMonitor> mOpRecordAudioMonitor;
};
// playback track, used by PatchPanel

@ -7303,7 +7303,7 @@ reacquire_wakelock:
// Sanitize before releasing if the track has no access to the source data
// An idle UID receives silence from non virtual devices until active
if (activeTrack->isSilenced()) {
memset(activeTrack->mSink.raw, 0, framesOut * mFrameSize);
memset(activeTrack->mSink.raw, 0, framesOut * activeTrack->frameSize());
}
activeTrack->releaseBuffer(&activeTrack->mSink);
}
@ -7464,7 +7464,8 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe
audio_input_flags_t *flags,
pid_t tid,
status_t *status,
audio_port_handle_t portId)
audio_port_handle_t portId,
const String16& opPackageName)
{
size_t frameCount = *pFrameCount;
size_t notificationFrameCount = *pNotificationFrameCount;
@ -7598,7 +7599,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe
track = new RecordTrack(this, client, attr, sampleRate,
format, channelMask, frameCount,
nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid, uid,
*flags, TrackBase::TYPE_DEFAULT, portId);
*flags, TrackBase::TYPE_DEFAULT, opPackageName, portId);
lStatus = track->initCheck();
if (lStatus != NO_ERROR) {

@ -1553,7 +1553,8 @@ public:
audio_input_flags_t *flags,
pid_t tid,
status_t *status /*non-NULL*/,
audio_port_handle_t portId);
audio_port_handle_t portId,
const String16& opPackageName);
status_t start(RecordTrack* recordTrack,
AudioSystem::sync_event_t event,

@ -215,6 +215,8 @@ protected:
uint32_t channelCount() const { return mChannelCount; }
size_t frameSize() const { return mFrameSize; }
audio_channel_mask_t channelMask() const { return mChannelMask; }
virtual uint32_t sampleRate() const { return mSampleRate; }

@ -444,7 +444,7 @@ bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const {
return mHasOpPlayAudio.load();
}
// Note this method is never called (and never to be) for audio server / root track
// Note this method is never called (and never to be) for audio server / patch record track
// - not called from constructor due to check on UID,
// - not called from PlayAudioOpCallback because the callback is not installed in this case
void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::checkPlayAudioForUsage()
@ -1885,6 +1885,105 @@ void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
// ----------------------------------------------------------------------------
// Record
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// AppOp for audio recording
// -------------------------------
#undef LOG_TAG
#define LOG_TAG "AF::OpRecordAudioMonitor"
// static
sp<AudioFlinger::RecordThread::OpRecordAudioMonitor>
AudioFlinger::RecordThread::OpRecordAudioMonitor::createIfNeeded(
uid_t uid, const String16& opPackageName)
{
if (isServiceUid(uid)) {
ALOGV("not silencing record for service uid:%d pack:%s",
uid, String8(opPackageName).string());
return nullptr;
}
if (opPackageName.size() == 0) {
Vector<String16> packages;
// no package name, happens with SL ES clients
// query package manager to find one
PermissionController permissionController;
permissionController.getPackagesForUid(uid, packages);
if (packages.isEmpty()) {
return nullptr;
} else {
ALOGV("using pack:%s for uid:%d", String8(packages[0]).string(), uid);
return new OpRecordAudioMonitor(uid, packages[0]);
}
}
return new OpRecordAudioMonitor(uid, opPackageName);
}
AudioFlinger::RecordThread::OpRecordAudioMonitor::OpRecordAudioMonitor(
uid_t uid, const String16& opPackageName)
: mHasOpRecordAudio(true), mUid(uid), mPackage(opPackageName)
{
}
AudioFlinger::RecordThread::OpRecordAudioMonitor::~OpRecordAudioMonitor()
{
if (mOpCallback != 0) {
mAppOpsManager.stopWatchingMode(mOpCallback);
}
mOpCallback.clear();
}
void AudioFlinger::RecordThread::OpRecordAudioMonitor::onFirstRef()
{
checkRecordAudio();
mOpCallback = new RecordAudioOpCallback(this);
ALOGV("start watching OP_RECORD_AUDIO for pack:%s", String8(mPackage).string());
mAppOpsManager.startWatchingMode(AppOpsManager::OP_RECORD_AUDIO, mPackage, mOpCallback);
}
bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOpRecordAudio() const {
return mHasOpRecordAudio.load();
}
// Called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
// and in onFirstRef()
// Note this method is never called (and never to be) for audio server / root track
// due to the UID in createIfNeeded(). As a result for those record track, it's:
// - not called from constructor,
// - not called from RecordAudioOpCallback because the callback is not installed in this case
void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkRecordAudio()
{
const int32_t mode = mAppOpsManager.checkOp(AppOpsManager::OP_RECORD_AUDIO,
mUid, mPackage);
const bool hasIt = (mode == AppOpsManager::MODE_ALLOWED);
// verbose logging only log when appOp changed
ALOGI_IF(hasIt != mHasOpRecordAudio.load(),
"OP_RECORD_AUDIO missing, %ssilencing record uid%d pack:%s",
hasIt ? "un" : "", mUid, String8(mPackage).string());
mHasOpRecordAudio.store(hasIt);
}
AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::RecordAudioOpCallback(
const wp<OpRecordAudioMonitor>& monitor) : mMonitor(monitor)
{ }
void AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
const String16& packageName) {
UNUSED(packageName);
if (op != AppOpsManager::OP_RECORD_AUDIO) {
return;
}
sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
if (monitor != NULL) {
monitor->checkRecordAudio();
}
}
#undef LOG_TAG
#define LOG_TAG "AF::RecordHandle"
@ -1956,6 +2055,7 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
uid_t uid,
audio_input_flags_t flags,
track_type type,
const String16& opPackageName,
audio_port_handle_t portId)
: TrackBase(thread, client, attr, sampleRate, format,
channelMask, frameCount, buffer, bufferSize, sessionId,
@ -1969,7 +2069,8 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
mRecordBufferConverter(NULL),
mFlags(flags),
mSilenced(false)
mSilenced(false),
mOpRecordAudioMonitor(OpRecordAudioMonitor::createIfNeeded(uid, opPackageName))
{
if (mCblk == NULL) {
return;
@ -2220,6 +2321,14 @@ void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
mServerLatencyMs.store(latencyMs);
}
bool AudioFlinger::RecordThread::RecordTrack::isSilenced() const {
if (mSilenced) {
return true;
}
// The monitor is only created for record tracks that can be silenced.
return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOpRecordAudio() : false;
}
status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
std::vector<media::MicrophoneInfo>* activeMicrophones)
{
@ -2270,7 +2379,7 @@ AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
audio_attributes_t{} /* currently unused for patch track */,
sampleRate, format, channelMask, frameCount,
buffer, bufferSize, AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER,
flags, TYPE_PATCH),
flags, TYPE_PATCH, String16()),
PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true),
*recordThread, timeout)
{

Loading…
Cancel
Save