summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioTrack.h10
-rw-r--r--include/media/IAudioFlinger.h1
-rw-r--r--media/libmedia/AudioTrack.cpp20
-rw-r--r--media/libmedia/IAudioFlinger.cpp5
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp19
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h3
-rw-r--r--services/audioflinger/AudioFlinger.cpp9
-rw-r--r--services/audioflinger/AudioFlinger.h1
-rw-r--r--services/audioflinger/PlaybackTracks.h10
-rw-r--r--services/audioflinger/RecordTracks.h3
-rw-r--r--services/audioflinger/Threads.cpp95
-rw-r--r--services/audioflinger/Threads.h8
-rw-r--r--services/audioflinger/TrackBase.h3
-rw-r--r--services/audioflinger/Tracks.cpp36
14 files changed, 171 insertions, 52 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f2f9c22..f379ee5 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -187,7 +187,8 @@ public:
int notificationFrames = 0,
int sessionId = 0,
transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_offload_info_t *offloadInfo = NULL,
+ int uid = -1);
/* Creates an audio track and registers it with AudioFlinger.
* With this constructor, the track is configured for static buffer mode.
@@ -211,7 +212,8 @@ public:
int notificationFrames = 0,
int sessionId = 0,
transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_offload_info_t *offloadInfo = NULL,
+ int uid = -1);
/* Terminates the AudioTrack and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioTrack.
@@ -248,7 +250,8 @@ public:
bool threadCanCallJava = false,
int sessionId = 0,
transfer_type transferType = TRANSFER_DEFAULT,
- const audio_offload_info_t *offloadInfo = NULL);
+ const audio_offload_info_t *offloadInfo = NULL,
+ int uid = -1);
/* Result of constructing the AudioTrack. This must be checked for successful initialization
* before using any AudioTrack API (except for set()), because using
@@ -751,6 +754,7 @@ private:
sp<DeathNotifier> mDeathNotifier;
uint32_t mSequence; // incremented for each new IAudioTrack attempt
audio_io_handle_t mOutput; // cached output io handle
+ int mClientUid;
};
class TimedAudioTrack : public AudioTrack
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index eaf7780..899d79f 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -74,6 +74,7 @@ public:
// output: server's description of IAudioTrack for display in logs.
// Don't attempt to parse, as the format could change.
String8& name,
+ int clientUid,
status_t *status) = 0;
virtual sp<IAudioRecord> openRecord(
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index fe5cd9e..b8a89a0 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -101,7 +101,8 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -109,7 +110,8 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
- 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
+ 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType,
+ offloadInfo, uid);
}
AudioTrack::AudioTrack(
@@ -124,7 +126,8 @@ AudioTrack::AudioTrack(
int notificationFrames,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
@@ -132,7 +135,7 @@ AudioTrack::AudioTrack(
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
- sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo);
+ sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid);
}
AudioTrack::~AudioTrack()
@@ -169,7 +172,8 @@ status_t AudioTrack::set(
bool threadCanCallJava,
int sessionId,
transfer_type transferType,
- const audio_offload_info_t *offloadInfo)
+ const audio_offload_info_t *offloadInfo,
+ int uid)
{
switch (transferType) {
case TRANSFER_DEFAULT:
@@ -313,6 +317,11 @@ status_t AudioTrack::set(
mNotificationFramesReq = notificationFrames;
mNotificationFramesAct = 0;
mSessionId = sessionId;
+ if (uid == -1 || (IPCThreadState::self()->getCallingPid() != getpid())) {
+ mClientUid = IPCThreadState::self()->getCallingUid();
+ } else {
+ mClientUid = uid;
+ }
mAuxEffectId = 0;
mFlags = flags;
mCbf = cbf;
@@ -962,6 +971,7 @@ status_t AudioTrack::createTrack_l(
tid,
&mSessionId,
mName,
+ mClientUid,
&status);
if (track == 0) {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 448a82e..acfaea0 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -96,6 +96,7 @@ public:
pid_t tid,
int *sessionId,
String8& name,
+ int clientUid,
status_t *status)
{
Parcel data, reply;
@@ -121,6 +122,7 @@ public:
lSessionId = *sessionId;
}
data.writeInt32(lSessionId);
+ data.writeInt32(clientUid);
status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
if (lStatus != NO_ERROR) {
ALOGE("createTrack error: %s", strerror(-lStatus));
@@ -762,6 +764,7 @@ status_t BnAudioFlinger::onTransact(
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
int sessionId = data.readInt32();
+ int clientUid = data.readInt32();
String8 name;
status_t status;
sp<IAudioTrack> track;
@@ -773,7 +776,7 @@ status_t BnAudioFlinger::onTransact(
track = createTrack(
(audio_stream_type_t) streamType, sampleRate, format,
channelMask, frameCount, &flags, buffer, output, tid,
- &sessionId, name, &status);
+ &sessionId, name, clientUid, &status);
}
reply->writeInt32(flags);
reply->writeInt32(sessionId);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9553458..cd052e6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -590,7 +590,7 @@ sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
}
if (!p->hardwareOutput()) {
- mAudioOutput = new AudioOutput(mAudioSessionId);
+ mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid());
static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
}
@@ -1296,12 +1296,13 @@ Exit:
#undef LOG_TAG
#define LOG_TAG "AudioSink"
-MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
+MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid)
: mCallback(NULL),
mCallbackCookie(NULL),
mCallbackData(NULL),
mBytesWritten(0),
mSessionId(sessionId),
+ mUid(uid),
mFlags(AUDIO_OUTPUT_FLAG_NONE) {
ALOGV("AudioOutput(%d)", sessionId);
mStreamType = AUDIO_STREAM_MUSIC;
@@ -1549,7 +1550,8 @@ status_t MediaPlayerService::AudioOutput::open(
0, // notification frames
mSessionId,
AudioTrack::TRANSFER_CALLBACK,
- offloadInfo);
+ offloadInfo,
+ mUid);
} else {
t = new AudioTrack(
mStreamType,
@@ -1558,10 +1560,13 @@ status_t MediaPlayerService::AudioOutput::open(
channelMask,
frameCount,
flags,
- NULL,
- NULL,
- 0,
- mSessionId);
+ NULL, // callback
+ NULL, // user data
+ 0, // notification frames
+ mSessionId,
+ AudioTrack::TRANSFER_DEFAULT,
+ NULL, // offload info
+ mUid);
}
if ((t == 0) || (t->initCheck() != NO_ERROR)) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 21f4117..05d44d4 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -72,7 +72,7 @@ class MediaPlayerService : public BnMediaPlayerService
class CallbackData;
public:
- AudioOutput(int sessionId);
+ AudioOutput(int sessionId, int uid);
virtual ~AudioOutput();
virtual bool ready() const { return mTrack != 0; }
@@ -135,6 +135,7 @@ class MediaPlayerService : public BnMediaPlayerService
uint32_t mSampleRateHz; // sample rate of the content, as set in open()
float mMsecsPerFrame;
int mSessionId;
+ int mUid;
float mSendLevel;
int mAuxEffectId;
static bool mIsOnEmulator;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a9c9b56..6f6c2b6 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -448,6 +448,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
pid_t tid,
int *sessionId,
String8& name,
+ int clientUid,
status_t *status)
{
sp<PlaybackThread::Track> track;
@@ -483,6 +484,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
}
pid_t pid = IPCThreadState::self()->getCallingPid();
+
client = registerPid_l(pid);
ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId);
@@ -510,7 +512,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
ALOGV("createTrack() lSessionId: %d", lSessionId);
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus);
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -1284,8 +1286,11 @@ sp<IAudioRecord> AudioFlinger::openRecord(
}
// create new record track.
// The record track uses one track in mHardwareMixerThread by convention.
+ // TODO: the uid should be passed in as a parameter to openRecord
recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
- frameCount, lSessionId, flags, tid, &lStatus);
+ frameCount, lSessionId,
+ IPCThreadState::self()->getCallingUid(),
+ flags, tid, &lStatus);
LOG_ALWAYS_FATAL_IF((recordTrack != 0) != (lStatus == NO_ERROR));
}
if (lStatus != NO_ERROR) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2aeb263..53e238e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -109,6 +109,7 @@ public:
pid_t tid,
int *sessionId,
String8& name,
+ int clientUid,
status_t *status);
virtual sp<IAudioRecord> openRecord(
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index a2e2511..43b77f3 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -31,6 +31,7 @@ public:
size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ int uid,
IAudioFlinger::track_flags_t flags);
virtual ~Track();
@@ -165,7 +166,8 @@ class TimedTrack : public Track {
audio_channel_mask_t channelMask,
size_t frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId);
+ int sessionId,
+ int uid);
virtual ~TimedTrack();
class TimedBuffer {
@@ -208,7 +210,8 @@ class TimedTrack : public Track {
audio_channel_mask_t channelMask,
size_t frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId);
+ int sessionId,
+ int uid);
void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer);
void timedYieldSilence_l(uint32_t numFrames,
@@ -255,7 +258,8 @@ public:
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- size_t frameCount);
+ size_t frameCount,
+ int uid);
virtual ~OutputTrack();
virtual status_t start(AudioSystem::sync_event_t event =
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index cd8f70c..57de568 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -28,7 +28,8 @@ public:
audio_format_t format,
audio_channel_mask_t channelMask,
size_t frameCount,
- int sessionId);
+ int sessionId,
+ int uid);
virtual ~RecordTrack();
virtual status_t start(AudioSystem::sync_event_t event, int triggerSession);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9c8fd1f..ae059fb 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -503,17 +503,7 @@ String16 AudioFlinger::ThreadBase::getWakeLockTag()
void AudioFlinger::ThreadBase::acquireWakeLock_l(int uid)
{
- if (mPowerManager == 0) {
- // use checkService() to avoid blocking if power service is not up yet
- sp<IBinder> binder =
- defaultServiceManager()->checkService(String16("power"));
- if (binder == 0) {
- ALOGW("Thread %s cannot connect to the power manager service", mName);
- } else {
- mPowerManager = interface_cast<IPowerManager>(binder);
- binder->linkToDeath(mDeathRecipient);
- }
- }
+ getPowerManager_l();
if (mPowerManager != 0) {
sp<IBinder> binder = new BBinder();
status_t status;
@@ -553,6 +543,41 @@ void AudioFlinger::ThreadBase::releaseWakeLock_l()
}
}
+void AudioFlinger::ThreadBase::updateWakeLockUids(const SortedVector<int> &uids) {
+ Mutex::Autolock _l(mLock);
+ updateWakeLockUids_l(uids);
+}
+
+void AudioFlinger::ThreadBase::getPowerManager_l() {
+
+ if (mPowerManager == 0) {
+ // use checkService() to avoid blocking if power service is not up yet
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16("power"));
+ if (binder == 0) {
+ ALOGW("Thread %s cannot connect to the power manager service", mName);
+ } else {
+ mPowerManager = interface_cast<IPowerManager>(binder);
+ binder->linkToDeath(mDeathRecipient);
+ }
+ }
+}
+
+void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uids) {
+
+ getPowerManager_l();
+ if (mWakeLockToken == NULL) {
+ ALOGE("no wake lock to update!");
+ return;
+ }
+ if (mPowerManager != 0) {
+ sp<IBinder> binder = new BBinder();
+ status_t status;
+ status = mPowerManager->updateWakeLockUids(mWakeLockToken, uids.size(), uids.array());
+ ALOGV("acquireWakeLock_l() %s status %d", mName, status);
+ }
+}
+
void AudioFlinger::ThreadBase::clearPowerManager()
{
Mutex::Autolock _l(mLock);
@@ -977,6 +1002,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
: ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),
mNormalFrameCount(0), mMixBuffer(NULL),
mAllocMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
+ mActiveTracksGeneration(0),
// mStreamTypes[] initialized in constructor body
mOutput(output),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
@@ -1160,6 +1186,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
int sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
+ int uid,
status_t *status)
{
sp<Track> track;
@@ -1293,10 +1320,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
if (!isTimed) {
track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, sessionId, *flags);
+ channelMask, frameCount, sharedBuffer, sessionId, uid, *flags);
} else {
track = TimedTrack::create(this, client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, sessionId);
+ channelMask, frameCount, sharedBuffer, sessionId, uid);
}
if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
@@ -1432,6 +1459,8 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
track->mResetDone = false;
track->mPresentationCompleteFrames = 0;
mActiveTracks.add(track);
+ mWakeLockUids.add(track->uid());
+ mActiveTracksGeneration++;
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(),
@@ -2127,6 +2156,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
// FIXME could this be made local to while loop?
writeFrames = 0;
+ int lastGeneration = 0;
+
cacheParameters_l();
sleepTime = idleSleepTime;
@@ -2183,6 +2214,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
break;
}
releaseWakeLock_l();
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
ALOGV("wait async completion");
mWaitWorkCV.wait(mLock);
ALOGV("async completion/wake");
@@ -2213,6 +2246,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
}
releaseWakeLock_l();
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
// wait until we have something to do...
ALOGV("%s going to sleep", myName.string());
mWaitWorkCV.wait(mLock);
@@ -2237,11 +2272,18 @@ bool AudioFlinger::PlaybackThread::threadLoop()
// mMixerStatusIgnoringFastTracks is also updated internally
mMixerStatus = prepareTracks_l(&tracksToRemove);
+ // compare with previously applied list
+ if (lastGeneration != mActiveTracksGeneration) {
+ // update wakelock
+ updateWakeLockUids_l(mWakeLockUids);
+ lastGeneration = mActiveTracksGeneration;
+ }
+
// prevent any changes in effect chain list and in each effect chain
// during mixing and effect process as the audio buffers could be deleted
// or modified if an effect is created or deleted
lockEffectChains_l(effectChains);
- }
+ } // mLock scope ends
if (mBytesRemaining == 0) {
mCurrentWriteLength = 0;
@@ -2351,6 +2393,8 @@ if (mType == MIXER) {
}
releaseWakeLock();
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
ALOGV("Thread %p type %d exiting", this, mType);
return false;
@@ -2364,6 +2408,8 @@ void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tra
for (size_t i=0 ; i<count ; i++) {
const sp<Track>& track = tracksToRemove.itemAt(i);
mActiveTracks.remove(track);
+ mWakeLockUids.remove(track->uid());
+ mActiveTracksGeneration++;
ALOGV("removeTracks_l removing track on session %d", track->sessionId());
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
@@ -4213,7 +4259,8 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
mSampleRate,
mFormat,
mChannelMask,
- frameCount);
+ frameCount,
+ IPCThreadState::self()->getCallingUid());
if (outputTrack->cblk() != NULL) {
thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f);
mOutputTracks.add(outputTrack);
@@ -4315,7 +4362,6 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
snprintf(mName, kNameLength, "AudioIn_%X", id);
readInputParameters();
- mClientUid = IPCThreadState::self()->getCallingUid();
}
@@ -4347,7 +4393,11 @@ bool AudioFlinger::RecordThread::threadLoop()
nsecs_t lastWarning = 0;
inputStandBy();
- acquireWakeLock(mClientUid);
+ {
+ Mutex::Autolock _l(mLock);
+ activeTrack = mActiveTrack;
+ acquireWakeLock_l(activeTrack != 0 ? activeTrack->uid() : -1);
+ }
// used to verify we've read at least once before evaluating how many bytes were read
bool readOnce = false;
@@ -4360,6 +4410,12 @@ bool AudioFlinger::RecordThread::threadLoop()
{ // scope for mLock
Mutex::Autolock _l(mLock);
checkForNewParameters_l();
+ if (mActiveTrack != 0 && activeTrack != mActiveTrack) {
+ SortedVector<int> tmp;
+ tmp.add(mActiveTrack->uid());
+ updateWakeLockUids_l(tmp);
+ }
+ activeTrack = mActiveTrack;
if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
standby();
@@ -4372,7 +4428,7 @@ bool AudioFlinger::RecordThread::threadLoop()
// go to sleep
mWaitWorkCV.wait(mLock);
ALOGV("RecordThread: loop starting");
- acquireWakeLock_l(mClientUid);
+ acquireWakeLock_l(mActiveTrack != 0 ? mActiveTrack->uid() : -1);
continue;
}
if (mActiveTrack != 0) {
@@ -4582,6 +4638,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
audio_channel_mask_t channelMask,
size_t frameCount,
int sessionId,
+ int uid,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
status_t *status)
@@ -4651,7 +4708,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
Mutex::Autolock _l(mLock);
track = new RecordTrack(this, client, sampleRate,
- format, channelMask, frameCount, sessionId);
+ format, channelMask, frameCount, sessionId, uid);
if (track->getCblk() == 0) {
ALOGE("createRecordTrack_l() no control block");
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index a5d2169..81804c2 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -241,6 +241,9 @@ protected:
void acquireWakeLock_l(int uid = -1);
void releaseWakeLock();
void releaseWakeLock_l();
+ void updateWakeLockUids(const SortedVector<int> &uids);
+ void updateWakeLockUids_l(const SortedVector<int> &uids);
+ void getPowerManager_l();
void setEffectSuspended_l(const effect_uuid_t *type,
bool suspend,
int sessionId);
@@ -421,6 +424,7 @@ public:
int sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
+ int uid,
status_t *status);
AudioStreamOut* getOutput() const;
@@ -495,6 +499,8 @@ private:
void setMasterMute_l(bool muted) { mMasterMute = muted; }
protected:
SortedVector< wp<Track> > mActiveTracks; // FIXME check if this could be sp<>
+ SortedVector<int> mWakeLockUids;
+ int mActiveTracksGeneration;
// Allocate a track name for a given channel mask.
// Returns name >= 0 if successful, -1 on failure.
@@ -873,6 +879,7 @@ public:
audio_channel_mask_t channelMask,
size_t frameCount,
int sessionId,
+ int uid,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
status_t *status);
@@ -953,5 +960,4 @@ private:
// For dumpsys
const sp<NBAIO_Sink> mTeeSink;
- int mClientUid;
};
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 523e4b2..cd201d9 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -45,6 +45,7 @@ public:
size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ int uid,
bool isOut);
virtual ~TrackBase();
@@ -54,6 +55,7 @@ public:
sp<IMemory> getCblk() const { return mCblkMemory; }
audio_track_cblk_t* cblk() const { return mCblk; }
int sessionId() const { return mSessionId; }
+ int uid() const { return mUid; }
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
protected:
@@ -132,6 +134,7 @@ protected:
// openRecord(), and then adjusted as needed
const int mSessionId;
+ int mUid;
Vector < sp<SyncEvent> >mSyncEvents;
const bool mIsOut;
ServerProxy* mServerProxy;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 363bc9d..712c5a1 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -68,6 +68,7 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ int clientUid,
bool isOut)
: RefBase(),
mThread(thread),
@@ -88,6 +89,18 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mId(android_atomic_inc(&nextTrackId)),
mTerminated(false)
{
+ // if the caller is us, trust the specified uid
+ if (IPCThreadState::self()->getCallingPid() != getpid_cached || clientUid == -1) {
+ int newclientUid = IPCThreadState::self()->getCallingUid();
+ if (clientUid != -1 && clientUid != newclientUid) {
+ ALOGW("uid %d tried to pass itself off as %d", newclientUid, clientUid);
+ }
+ clientUid = newclientUid;
+ }
+ // clientUid contains the uid of the app that is responsible for this track, so we can blame
+ // battery usage on it.
+ mUid = clientUid;
+
// client == 0 implies sharedBuffer == 0
ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
@@ -313,9 +326,10 @@ AudioFlinger::PlaybackThread::Track::Track(
size_t frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ int uid,
IAudioFlinger::track_flags_t flags)
: TrackBase(thread, client, sampleRate, format, channelMask, frameCount, sharedBuffer,
- sessionId, true /*isOut*/),
+ sessionId, uid, true /*isOut*/),
mFillingUpStatus(FS_INVALID),
// mRetryCount initialized later when needed
mSharedBuffer(sharedBuffer),
@@ -963,13 +977,14 @@ AudioFlinger::PlaybackThread::TimedTrack::create(
audio_channel_mask_t channelMask,
size_t frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId) {
+ int sessionId,
+ int uid) {
if (!client->reserveTimedTrack())
return 0;
return new TimedTrack(
thread, client, streamType, sampleRate, format, channelMask, frameCount,
- sharedBuffer, sessionId);
+ sharedBuffer, sessionId, uid);
}
AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
@@ -981,9 +996,10 @@ AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
audio_channel_mask_t channelMask,
size_t frameCount,
const sp<IMemory>& sharedBuffer,
- int sessionId)
+ int sessionId,
+ int uid)
: Track(thread, client, streamType, sampleRate, format, channelMask,
- frameCount, sharedBuffer, sessionId, IAudioFlinger::TRACK_TIMED),
+ frameCount, sharedBuffer, sessionId, uid, IAudioFlinger::TRACK_TIMED),
mQueueHeadInFlight(false),
mTrimQueueHeadOnRelease(false),
mFramesPendingInQueue(0),
@@ -1476,9 +1492,10 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- size_t frameCount)
+ size_t frameCount,
+ int uid)
: Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
- NULL, 0, IAudioFlinger::TRACK_DEFAULT),
+ NULL, 0, uid, IAudioFlinger::TRACK_DEFAULT),
mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
{
@@ -1738,9 +1755,10 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
audio_format_t format,
audio_channel_mask_t channelMask,
size_t frameCount,
- int sessionId)
+ int sessionId,
+ int uid)
: TrackBase(thread, client, sampleRate, format,
- channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, false /*isOut*/),
+ channelMask, frameCount, 0 /*sharedBuffer*/, sessionId, uid, false /*isOut*/),
mOverflow(false)
{
ALOGV("RecordTrack constructor");