Revert "AudioFlinger: Associate audio time with client uid"
This reverts commit 2f366df67c31119bb6dd726becd32d14b18e6573.
Bug: 32728805
Change-Id: If0a158154814492eda427de0af8a49c0b0a91180
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 5052094..1d7b946 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -508,7 +508,8 @@
mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
// mName will be set by concrete (non-virtual) subclass
mDeathRecipient(new PMDeathRecipient(this)),
- mSystemReady(systemReady)
+ mSystemReady(systemReady),
+ mNotifiedBatteryStart(false)
{
memset(&mPatch, 0, sizeof(struct audio_patch));
}
@@ -849,10 +850,10 @@
}
}
-void AudioFlinger::ThreadBase::acquireWakeLock()
+void AudioFlinger::ThreadBase::acquireWakeLock(int uid)
{
Mutex::Autolock _l(mLock);
- acquireWakeLock_l();
+ acquireWakeLock_l(uid);
}
String16 AudioFlinger::ThreadBase::getWakeLockTag()
@@ -874,23 +875,37 @@
}
}
-void AudioFlinger::ThreadBase::acquireWakeLock_l()
+void AudioFlinger::ThreadBase::acquireWakeLock_l(int uid)
{
getPowerManager_l();
if (mPowerManager != 0) {
sp<IBinder> binder = new BBinder();
- // Uses AID_AUDIOSERVER for wakelock. updateWakeLockUids_l() updates with client uids.
- status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
+ status_t status;
+ if (uid >= 0) {
+ status = mPowerManager->acquireWakeLockWithUid(POWERMANAGER_PARTIAL_WAKE_LOCK,
+ binder,
+ getWakeLockTag(),
+ String16("audioserver"),
+ uid,
+ true /* FIXME force oneway contrary to .aidl */);
+ } else {
+ status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
binder,
getWakeLockTag(),
String16("audioserver"),
true /* FIXME force oneway contrary to .aidl */);
+ }
if (status == NO_ERROR) {
mWakeLockToken = binder;
}
ALOGV("acquireWakeLock_l() %s status %d", mThreadName, status);
}
+ if (!mNotifiedBatteryStart) {
+ // TODO: call this function for each track when it becomes active.
+ BatteryNotifier::getInstance().noteStartAudio(AID_AUDIOSERVER);
+ mNotifiedBatteryStart = true;
+ }
gBoottime.acquire(mWakeLockToken);
mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] =
gBoottime.getBoottimeOffset();
@@ -913,6 +928,12 @@
}
mWakeLockToken.clear();
}
+
+ if (mNotifiedBatteryStart) {
+ // TODO: call this function for each track when it becomes inactive.
+ BatteryNotifier::getInstance().noteStopAudio(AID_AUDIOSERVER);
+ mNotifiedBatteryStart = false;
+ }
}
void AudioFlinger::ThreadBase::getPowerManager_l() {
@@ -929,17 +950,8 @@
}
}
-void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<uid_t> &uids) {
+void AudioFlinger::ThreadBase::updateWakeLockUids_l(const SortedVector<int> &uids) {
getPowerManager_l();
-
-#if !LOG_NDEBUG
- std::stringstream s;
- for (uid_t uid : uids) {
- s << uid << " ";
- }
- ALOGD("updateWakeLockUids_l %s uids:%s", mThreadName, s.str().c_str());
-#endif
-
if (mWakeLockToken == NULL) { // token may be NULL if AudioFlinger::systemReady() not called.
if (mSystemReady) {
ALOGE("no wake lock to update, but system ready!");
@@ -1501,41 +1513,6 @@
mPendingConfigEvents.clear();
}
-template <typename T>
-ssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::add(const sp<T> &track) {
- ssize_t index = mActiveTracks.indexOf(track);
- if (index >= 0) {
- ALOGW("ActiveTracks<T>::add track %p already there", track.get());
- return index;
- }
- mActiveTracksGeneration++;
- mLatestActiveTrack = track;
- BatteryNotifier::getInstance().noteStartAudio(track->uid());
- return mActiveTracks.add(track);
-}
-
-template <typename T>
-ssize_t AudioFlinger::ThreadBase::ActiveTracks<T>::remove(const sp<T> &track) {
- ssize_t index = mActiveTracks.remove(track);
- if (index < 0) {
- ALOGW("ActiveTracks<T>::remove nonexistent track %p", track.get());
- return index;
- }
- mActiveTracksGeneration++;
- BatteryNotifier::getInstance().noteStopAudio(track->uid());
- // mLatestActiveTrack is not cleared even if is the same as track.
- return index;
-}
-
-template <typename T>
-void AudioFlinger::ThreadBase::ActiveTracks<T>::clear() {
- for (const sp<T> &track : mActiveTracks) {
- BatteryNotifier::getInstance().noteStopAudio(track->uid());
- }
- mLastActiveTracksGeneration = mActiveTracksGeneration;
- mActiveTracks.clear();
- mLatestActiveTrack.clear();
-}
// ----------------------------------------------------------------------------
// Playback
@@ -1562,6 +1539,7 @@
mSuspended(0), mBytesWritten(0),
mFramesWritten(0),
mSuspendedFrames(0),
+ mActiveTracksGeneration(0),
// mStreamTypes[] initialized in constructor body
mOutput(output),
mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
@@ -1680,8 +1658,8 @@
result.append(buffer);
Track::appendDumpHeader(result);
for (size_t i = 0; i < numactive; ++i) {
- sp<Track> track = mActiveTracks[i];
- if (mTracks.indexOf(track) < 0) {
+ sp<Track> track = mActiveTracks[i].promote();
+ if (track != 0 && mTracks.indexOf(track) < 0) {
track->dump(buffer, SIZE, true);
result.append(buffer);
}
@@ -2084,6 +2062,9 @@
track->mResetDone = false;
track->mPresentationCompleteFrames = 0;
mActiveTracks.add(track);
+ mWakeLockUids.add(track->uid());
+ mActiveTracksGeneration++;
+ mLatestActiveTrack = track;
sp<EffectChain> chain = getEffectChain_l(track->sessionId());
if (chain != 0) {
ALOGV("addTrack_l() starting track on chain %p for session %d", chain.get(),
@@ -2718,7 +2699,11 @@
}
// indicate all active tracks in the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
+ sp<Track> track = mActiveTracks[i].promote();
+ if (track == 0) {
+ continue;
+ }
if (session == track->sessionId()) {
ALOGV("addEffectChain_l() activating track %p on session %d", track.get(), session);
chain->incActiveTrackCnt();
@@ -2765,7 +2750,11 @@
if (chain == mEffectChains[i]) {
mEffectChains.removeAt(i);
// detach all active tracks from the chain
- for (const sp<Track> &track : mActiveTracks) {
+ for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
+ sp<Track> track = mActiveTracks[i].promote();
+ if (track == 0) {
+ continue;
+ }
if (session == track->sessionId()) {
ALOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d",
chain.get(), session);
@@ -2842,6 +2831,8 @@
// FIXME could this be made local to while loop?
writeFrames = 0;
+ int lastGeneration = 0;
+
cacheParameters_l();
mSleepTimeUs = mIdleSleepTimeUs;
@@ -2939,9 +2930,10 @@
mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastWriteTime == -1
? systemTime() : mLastWriteTime;
}
-
- for (const sp<Track> &t : mActiveTracks) {
- if (!t->isFastTrack()) {
+ const size_t size = mActiveTracks.size();
+ for (size_t i = 0; i < size; ++i) {
+ sp<Track> t = mActiveTracks[i].promote();
+ if (t != 0 && !t->isFastTrack()) {
t->updateTrackFrameInfo(
t->mAudioTrackServerProxy->framesReleased(),
mFramesWritten,
@@ -2962,6 +2954,8 @@
if (!keepWakeLock()) {
releaseWakeLock_l();
released = true;
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
}
ALOGV("wait async completion");
mWaitWorkCV.wait(mLock);
@@ -2995,6 +2989,8 @@
}
releaseWakeLock_l();
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
// wait until we have something to do...
ALOGV("%s going to sleep", myName.string());
mWaitWorkCV.wait(mLock);
@@ -3019,7 +3015,12 @@
// mMixerStatusIgnoringFastTracks is also updated internally
mMixerStatus = prepareTracks_l(&tracksToRemove);
- mActiveTracks.updateWakeLockUids(this);
+ // 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
@@ -3237,6 +3238,8 @@
}
releaseWakeLock();
+ mWakeLockUids.clear();
+ mActiveTracksGeneration++;
ALOGV("Thread %p type %d exiting", this, mType);
return false;
@@ -3250,6 +3253,8 @@
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) {
@@ -3868,7 +3873,10 @@
mEffectBufferValid = false; // mEffectBuffer has no valid data until tracks found.
for (size_t i=0 ; i<count ; i++) {
- const sp<Track> t = mActiveTracks[i];
+ const sp<Track> t = mActiveTracks[i].promote();
+ if (t == 0) {
+ continue;
+ }
// this const just means the local variable doesn't change
Track* const track = t.get();
@@ -4364,7 +4372,11 @@
size_t i = __builtin_ctz(resetMask);
ALOG_ASSERT(i < count);
resetMask &= ~(1 << i);
- sp<Track> track = mActiveTracks[i];
+ sp<Track> t = mActiveTracks[i].promote();
+ if (t == 0) {
+ continue;
+ }
+ Track* track = t.get();
ALOG_ASSERT(track->isFastTrack() && track->isStopped());
track->reset();
}
@@ -4674,7 +4686,7 @@
void AudioFlinger::DirectOutputThread::onAddNewTrack_l()
{
sp<Track> previousTrack = mPreviousTrack.promote();
- sp<Track> latestTrack = mActiveTracks.getLatest();
+ sp<Track> latestTrack = mLatestActiveTrack.promote();
if (previousTrack != 0 && latestTrack != 0) {
if (mType == DIRECT) {
@@ -4700,7 +4712,13 @@
bool doHwResume = false;
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
+ for (size_t i = 0; i < count; i++) {
+ sp<Track> t = mActiveTracks[i].promote();
+ // The track died recently
+ if (t == 0) {
+ continue;
+ }
+
if (t->isInvalid()) {
ALOGW("An invalidated track shouldn't be in active list");
tracksToRemove->add(t);
@@ -4715,7 +4733,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<Track> l = mLatestActiveTrack.promote();
bool last = l.get() == track;
if (track->isPausing()) {
@@ -5249,7 +5267,12 @@
ALOGV("OffloadThread::prepareTracks_l active tracks %zu", count);
// find out which tracks need to be processed
- for (const sp<Track> &t : mActiveTracks) {
+ for (size_t i = 0; i < count; i++) {
+ sp<Track> t = mActiveTracks[i].promote();
+ // The track died recently
+ if (t == 0) {
+ continue;
+ }
Track* const track = t.get();
#ifdef VERY_VERY_VERBOSE_LOGGING
audio_track_cblk_t* cblk = track->cblk();
@@ -5258,7 +5281,7 @@
// In theory an older track could underrun and restart after the new one starts
// but as we only care about the transition phase between two tracks on a
// direct output, it is not a problem to ignore the underrun case.
- sp<Track> l = mActiveTracks.getLatest();
+ sp<Track> l = mLatestActiveTrack.promote();
bool last = l.get() == track;
if (track->isInvalid()) {
@@ -5717,7 +5740,7 @@
#endif
) :
ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD, systemReady),
- mInput(input), mRsmpInBuffer(NULL),
+ mInput(input), mActiveTracksGen(0), mRsmpInBuffer(NULL),
// mRsmpInFrames, mRsmpInFramesP2, and mRsmpInFramesOA are set by readInputParameters_l()
mRsmpInRear(0)
#ifdef TEE_SINK
@@ -5875,9 +5898,25 @@
reacquire_wakelock:
sp<RecordTrack> activeTrack;
+ int activeTracksGen;
{
Mutex::Autolock _l(mLock);
- acquireWakeLock_l();
+ size_t size = mActiveTracks.size();
+ activeTracksGen = mActiveTracksGen;
+ if (size > 0) {
+ // FIXME an arbitrary choice
+ activeTrack = mActiveTracks[0];
+ acquireWakeLock_l(activeTrack->uid());
+ if (size > 1) {
+ SortedVector<int> tmp;
+ for (size_t i = 0; i < size; i++) {
+ tmp.add(mActiveTracks[i]->uid());
+ }
+ updateWakeLockUids_l(tmp);
+ }
+ } else {
+ acquireWakeLock_l(-1);
+ }
}
// used to request a deferred sleep, to be executed later while mutex is unlocked
@@ -5929,6 +5968,15 @@
goto reacquire_wakelock;
}
+ if (mActiveTracksGen != activeTracksGen) {
+ activeTracksGen = mActiveTracksGen;
+ SortedVector<int> tmp;
+ for (size_t i = 0; i < size; i++) {
+ tmp.add(mActiveTracks[i]->uid());
+ }
+ updateWakeLockUids_l(tmp);
+ }
+
bool doBroadcast = false;
bool allStopped = true;
for (size_t i = 0; i < size; ) {
@@ -5941,6 +5989,7 @@
}
removeTrack_l(activeTrack);
mActiveTracks.remove(activeTrack);
+ mActiveTracksGen++;
size--;
continue;
}
@@ -5950,6 +5999,7 @@
case TrackBase::PAUSING:
mActiveTracks.remove(activeTrack);
+ mActiveTracksGen++;
doBroadcast = true;
size--;
continue;
@@ -5989,8 +6039,6 @@
}
}
- mActiveTracks.updateWakeLockUids(this);
-
if (allStopped) {
standbyIfNotAlreadyInStandby();
}
@@ -6289,6 +6337,7 @@
track->invalidate();
}
mActiveTracks.clear();
+ mActiveTracksGen++;
mStartStopCond.broadcast();
}
@@ -6542,6 +6591,7 @@
// or using a separate command thread
recordTrack->mState = TrackBase::STARTING_1;
mActiveTracks.add(recordTrack);
+ mActiveTracksGen++;
status_t status = NO_ERROR;
if (recordTrack->isExternalTrack()) {
mLock.unlock();
@@ -6550,6 +6600,7 @@
// FIXME should verify that recordTrack is still in mActiveTracks
if (status != NO_ERROR) {
mActiveTracks.remove(recordTrack);
+ mActiveTracksGen++;
recordTrack->clearSyncStartEvent();
ALOGV("RecordThread::start error %d", status);
return status;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index fc3c013..5235cde 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -400,11 +400,11 @@
effect_uuid_t mType; // effect type UUID
};
- void acquireWakeLock();
- virtual void acquireWakeLock_l();
+ void acquireWakeLock(int uid = -1);
+ virtual void acquireWakeLock_l(int uid = -1);
void releaseWakeLock();
void releaseWakeLock_l();
- void updateWakeLockUids_l(const SortedVector<uid_t> &uids);
+ void updateWakeLockUids_l(const SortedVector<int> &uids);
void getPowerManager_l();
void setEffectSuspended_l(const effect_uuid_t *type,
bool suspend,
@@ -478,88 +478,8 @@
static const size_t kLogSize = 4 * 1024;
sp<NBLog::Writer> mNBLogWriter;
bool mSystemReady;
+ bool mNotifiedBatteryStart;
ExtendedTimestamp mTimestamp;
-
- // ActiveTracks is a sorted vector of track type T representing the
- // active tracks of threadLoop() to be considered by the locked prepare portion.
- // ActiveTracks should be accessed with the ThreadBase lock held.
- //
- // During processing and I/O, the threadLoop does not hold the lock;
- // hence it does not directly use ActiveTracks. Care should be taken
- // to hold local strong references or defer removal of tracks
- // if the threadLoop may still be accessing those tracks due to mix, etc.
- //
- // This class updates power information appropriately.
- //
-
- template <typename T>
- class ActiveTracks {
- public:
- ActiveTracks()
- : mActiveTracksGeneration(0)
- , mLastActiveTracksGeneration(0)
- { }
-
- ~ActiveTracks() {
- clear();
- }
- // returns the last track added (even though it may have been
- // subsequently removed from ActiveTracks).
- //
- // Used for DirectOutputThread to ensure a flush is called when transitioning
- // to a new track (even though it may be on the same session).
- // Used for OffloadThread to ensure that volume and mixer state is
- // taken from the latest track added.
- //
- // The latest track is saved with a weak pointer to prevent keeping an
- // otherwise useless track alive. Thus the function will return nullptr
- // if the latest track has subsequently been removed and destroyed.
- sp<T> getLatest() {
- return mLatestActiveTrack.promote();
- }
-
- // Updates ActiveTracks client uids to the thread wakelock.
- void updateWakeLockUids(sp<ThreadBase> thread, bool force = false) {
- if (mActiveTracksGeneration != mLastActiveTracksGeneration || force) {
- thread->updateWakeLockUids_l(getWakeLockUids());
- mLastActiveTracksGeneration = mActiveTracksGeneration;
- }
- }
-
- // SortedVector methods
- ssize_t add(const sp<T> &track);
- ssize_t remove(const sp<T> &track);
- size_t size() const {
- return mActiveTracks.size();
- }
- ssize_t indexOf(const sp<T>& item) {
- return mActiveTracks.indexOf(item);
- }
- sp<T> operator[](size_t index) const {
- return mActiveTracks[index];
- }
- typename SortedVector<sp<T>>::iterator begin() {
- return mActiveTracks.begin();
- }
- typename SortedVector<sp<T>>::iterator end() {
- return mActiveTracks.end();
- }
- void clear();
-
- private:
- SortedVector<uid_t> getWakeLockUids() {
- SortedVector<uid_t> wakeLockUids;
- for (const sp<T> &track : mActiveTracks) {
- wakeLockUids.add(track->uid());
- }
- return wakeLockUids; // moved by underlying SharedBuffer
- }
-
- SortedVector<sp<T>> mActiveTracks;
- int mActiveTracksGeneration;
- int mLastActiveTracksGeneration;
- wp<T> mLatestActiveTrack; // latest track added to ActiveTracks
- };
};
// --- PlaybackThread ---
@@ -638,10 +558,6 @@
virtual void preExit();
virtual bool keepWakeLock() const { return true; }
- virtual void acquireWakeLock_l() {
- ThreadBase::acquireWakeLock_l();
- mActiveTracks.updateWakeLockUids(this, true /* force */);
- }
public:
@@ -814,7 +730,10 @@
bool mMasterMute;
void setMasterMute_l(bool muted) { mMasterMute = muted; }
protected:
- ActiveTracks<Track> mActiveTracks;
+ SortedVector< wp<Track> > mActiveTracks; // FIXME check if this could be sp<>
+ SortedVector<int> mWakeLockUids;
+ int mActiveTracksGeneration;
+ wp<Track> mLatestActiveTrack; // latest track added to mActiveTracks
// Allocate a track name for a given channel mask.
// Returns name >= 0 if successful, -1 on failure.
@@ -980,8 +899,8 @@
virtual uint32_t suspendSleepTimeUs() const;
virtual void cacheParameters_l();
- virtual void acquireWakeLock_l() {
- PlaybackThread::acquireWakeLock_l();
+ virtual void acquireWakeLock_l(int uid = -1) {
+ PlaybackThread::acquireWakeLock_l(uid);
if (hasFastMixer()) {
mFastMixer->setBoottimeOffset(
mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME]);
@@ -1420,11 +1339,6 @@
virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc,
audio_session_t sessionId);
- virtual void acquireWakeLock_l() {
- ThreadBase::acquireWakeLock_l();
- mActiveTracks.updateWakeLockUids(this, true /* force */);
- }
-
private:
// Enter standby if not already in standby, and set mStandby flag
void standbyIfNotAlreadyInStandby();
@@ -1436,8 +1350,9 @@
SortedVector < sp<RecordTrack> > mTracks;
// mActiveTracks has dual roles: it indicates the current active track(s), and
// is used together with mStartStopCond to indicate start()/stop() progress
- ActiveTracks<RecordTrack> mActiveTracks;
-
+ SortedVector< sp<RecordTrack> > mActiveTracks;
+ // generation counter for mActiveTracks
+ int mActiveTracksGen;
Condition mStartStopCond;
// resampler converts input at HAL Hz to output at AudioRecord client Hz