Merge "audio policy: fix delayed command insertion"
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e5a60f5..74438ee 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -367,7 +367,6 @@
 void AudioTrack::start()
 {
     sp<AudioTrackThread> t = mAudioTrackThread;
-    status_t status = NO_ERROR;
 
     ALOGV("start %p", this);
 
@@ -395,6 +394,7 @@
         }
 
         ALOGV("start %p before lock cblk %p", this, mCblk);
+        status_t status = NO_ERROR;
         if (!(cblk->flags & CBLK_INVALID_MSK)) {
             cblk->lock.unlock();
             ALOGV("mAudioTrack->start()");
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 8473fab..c2d2790 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -89,7 +89,7 @@
 
 LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"'
 
-LOCAL_CFLAGS += -DHAVE_REQUEST_PRIORITY -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE -USOAKER
+LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
 
 # uncomment for systrace
 # LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 65255ba..ad0a533 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -83,13 +83,7 @@
 #include "PipeReader.h"
 #include "SourceAudioBufferProvider.h"
 
-#ifdef HAVE_REQUEST_PRIORITY
 #include "SchedulingPolicyService.h"
-#endif
-
-#ifdef SOAKER
-#include "Soaker.h"
-#endif
 
 // ----------------------------------------------------------------------------
 
@@ -216,8 +210,9 @@
 AudioFlinger::AudioFlinger()
     : BnAudioFlinger(),
       mPrimaryHardwareDev(NULL),
-      mHardwareStatus(AUDIO_HW_IDLE), // see also onFirstRef()
+      mHardwareStatus(AUDIO_HW_IDLE),
       mMasterVolume(1.0f),
+      mMasterVolumeSW(1.0f),
       mMasterVolumeSupportLvl(MVS_NONE),
       mMasterMute(false),
       mNextUniqueId(1),
@@ -247,9 +242,6 @@
     }
 
     mMode = AUDIO_MODE_NORMAL;
-    mMasterVolumeSW = 1.0;
-    mMasterVolume   = 1.0;
-    mHardwareStatus = AUDIO_HW_IDLE;
 }
 
 AudioFlinger::~AudioFlinger()
@@ -1133,8 +1125,7 @@
         mChannelCount(0),
         mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
         mParamStatus(NO_ERROR),
-        mStandby(false), mId(id),
-        mDevice(device),
+        mStandby(false), mDevice((audio_devices_t) device), mId(id),
         mDeathRecipient(new PMDeathRecipient(this))
 {
 }
@@ -1805,7 +1796,6 @@
         }
     }
 
-#ifdef HAVE_REQUEST_PRIORITY
     if ((flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
         pid_t callingPid = IPCThreadState::self()->getCallingPid();
         // we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful,
@@ -1816,7 +1806,6 @@
                     1, callingPid, tid, err);
         }
     }
-#endif
 
     lStatus = NO_ERROR;
 
@@ -2196,9 +2185,6 @@
         audio_io_handle_t id, uint32_t device, type_t type)
     :   PlaybackThread(audioFlinger, output, id, device, type),
         // mAudioMixer below
-#ifdef SOAKER
-        mSoaker(NULL),
-#endif
         // mFastMixer below
         mFastMixerFutex(0)
         // mOutputSink below
@@ -2268,13 +2254,6 @@
         mTeeSource = teeSource;
 #endif
 
-#ifdef SOAKER
-        // create a soaker as workaround for governor issues
-        mSoaker = new Soaker();
-        // FIXME Soaker should only run when needed, i.e. when FastMixer is not in COLD_IDLE
-        mSoaker->run("Soaker", PRIORITY_LOWEST);
-#endif
-
         // create fast mixer and configure it initially with just one fast track for our submix
         mFastMixer = new FastMixer();
         FastMixerStateQueue *sq = mFastMixer->sq();
@@ -2306,14 +2285,12 @@
 
         // start the fast mixer
         mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);
-#ifdef HAVE_REQUEST_PRIORITY
         pid_t tid = mFastMixer->getTid();
         int err = requestPriority(getpid_cached, tid, 2);
         if (err != 0) {
             ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",
                     2, getpid_cached, tid, err);
         }
-#endif
 
 #ifdef AUDIO_WATCHDOG
         // create and start the watchdog
@@ -2371,12 +2348,6 @@
         delete fastTrack->mBufferProvider;
         sq->end(false /*didModify*/);
         delete mFastMixer;
-#ifdef SOAKER
-        if (mSoaker != NULL) {
-            mSoaker->requestExitAndWait();
-        }
-        delete mSoaker;
-#endif
         if (mAudioWatchdog != 0) {
             mAudioWatchdog->requestExit();
             mAudioWatchdog->requestExitAndWait();
@@ -2517,9 +2488,9 @@
     cacheParameters_l();
     sleepTime = idleSleepTime;
 
-if (mType == MIXER) {
-    sleepTimeShift = 0;
-}
+    if (mType == MIXER) {
+        sleepTimeShift = 0;
+    }
 
     CpuStats cpuStats;
     const String8 myName(String8::format("thread %p type %d TID %d", this, mType, gettid()));
@@ -2660,15 +2631,13 @@
         // is now local to this block, but will keep it for now (at least until merge done).
     }
 
