Call AudioMixer only from MixerThread threadLoop.

As part of change:
Remove track name offset by TRACK0.
Move track name management to the Tracks class.
Sync mixer track name to FastMixer track index.

Fixes regression introduced by commit 8ed196a.

Test: SoundPool, AudioTrack CTS, Usability
Bug: 72937362
Bug: 73004420
Change-Id: I2f1a33f6f0da66bcd7aa91e2a4b663ff822df645
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index ace586c..ef466a2 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -79,7 +79,6 @@
 
     unsigned i;
     for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
-        mFastTrackNames[i] = -1;
         mGenerations[i] = 0;
     }
 #ifdef FAST_THREAD_STATISTICS
@@ -190,7 +189,7 @@
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal mixer allocate for us
             //       to avoid blocking here and to prevent possible priority inversion
-            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks);
+            mMixer = new AudioMixer(frameCount, mSampleRate);
             // FIXME See the other FIXME at FastMixer::setNBLogWriter()
             const size_t mixerFrameSize = mSinkChannelCount
                     * audio_bytes_per_sample(mMixerBufferFormat);
@@ -235,7 +234,6 @@
     dumpState->mTrackMask = currentTrackMask;
     if (current->mFastTracksGen != mFastTracksGen) {
         ALOG_ASSERT(mMixerBuffer != NULL);
-        int name;
 
         // process removed tracks first to avoid running out of track names
         unsigned removedTracks = previousTrackMask & ~currentTrackMask;
@@ -245,9 +243,7 @@
             const FastTrack* fastTrack = &current->mFastTracks[i];
             ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
             if (mMixer != NULL) {
-                name = mFastTrackNames[i];
-                ALOG_ASSERT(name >= 0);
-                mMixer->deleteTrackName(name);
+                mMixer->destroy(i);
             }
 #if !LOG_NDEBUG
             mFastTrackNames[i] = -1;
@@ -265,10 +261,16 @@
             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
             ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
             if (mMixer != NULL) {
-                name = mMixer->getTrackName(fastTrack->mChannelMask,
+                const int name = i; // for clarity, choose name as fast track index.
+                status_t status = mMixer->create(
+                        name,
+                        fastTrack->mChannelMask,
                         fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
-                ALOG_ASSERT(name >= 0);
-                mFastTrackNames[i] = name;
+                LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
+                        "%s: cannot create track name"
+                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+                        __func__, name,
+                        fastTrack->mChannelMask, fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
                 mMixer->setBufferProvider(name, bufferProvider);
                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
                         (void *)mMixerBuffer);
@@ -300,8 +302,7 @@
                 AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
                 ALOG_ASSERT(bufferProvider != NULL);
                 if (mMixer != NULL) {
-                    name = mFastTrackNames[i];
-                    ALOG_ASSERT(name >= 0);
+                    const int name = i;
                     mMixer->setBufferProvider(name, bufferProvider);
                     if (fastTrack->mVolumeProvider == NULL) {
                         float f = AudioMixer::UNITY_GAIN_FLOAT;
@@ -378,8 +379,7 @@
             perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten;
             fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
 
-            int name = mFastTrackNames[i];
-            ALOG_ASSERT(name >= 0);
+            const int name = i;
             if (fastTrack->mVolumeProvider != NULL) {
                 gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 930fa8d..235d23f 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -57,8 +57,6 @@
     static const FastMixerState sInitial;
 
     FastMixerState  mPreIdle;   // copy of state before we went into idle
-    int             mFastTrackNames[FastMixerState::kMaxFastTracks];
-                                // handles used by mixer to identify tracks
     int             mGenerations[FastMixerState::kMaxFastTracks];
                                 // last observed mFastTracks[i].mGeneration
     NBAIO_Sink*     mOutputSink;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 27c6d35..e5cb8a2 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -497,9 +497,6 @@
                                            patch->mPatchRecord->buffer(),
                                            patch->mPatchRecord->bufferSize(),
                                            AUDIO_OUTPUT_FLAG_NONE);
-    if (patch->mPatchTrack == 0) {
-        return NO_MEMORY;
-    }
     status = patch->mPatchTrack->initCheck();
     if (status != NO_ERROR) {
         return status;
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index e97bb06..6454be5 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -51,6 +51,11 @@
             void        flush();
             void        destroy();
             int         name() const { return mName; }
+            void        setName(int name) {
+                LOG_ALWAYS_FATAL_IF(mName >= 0 && name >= 0,
+                        "%s both old name %d and new name %d are valid", __func__, mName, name);
+                mName = name;
+            }
 
     virtual uint32_t    sampleRate() const;
 
@@ -146,10 +151,7 @@
 
     bool                mResetDone;
     const audio_stream_type_t mStreamType;
-    int                 mName;      // track name on the normal mixer,
-                                    // allocated statically at track creation time,
-                                    // and is even allocated (though unused) for fast tracks
-                                    // FIXME don't allocate track name for fast tracks
+    int                 mName;
     effect_buffer_t     *mMainBuffer;
 
     int32_t             *mAuxBuffer;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d6021b3..cae296e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1661,6 +1661,7 @@
         mSuspendedFrames(0),
         mActiveTracks(&this->mLocalLog),
         // mStreamTypes[] initialized in constructor body
+        mTracks(type == MIXER),
         mOutput(output),
         mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
         mMixerStatus(MIXER_IDLE),
@@ -2157,6 +2158,53 @@
     return track;
 }
 
+template<typename T>
+ssize_t AudioFlinger::PlaybackThread::Tracks<T>::add(const sp<T> &track)
+{
+    const ssize_t index = mTracks.add(track);
+    if (index >= 0) {
+        // set name for track when adding.
+        int name;
+        if (mUnusedTrackNames.empty()) {
+            name = mTracks.size() - 1; // new name {0 ... size-1}.
+        } else {
+            // reuse smallest name for deleted track.
+            auto it = mUnusedTrackNames.begin();
+            name = *it;
+            (void)mUnusedTrackNames.erase(it);
+        }
+        track->setName(name);
+    } else {
+        LOG_ALWAYS_FATAL("cannot add track");
+    }
+    return index;
+}
+
+template<typename T>
+ssize_t AudioFlinger::PlaybackThread::Tracks<T>::remove(const sp<T> &track)
+{
+    const int name = track->name();
+    const ssize_t index = mTracks.remove(track);
+    if (index >= 0) {
+        // invalidate name when removing from mTracks.
+        LOG_ALWAYS_FATAL_IF(name < 0, "invalid name %d for track on mTracks", name);
+
+        if (mSaveDeletedTrackNames) {
+            // We can't directly access mAudioMixer since the caller may be outside of threadLoop.
+            // Instead, we add to mDeletedTrackNames which is solely used for mAudioMixer update,
+            // to be handled when MixerThread::prepareTracks_l() next changes mAudioMixer.
+            mDeletedTrackNames.emplace(name);
+        }
+
+        mUnusedTrackNames.emplace(name);
+        track->setName(T::TRACK_NAME_PENDING);
+    } else {
+        LOG_ALWAYS_FATAL_IF(name >= 0,
+                "valid name %d for track not in mTracks (returned %zd)", name, index);
+    }
+    return index;
+}
+
 uint32_t AudioFlinger::PlaybackThread::correctLatency_l(uint32_t latency) const
 {
     return latency;
@@ -2313,9 +2361,6 @@
     mLocalLog.log("removeTrack_l (%p) %s", track.get(), result.string());
 
     mTracks.remove(track);
-    deleteTrackName_l(track->name());
-    // redundant as track is about to be destroyed, for dumpsys only
-    track->mName = -1;
     if (track->isFastTrack()) {
         int index = track->mFastIndex;
         ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
@@ -4111,6 +4156,14 @@
 AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTracks_l(
         Vector< sp<Track> > *tracksToRemove)
 {
+    // clean up deleted track names in AudioMixer before allocating new tracks
+    (void)mTracks.processDeletedTrackNames([this](int name) {
+        // for each name, destroy it in the AudioMixer
+        if (mAudioMixer->exists(name)) {
+            mAudioMixer->destroy(name);
+        }
+    });
+    mTracks.clearDeletedTrackNames();
 
     mixer_state mixerStatus = MIXER_IDLE;
     // find out which tracks need to be processed
@@ -4332,6 +4385,24 @@
         // The first time a track is added we wait
         // for all its buffers to be filled before processing it
         int name = track->name();
+
+        // if an active track doesn't exist in the AudioMixer, create it.
+        if (!mAudioMixer->exists(name)) {
+            status_t status = mAudioMixer->create(
+                    name,
+                    track->mChannelMask,
+                    track->mFormat,
+                    track->mSessionId);
+            if (status != OK) {
+                ALOGW("%s: cannot create track name"
+                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+                        __func__, name, track->mChannelMask, track->mFormat, track->mSessionId);
+                tracksToRemove->add(track);
+                track->invalidate(); // consider it dead.
+                continue;
+            }
+        }
+
         // make sure that we have enough frames to mix one full buffer.
         // enforce this condition only once to enable draining the buffer in case the client
         // app does not call stop() and relies on underrun to stop:
@@ -4357,20 +4428,9 @@
         size_t framesReady = track->framesReady();
         if (ATRACE_ENABLED()) {
             // I wish we had formatted trace names
-            char traceName[16];
-            strcpy(traceName, "nRdy");
-            int name = track->name();
-            if (AudioMixer::TRACK0 <= name &&
-                    name < (int) (AudioMixer::TRACK0 + AudioMixer::MAX_NUM_TRACKS)) {
-                name -= AudioMixer::TRACK0;
-                traceName[4] = (name / 10) + '0';
-                traceName[5] = (name % 10) + '0';
-            } else {
-                traceName[4] = '?';
-                traceName[5] = '?';
-            }
-            traceName[6] = '\0';
-            ATRACE_INT(traceName, framesReady);
+            std::string traceName("nRdy");
+            traceName += std::to_string(track->name());
+            ATRACE_INT(traceName.c_str(), framesReady);
         }
         if ((framesReady >= minFrames) && track->isReady() &&
                 !track->isPaused() && !track->isTerminated())
@@ -4736,7 +4796,7 @@
 }
 
 // trackCountForUid_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid)
+uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const
 {
     uint32_t trackCount = 0;
     for (size_t i = 0; i < mTracks.size() ; i++) {
@@ -4747,21 +4807,24 @@
     return trackCount;
 }
 
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask,
-        audio_format_t format, audio_session_t sessionId, uid_t uid)
+// isTrackAllowed_l() must be called with ThreadBase::mLock held
+bool AudioFlinger::MixerThread::isTrackAllowed_l(
+        audio_channel_mask_t channelMask, audio_format_t format,
+        audio_session_t sessionId, uid_t uid) const
 {
-    if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
-        return -1;
+    if (!PlaybackThread::isTrackAllowed_l(channelMask, format, sessionId, uid)) {
+        return false;
     }
-    return mAudioMixer->getTrackName(channelMask, format, sessionId);
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::MixerThread::deleteTrackName_l(int name)
-{
-    ALOGV("remove track (%d) and delete from mixer", name);
-    mAudioMixer->deleteTrackName(name);
+    // Check validity as we don't call AudioMixer::create() here.
+    if (!AudioMixer::isValidFormat(format)) {
+        ALOGW("%s: invalid format: %#x", __func__, format);
+        return false;
+    }
+    if (!AudioMixer::isValidChannelMask(channelMask)) {
+        ALOGW("%s: invalid channelMask: %#x", __func__, channelMask);
+        return false;
+    }
+    return true;
 }
 
 // checkForNewParameter_l() must be called with ThreadBase::mLock held
@@ -4854,13 +4917,18 @@
             readOutputParameters_l();
             delete mAudioMixer;
             mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);
-            for (size_t i = 0; i < mTracks.size() ; i++) {
-                int name = getTrackName_l(mTracks[i]->mChannelMask,
-                        mTracks[i]->mFormat, mTracks[i]->mSessionId, mTracks[i]->uid());
-                if (name < 0) {
-                    break;
-                }
-                mTracks[i]->mName = name;
+            for (const auto &track : mTracks) {
+                const int name = track->name();
+                status_t status = mAudioMixer->create(
+                        name,
+                        track->mChannelMask,
+                        track->mFormat,
+                        track->mSessionId);
+                ALOGW_IF(status != NO_ERROR,
+                        "%s: cannot create track name"
+                        " %d, mask %#x, format %#x, sessionId %d in AudioMixer",
+                        __func__,
+                        name, track->mChannelMask, track->mFormat, track->mSessionId);
             }
             sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
         }
@@ -5309,21 +5377,6 @@
     return !mStandby && !(trackPaused || (mHwPaused && !trackStopped));
 }
 
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::DirectOutputThread::getTrackName_l(audio_channel_mask_t channelMask __unused,
-        audio_format_t format __unused, audio_session_t sessionId __unused, uid_t uid)
-{
-    if (trackCountForUid_l(uid) > (PlaybackThread::kMaxTracksPerUid - 1)) {
-        return -1;
-    }
-    return 0;
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name __unused)
-{
-}
-
 // checkForNewParameter_l() must be called with ThreadBase::mLock held
 bool AudioFlinger::DirectOutputThread::checkForNewParameter_l(const String8& keyValuePair,
                                                               status_t& status)
@@ -5941,6 +5994,31 @@
     }
 }
 
+void AudioFlinger::DuplicatingThread::dumpInternals(int fd, const Vector<String16>& args __unused)
+{
+    MixerThread::dumpInternals(fd, args);
+
+    std::stringstream ss;
+    const size_t numTracks = mOutputTracks.size();
+    ss << "  " << numTracks << " OutputTracks";
+    if (numTracks > 0) {
+        ss << ":";
+        for (const auto &track : mOutputTracks) {
+            const sp<ThreadBase> thread = track->thread().promote();
+            ss << " (" << track->name() << " : ";
+            if (thread.get() != nullptr) {
+                ss << thread.get() << ", " << thread->id();
+            } else {
+                ss << "null";
+            }
+            ss << ")";
+        }
+    }
+    ss << "\n";
+    std::string result = ss.str();
+    write(fd, result.c_str(), result.size());
+}
+
 void AudioFlinger::DuplicatingThread::saveOutputTracks()
 {
     outputTracks = mOutputTracks;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 53cb8ad..ae14ac1 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -624,6 +624,7 @@
     static const int8_t kMaxTrackStartupRetriesOffload = 100;
     static const int8_t kMaxTrackStopRetriesOffload = 2;
     static constexpr uint32_t kMaxTracksPerUid = 40;
+    static constexpr size_t kMaxTracks = 256;
 
     // Maximum delay (in nanoseconds) for upcoming buffers in suspend mode, otherwise
     // if delay is greater, the estimated time for timeLoopNextNs is reset.
@@ -778,6 +779,16 @@
 
     virtual     bool        isOutput() const override { return true; }
 
+                // returns true if the track is allowed to be added to the thread.
+    virtual     bool        isTrackAllowed_l(
+                                    audio_channel_mask_t channelMask __unused,
+                                    audio_format_t format __unused,
+                                    audio_session_t sessionId __unused,
+                                    uid_t uid) const {
+                                return trackCountForUid_l(uid) < PlaybackThread::kMaxTracksPerUid
+                                       && mTracks.size() < PlaybackThread::kMaxTracks;
+                            }
+
 protected:
     // updated by readOutputParameters_l()
     size_t                          mNormalFrameCount;  // normal mixer and effects
@@ -866,12 +877,6 @@
 protected:
     ActiveTracks<Track>     mActiveTracks;
 
-    // Allocate a track name for a given channel mask.
-    //   Returns name >= 0 if successful, -1 on failure.
-    virtual int             getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
-                                           audio_session_t sessionId, uid_t uid) = 0;
-    virtual void            deleteTrackName_l(int name) = 0;
-
     // Time to sleep between cycles when:
     virtual uint32_t        activeSleepTimeUs() const;      // mixer state MIXER_TRACKS_ENABLED
     virtual uint32_t        idleSleepTimeUs() const = 0;    // mixer state MIXER_IDLE
@@ -899,7 +904,7 @@
                                     && mHwSupportsPause
                                     && (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
 
-                uint32_t    trackCountForUid_l(uid_t uid);
+                uint32_t    trackCountForUid_l(uid_t uid) const;
 
 private:
 
@@ -916,7 +921,64 @@
     virtual void dumpInternals(int fd, const Vector<String16>& args);
     void        dumpTracks(int fd, const Vector<String16>& args);
 
-    SortedVector< sp<Track> >       mTracks;
+    // The Tracks class manages names for all tracks
+    // added and removed from the Thread.
+    template <typename T>
+    class Tracks {
+    public:
+        Tracks(bool saveDeletedTrackNames) :
+            mSaveDeletedTrackNames(saveDeletedTrackNames) { }
+
+        // SortedVector methods
+        ssize_t         add(const sp<T> &track);
+        ssize_t         remove(const sp<T> &track);
+        size_t          size() const {
+            return mTracks.size();
+        }
+        bool            isEmpty() const {
+            return mTracks.isEmpty();
+        }
+        ssize_t         indexOf(const sp<T> &item) {
+            return mTracks.indexOf(item);
+        }
+        sp<T>           operator[](size_t index) const {
+            return mTracks[index];
+        }
+        typename SortedVector<sp<T>>::iterator begin() {
+            return mTracks.begin();
+        }
+        typename SortedVector<sp<T>>::iterator end() {
+            return mTracks.end();
+        }
+
+        size_t          processDeletedTrackNames(std::function<void(int)> f) {
+            const size_t size = mDeletedTrackNames.size();
+            if (size > 0) {
+                for (const int name : mDeletedTrackNames) {
+                    f(name);
+                }
+            }
+            return size;
+        }
+
+        void            clearDeletedTrackNames() { mDeletedTrackNames.clear(); }
+
+    private:
+        // Track names pending deletion for MIXER type threads
+        const bool mSaveDeletedTrackNames; // true to enable tracking
+        std::set<int> mDeletedTrackNames;
+
+        // Fast lookup of previously deleted track names for reuse.
+        // This is an arbitrary decision (actually any non-negative
+        // integer that isn't in mTracks[*]->names() could be used) - we attempt
+        // to use the smallest possible available name.
+        std::set<int> mUnusedTrackNames;
+
+        SortedVector<sp<T>> mTracks; // wrapped SortedVector.
+    };
+
+    Tracks<Track>                   mTracks;
+
     stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT];
     AudioStreamOut                  *mOutput;
 
@@ -1023,11 +1085,11 @@
                                                    status_t& status);
     virtual     void        dumpInternals(int fd, const Vector<String16>& args);
 
+    virtual     bool        isTrackAllowed_l(
+                                    audio_channel_mask_t channelMask, audio_format_t format,
+                                    audio_session_t sessionId, uid_t uid) const override;
 protected:
     virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
-                                           audio_session_t sessionId, uid_t uid);
-    virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
     virtual     void        cacheParameters_l();
@@ -1105,9 +1167,6 @@
     virtual     void        flushHw_l();
 
 protected:
-    virtual     int         getTrackName_l(audio_channel_mask_t channelMask, audio_format_t format,
-                                           audio_session_t sessionId, uid_t uid);
-    virtual     void        deleteTrackName_l(int name);
     virtual     uint32_t    activeSleepTimeUs() const;
     virtual     uint32_t    idleSleepTimeUs() const;
     virtual     uint32_t    suspendSleepTimeUs() const;
@@ -1211,6 +1270,8 @@
     virtual                 ~DuplicatingThread();
 
     // Thread virtuals
+    virtual     void        dumpInternals(int fd, const Vector<String16>& args) override;
+
                 void        addOutputTrack(MixerThread* thread);
                 void        removeOutputTrack(MixerThread* thread);
                 uint32_t    waitTimeMs() const { return mWaitTimeMs; }
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a3ea756..a7e966f 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -54,6 +54,11 @@
         TYPE_PATCH,
     };
 
+    enum {
+        TRACK_NAME_PENDING = -1,
+        TRACK_NAME_FAILURE = -2,
+    };
+
                         TrackBase(ThreadBase *thread,
                                 const sp<Client>& client,
                                 uint32_t sampleRate,
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 67f27d0..9b93939 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -394,7 +394,7 @@
     // mRetryCount initialized later when needed
     mSharedBuffer(sharedBuffer),
     mStreamType(streamType),
-    mName(-1),  // see note below
+    mName(TRACK_NAME_FAILURE),  // set to TRACK_NAME_PENDING on constructor success.
     mMainBuffer(thread->sinkBuffer()),
     mAuxBuffer(NULL),
     mAuxEffectId(0), mHasVolumeController(false),
@@ -427,9 +427,8 @@
     }
     mServerProxy = mAudioTrackServerProxy;
 
-    mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
-    if (mName < 0) {
-        ALOGE("no more track names available");
+    if (!thread->isTrackAllowed_l(channelMask, format, sessionId, uid)) {
+        ALOGE("no more tracks available");
         return;
     }
     // only allocate a fast track index if we were able to allocate a normal track name
@@ -448,6 +447,7 @@
         mFastIndex = i;
         thread->mFastTrackAvailMask &= ~(1 << i);
     }
+    mName = TRACK_NAME_PENDING;
 }
 
 AudioFlinger::PlaybackThread::Track::~Track()
@@ -466,7 +466,7 @@
 status_t AudioFlinger::PlaybackThread::Track::initCheck() const
 {
     status_t status = TrackBase::initCheck();
-    if (status == NO_ERROR && mName < 0) {
+    if (status == NO_ERROR && mName == TRACK_NAME_FAILURE) {
         status = NO_MEMORY;
     }
     return status;
@@ -527,10 +527,12 @@
 
     if (isFastTrack()) {
         result.appendFormat("F%c %3d", trackType, mFastIndex);
-    } else if (mName >= AudioMixer::TRACK0) {
-        result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
+    } else if (mName == TRACK_NAME_PENDING) {
+        result.appendFormat("%c pend", trackType);
+    } else if (mName == TRACK_NAME_FAILURE) {
+        result.appendFormat("%c fail", trackType);
     } else {
-        result.appendFormat("%c none", trackType);
+        result.appendFormat("%c %4d", trackType, mName);
     }
 
     char nowInUnderrun;