AudioFlinger: Associate audio time with client uid

Group active track operations for add and remove together.
PlaybackThread now uses strong pointer for active tracks.

Test: Play Music, Youtube, Batterystats, CTS AudioTrack
Bug: 32361950
Change-Id: I101df081dd8d090560a83c44c2fa9ffcbf39c84d
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index d261ea5..8607815 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -403,8 +403,8 @@
                     effect_uuid_t mType;    // effect type UUID
                 };
 
-                void        acquireWakeLock(int uid = -1);
-                virtual void acquireWakeLock_l(int uid = -1);
+                void        acquireWakeLock();
+                virtual void acquireWakeLock_l();
                 void        releaseWakeLock();
                 void        releaseWakeLock_l();
                 void        updateWakeLockUids_l(const SortedVector<int> &uids);
@@ -481,8 +481,92 @@
                 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() {
+                        ALOGW_IF(!mActiveTracks.isEmpty(),
+                                "ActiveTracks should be empty in destructor");
+                    }
+                    // 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();
+                    }
+
+                    // 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();
+                    }
+
+                    // Due to Binder recursion optimization, clear() and updatePowerState()
+                    // cannot be called from a Binder thread because they may call back into
+                    // the original calling process (system server) for BatteryNotifier
+                    // (which requires a Java environment that may not be present).
+                    // Hence, call clear() and updatePowerState() only from the
+                    // ThreadBase thread.
+                    void            clear();
+                    // periodically called in the threadLoop() to update power state uids.
+                    void            updatePowerState(sp<ThreadBase> thread, bool force = false);
+
+                private:
+                    SortedVector<int> getWakeLockUids() {
+                        SortedVector<int> wakeLockUids;
+                        for (const sp<T> &track : mActiveTracks) {
+                            wakeLockUids.add(track->uid());
+                        }
+                        return wakeLockUids; // moved by underlying SharedBuffer
+                    }
+
+                    std::map<uid_t, std::pair<ssize_t /* previous */, ssize_t /* current */>>
+                                        mBatteryCounter;
+                    SortedVector<sp<T>> mActiveTracks;
+                    int                 mActiveTracksGeneration;
+                    int                 mLastActiveTracksGeneration;
+                    wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
+                };
 };
 
 // --- PlaybackThread ---
@@ -561,6 +645,10 @@
     virtual     void        preExit();
 
     virtual     bool        keepWakeLock() const { return true; }
+    virtual     void        acquireWakeLock_l() {
+                                ThreadBase::acquireWakeLock_l();
+                                mActiveTracks.updatePowerState(this, true /* force */);
+                            }
 
 public:
 
@@ -733,10 +821,7 @@
     bool                            mMasterMute;
                 void        setMasterMute_l(bool muted) { mMasterMute = muted; }
 protected:
-    SortedVector< wp<Track> >       mActiveTracks;  // FIXME check if this could be sp<>
-    SortedVector<int>               mWakeLockUids;
-    int                             mActiveTracksGeneration;
-    wp<Track>                       mLatestActiveTrack; // latest track added to mActiveTracks
+    ActiveTracks<Track>     mActiveTracks;
 
     // Allocate a track name for a given channel mask.
     //   Returns name >= 0 if successful, -1 on failure.
@@ -974,8 +1059,8 @@
     virtual     uint32_t    suspendSleepTimeUs() const;
     virtual     void        cacheParameters_l();
 
-    virtual void acquireWakeLock_l(int uid = -1) {
-        PlaybackThread::acquireWakeLock_l(uid);
+    virtual void acquireWakeLock_l() {
+        PlaybackThread::acquireWakeLock_l();
         if (hasFastMixer()) {
             mFastMixer->setBoottimeOffset(
                     mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME]);
@@ -1414,6 +1499,11 @@
     virtual status_t    checkEffectCompatibility_l(const effect_descriptor_t *desc,
                                                    audio_session_t sessionId);
 
+    virtual void        acquireWakeLock_l() {
+                            ThreadBase::acquireWakeLock_l();
+                            mActiveTracks.updatePowerState(this, true /* force */);
+                        }
+
 private:
             // Enter standby if not already in standby, and set mStandby flag
             void    standbyIfNotAlreadyInStandby();
@@ -1425,9 +1515,8 @@
             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
-            SortedVector< sp<RecordTrack> >     mActiveTracks;
-            // generation counter for mActiveTracks
-            int                                 mActiveTracksGen;
+            ActiveTracks<RecordTrack>           mActiveTracks;
+
             Condition                           mStartStopCond;
 
             // resampler converts input at HAL Hz to output at AudioRecord client Hz