-if (mType == MIXER || mType == DIRECT) {
-    // put output stream into standby mode
-    if (!mStandby) {
-        mOutput->stream->common.standby(&mOutput->stream->common);
+    // for DuplicatingThread, standby mode is handled by the outputTracks, otherwise ...
+    if (mType == MIXER || mType == DIRECT) {
+        // put output stream into standby mode
+        if (!mStandby) {
+            mOutput->stream->common.standby(&mOutput->stream->common);
+        }
     }
-}
-if (mType == DUPLICATING) {
-    // for DuplicatingThread, standby mode is handled by the outputTracks
-}
 
     releaseWakeLock();
 
@@ -3474,7 +3443,7 @@
 
             // forward device change to effects that have requested to be
             // aware of attached audio device.
-            mDevice = (uint32_t)value;
+            mDevice = (audio_devices_t) value;
             for (size_t i = 0; i < mEffectChains.size(); i++) {
                 mEffectChains[i]->setDevice_l(mDevice);
             }
@@ -4062,6 +4031,7 @@
             return false;
         }
         PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+        // see note at standby() declaration
         if (playbackThread->standby() && !playbackThread->isSuspended()) {
             ALOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
             return false;
@@ -4488,8 +4458,6 @@
         }
 
         buffer->raw = getBuffer(s, framesReq);
-        if (buffer->raw == NULL) goto getNextBuffer_exit;
-
         buffer->frameCount = framesReq;
         return NO_ERROR;
     }
@@ -5381,8 +5349,6 @@
         }
 
         buffer->raw = getBuffer(s, framesReq);
-        if (buffer->raw == NULL) goto getNextBuffer_exit;
-
         buffer->frameCount = framesReq;
         return NO_ERROR;
     }
@@ -6500,11 +6466,12 @@
             // store input device and output device but do not forward output device to audio HAL.
             // Note that status is ignored by the caller for output device
             // (see AudioFlinger::setParameters()
+            uint32_t /*audio_devices_t*/ newDevice = mDevice;
             if (value & AUDIO_DEVICE_OUT_ALL) {
-                mDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
                 status = BAD_VALUE;
             } else {
-                mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
                 // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
                 if (mTrack != NULL) {
                     bool suspend = audio_is_bluetooth_sco_device(
@@ -6513,7 +6480,8 @@
                     setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
                 }
             }
-            mDevice |= (uint32_t)value;
+            newDevice |= value;
+            mDevice = (audio_devices_t) newDevice;    // since mDevice is read by other threads, only write to it once
         }
         if (status == NO_ERROR) {
             status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index cd157ec..08c727d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -417,6 +417,13 @@
 
             int sampleRate() const; // FIXME inline after cblk sr moved
 
+            // Return a pointer to the start of a contiguous slice of the track buffer.
+            // Parameter 'offset' is the requested start position, expressed in
+            // monotonically increasing frame units relative to the track epoch.
+            // Parameter 'frames' is the requested length, also in frame units.
+            // Always returns non-NULL.  It is the caller's responsibility to
+            // verify that this will be successful; the result of calling this
+            // function with invalid 'offset' or 'frames' is undefined.
             void* getBuffer(uint32_t offset, uint32_t frames) const;
 
             bool isStopped() const {
@@ -484,13 +491,19 @@
         };
 
         virtual     status_t    initCheck() const = 0;
+
+                    // static externally-visible
                     type_t      type() const { return mType; }
+                    audio_io_handle_t id() const { return mId;}
+
+                    // dynamic externally-visible
                     uint32_t    sampleRate() const { return mSampleRate; }
                     int         channelCount() const { return mChannelCount; }
                     audio_format_t format() const { return mFormat; }
                     // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
                     // and returns the normal mix buffer's frame count.  No API for HAL frame count.
                     size_t      frameCount() const { return mNormalFrameCount; }
+
                     void        wakeUp()    { mWaitWorkCV.broadcast(); }
         // Should be "virtual status_t requestExitAndWait()" and override same
         // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
@@ -502,9 +515,11 @@
                     void        sendConfigEvent(int event, int param = 0);
                     void        sendConfigEvent_l(int event, int param = 0);
                     void        processConfigEvents();
-                    audio_io_handle_t id() const { return mId;}
+
+                    // see note at declaration of mStandby and mDevice
                     bool        standby() const { return mStandby; }
-                    uint32_t    device() const { return mDevice; }
+                    audio_devices_t device() const { return mDevice; }
+
         virtual     audio_stream_t* stream() const = 0;
 
                     sp<EffectHandle> createEffect_l(
@@ -647,11 +662,19 @@
                     status_t                mParamStatus;
 
                     Vector<ConfigEvent>     mConfigEvents;
-                    bool                    mStandby;
+
+                    // These fields are written and read by thread itself without lock or barrier,
+                    // and read by other threads without lock or barrier via standby() and device().
+                    // Because of the absence of a lock or barrier, any other thread that reads
+                    // these fields must use the information in isolation, or be prepared to deal
+                    // with possibility that it might be inconsistent with other information.
+                    bool                    mStandby;   // Whether thread is currently in standby.
+                    audio_devices_t         mDevice;    // output device for PlaybackThread
+                                                        // input + output devices for RecordThread
+
                     const audio_io_handle_t mId;
                     Vector< sp<EffectChain> > mEffectChains;
-                    uint32_t                mDevice;    // output device for PlaybackThread
-                                                        // input + output devices for RecordThread
+
                     static const int        kNameLength = 16;   // prctl(PR_SET_NAME) limit
                     char                    mName[kNameLength];
                     sp<IPowerManager>       mPowerManager;
@@ -709,9 +732,7 @@
                     void        flush();
                     void        destroy();
                     void        mute(bool);
-                    int name() const {
-                        return mName;
-                    }
+                    int         name() const { return mName; }
 
                     audio_stream_type_t streamType() const {
                         return mStreamType;
@@ -768,10 +789,14 @@
             void triggerEvents(AudioSystem::sync_event_t type);
             virtual bool isTimedTrack() const { return false; }
             bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
+
         protected:
 
-            // we don't really need a lock for these
-            volatile bool       mMute;
+            // written by Track::mute() called by binder thread(s), without a mutex or barrier.
+            // read by Track::isMuted() called by playback thread, also without a mutex or barrier.
+            // The lack of mutex or barrier is safe because the mute status is only used by itself.
+            bool                mMute;
+
             // FILLED state is used for suppressing volume ramp at begin of playing
             enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE};
             mutable uint8_t     mFillingUpStatus;
@@ -1079,6 +1104,7 @@
         // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by DuplicatingThread
         stream_type_t                   mStreamTypes[AUDIO_STREAM_CNT + 1];
         AudioStreamOut                  *mOutput;
+
         float                           mMasterVolume;
         nsecs_t                         mLastWriteTime;
         int                             mNumWrites;
@@ -1168,9 +1194,6 @@
 
                     AudioMixer* mAudioMixer;    // normal mixer
     private:
-#ifdef SOAKER
-                    Thread*     mSoaker;
-#endif
                     // one-time initialization, no locks required
                     FastMixer*  mFastMixer;         // non-NULL if there is also a fast mixer
                     sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
@@ -1712,12 +1735,12 @@
 
         void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
         void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
-        int32_t trackCnt() const { return mTrackCnt;}
+        int32_t trackCnt() const { return android_atomic_acquire_load(&mTrackCnt); }
 
         void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt);
                                    mTailBufferCount = mMaxTailBuffers; }
         void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
-        int32_t activeTrackCnt() const { return mActiveTrackCnt;}
+        int32_t activeTrackCnt() const { return android_atomic_acquire_load(&mActiveTrackCnt); }
 
         uint32_t strategy() const { return mStrategy; }
         void setStrategy(uint32_t strategy)
@@ -1769,8 +1792,11 @@
         int mSessionId;             // audio session ID
         int16_t *mInBuffer;         // chain input buffer
         int16_t *mOutBuffer;        // chain output buffer
-        volatile int32_t mActiveTrackCnt;  // number of active tracks connected
-        volatile int32_t mTrackCnt;        // number of tracks connected
+
+        // 'volatile' here means these are accessed with atomic operations instead of mutex
+        volatile int32_t mActiveTrackCnt;    // number of active tracks connected
+        volatile int32_t mTrackCnt;          // number of tracks connected
+
         int32_t mTailBufferCount;   // current effect tail buffer count
         int32_t mMaxTailBuffers;    // maximum effect tail buffers
         bool mOwnInBuffer;          // true if the chain owns its input buffer
diff --git a/services/audioflinger/Soaker.h b/services/audioflinger/Soaker.h
deleted file mode 100644
index 43d9d2f..0000000
--- a/services/audioflinger/Soaker.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_AUDIO_SOAKER_H
-#define _ANDROID_AUDIO_SOAKER_H
-
-#include <utils/Thread.h>
-
-namespace android {
-
-class Soaker : public Thread {
-public:
-    Soaker() : Thread() { }
-    virtual ~Soaker() { }
-protected:
-    virtual bool threadLoop() {
-        int j = 0;
-        for (;;) {
-            for (int i = 0; i < 10000; ++i) {
-                j += i * i;
-            }
-            if (exitPending()) {
-                return false;
-            }
-        }
-        return j < 555555;
-    }
-};
-
-}   // namespace android
-
-#endif  // _ANDROID_AUDIO_SOAKER_H