Merge "AudioRecord locking"
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index cc18a1d..163205e 100755
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -42,6 +42,7 @@
 
 namespace android {
 
+static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
 static const int64_t kMax32BitFileSize = 0x007fffffffLL;
 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
 static const uint8_t kNalUnitTypePicParamSet = 0x08;
@@ -487,8 +488,16 @@
     CHECK_GT(mTimeScale, 0);
     ALOGV("movie time scale: %d", mTimeScale);
 
-    mStreamableFile = true;
-    mWriteMoovBoxToMemory = false;
+    /*
+     * When the requested file size limit is small, the priority
+     * is to meet the file size limit requirement, rather than
+     * to make the file streamable.
+     */
+    mStreamableFile =
+        (mMaxFileSizeLimitBytes != 0 &&
+         mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
+
+    mWriteMoovBoxToMemory = mStreamableFile;
     mMoovBoxBuffer = NULL;
     mMoovBoxBufferOffset = 0;
 
@@ -504,11 +513,16 @@
         mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
     }
     CHECK_GE(mEstimatedMoovBoxSize, 8);
-    lseek64(mFd, mFreeBoxOffset, SEEK_SET);
-    writeInt32(mEstimatedMoovBoxSize);
-    write("free", 4);
+    if (mStreamableFile) {
+        // Reserve a 'free' box only for streamable file
+        lseek64(mFd, mFreeBoxOffset, SEEK_SET);
+        writeInt32(mEstimatedMoovBoxSize);
+        write("free", 4);
+        mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
+    } else {
+        mMdatOffset = mOffset;
+    }
 
-    mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
     mOffset = mMdatOffset;
     lseek64(mFd, mMdatOffset, SEEK_SET);
     if (mUse32BitOffset) {
@@ -689,7 +703,7 @@
     lseek64(mFd, mOffset, SEEK_SET);
 
     const off64_t moovOffset = mOffset;
-    mWriteMoovBoxToMemory = true;
+    mWriteMoovBoxToMemory = mStreamableFile;
     mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
     mMoovBoxBufferOffset = 0;
     CHECK(mMoovBoxBuffer != NULL);
@@ -1062,6 +1076,10 @@
         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
     }
 
+    if (!mStreamableFile) {
+        // Add 1024 bytes as error tolerance
+        return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes;
+    }
     // Be conservative in the estimate: do not exceed 95% of
     // the target file limit. For small target file size limit, though,
     // this will not help.
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f033080..b2aa388 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -273,7 +273,7 @@
 };
 #define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
 
-audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices)
+audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module, audio_devices_t devices)
 {
     // if module is 0, the request comes from an old policy manager and we should load
     // well known modules
@@ -873,8 +873,7 @@
                     sp<RecordThread> thread = mRecordThreads.valueAt(i);
                     RecordThread::RecordTrack *track = thread->track();
                     if (track != NULL) {
-                        audio_devices_t device = (audio_devices_t)(
-                                thread->device() & AUDIO_DEVICE_IN_ALL);
+                        audio_devices_t device = thread->device() & AUDIO_DEVICE_IN_ALL;
                         bool suspend = audio_is_bluetooth_sco_device(device) && btNrecIsOff;
                         thread->setEffectSuspended(FX_IID_AEC,
                                                    suspend,
@@ -1116,7 +1115,7 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
-        uint32_t device, type_t type)
+        audio_devices_t device, type_t type)
     :   Thread(false),
         mType(type),
         mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0),
@@ -1124,7 +1123,7 @@
         mChannelCount(0),
         mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
         mParamStatus(NO_ERROR),
-        mStandby(false), mDevice((audio_devices_t) device), mId(id),
+        mStandby(false), mDevice(device), mId(id),
         mDeathRecipient(new PMDeathRecipient(this))
 {
 }
@@ -1500,7 +1499,7 @@
 AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
                                              AudioStreamOut* output,
                                              audio_io_handle_t id,
-                                             uint32_t device,
+                                             audio_devices_t device,
                                              type_t type)
     :   ThreadBase(audioFlinger, id, device, type),
         mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
@@ -2181,7 +2180,7 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-        audio_io_handle_t id, uint32_t device, type_t type)
+        audio_io_handle_t id, audio_devices_t device, type_t type)
     :   PlaybackThread(audioFlinger, output, id, device, type),
         // mAudioMixer below
         // mFastMixer below
@@ -2190,7 +2189,7 @@
         // mPipeSink below
         // mNormalSink below
 {
-    ALOGV("MixerThread() id=%d device=%d type=%d", id, device, type);
+    ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);
     ALOGV("mSampleRate=%d, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%d, "
             "mFrameCount=%d, mNormalFrameCount=%d",
             mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,
@@ -3420,14 +3419,14 @@
 #ifdef ADD_BATTERY_DATA
             // when changing the audio output device, call addBatteryData to notify
             // the change
-            if ((int)mDevice != value) {
+            if (mDevice != value) {
                 uint32_t params = 0;
                 // check whether speaker is on
                 if (value & AUDIO_DEVICE_OUT_SPEAKER) {
                     params |= IMediaPlayerService::kBatteryDataSpeakerOn;
                 }
 
-                int deviceWithoutSpeaker
+                audio_devices_t deviceWithoutSpeaker
                     = AUDIO_DEVICE_OUT_ALL & ~AUDIO_DEVICE_OUT_SPEAKER;
                 // check if any other device (except speaker) is on
                 if (value & deviceWithoutSpeaker ) {
@@ -3442,7 +3441,7 @@
 
             // forward device change to effects that have requested to be
             // aware of attached audio device.
-            mDevice = (audio_devices_t) value;
+            mDevice = value;
             for (size_t i = 0; i < mEffectChains.size(); i++) {
                 mEffectChains[i]->setDevice_l(mDevice);
             }
@@ -3611,7 +3610,7 @@
 
 // ----------------------------------------------------------------------------
 AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
-        AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
+        AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device)
     :   PlaybackThread(audioFlinger, output, id, device, DIRECT)
         // mLeftVolFloat, mRightVolFloat
 {
@@ -5900,7 +5899,7 @@
                                          uint32_t sampleRate,
                                          audio_channel_mask_t channelMask,
                                          audio_io_handle_t id,
-                                         uint32_t device) :
+                                         audio_devices_t device) :
     ThreadBase(audioFlinger, id, device, RECORD),
     mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL),
     // mRsmpInIndex and mInputBytes set by readInputParameters()
@@ -6179,8 +6178,8 @@
 
         mTrack = track.get();
         // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
-        bool suspend = audio_is_bluetooth_sco_device(
-                (audio_devices_t)(mDevice & AUDIO_DEVICE_IN_ALL)) && mAudioFlinger->btNrecIsOff();
+        bool suspend = audio_is_bluetooth_sco_device(mDevice & AUDIO_DEVICE_IN_ALL) &&
+                        mAudioFlinger->btNrecIsOff();
         setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
         setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
     }
@@ -6469,12 +6468,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;
+            audio_devices_t newDevice = mDevice;
             if (value & AUDIO_DEVICE_OUT_ALL) {
-                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+                newDevice &= ~(value & AUDIO_DEVICE_OUT_ALL);
                 status = BAD_VALUE;
             } else {
-                newDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+                newDevice &= ~(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(
@@ -6484,7 +6483,7 @@
                 }
             }
             newDevice |= value;
-            mDevice = (audio_devices_t) newDevice;    // since mDevice is read by other threads, only write to it once
+            mDevice = 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());
@@ -6725,7 +6724,7 @@
 
     ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
               module,
-              (pDevices != NULL) ? (int)*pDevices : 0,
+              (pDevices != NULL) ? *pDevices : 0,
               config.sample_rate,
               config.format,
               config.channel_mask,
@@ -6985,7 +6984,7 @@
         // Start record thread
         // RecorThread require both input and output device indication to forward to audio
         // pre processing modules
-        uint32_t device = (*pDevices) | primaryOutputDevice_l();
+        audio_devices_t device = (*pDevices) | primaryOutputDevice_l();
         thread = new RecordThread(this,
                                   input,
                                   reqSamplingRate,
@@ -7195,7 +7194,7 @@
     return NULL;
 }
 
-uint32_t AudioFlinger::primaryOutputDevice_l() const
+audio_devices_t AudioFlinger::primaryOutputDevice_l() const
 {
     PlaybackThread *thread = primaryPlaybackThread_l();
 
@@ -8534,14 +8533,14 @@
     return status;
 }
 
-status_t AudioFlinger::EffectModule::setDevice(uint32_t device)
+status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
 {
     Mutex::Autolock _l(mLock);
     status_t status = NO_ERROR;
     if (device && (mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
         // audio pre processing modules on RecordThread can receive both output and
         // input device indication in the same call
-        uint32_t dev = device & AUDIO_DEVICE_OUT_ALL;
+        audio_devices_t dev = device & AUDIO_DEVICE_OUT_ALL;
         if (dev) {
             status_t cmdStatus;
             uint32_t size = sizeof(status_t);
@@ -9258,7 +9257,7 @@
 }
 
 // setDevice_l() must be called with PlaybackThread::mLock held
-void AudioFlinger::EffectChain::setDevice_l(uint32_t device)
+void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
 {
     size_t size = mEffects.size();
     for (size_t i = 0; i < size; i++) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index fa1ad93..c6f08cd 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -270,7 +270,7 @@
     // RefBase
     virtual     void        onFirstRef();
 
-    audio_hw_device_t*      findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices);
+    audio_hw_device_t*      findSuitableHwDev_l(audio_module_handle_t module, audio_devices_t devices);
     void                    purgeStaleEffects_l();
 
     // standby delay for MIXER and DUPLICATING playback threads is read from property
@@ -352,7 +352,7 @@
             RECORD              // Thread class is RecordThread
         };
 
-        ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, uint32_t device, type_t type);
+        ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, audio_devices_t device, type_t type);
         virtual             ~ThreadBase();
 
         status_t dumpBase(int fd, const Vector<String16>& args);
@@ -963,7 +963,7 @@
         };  // end of OutputTrack
 
         PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-                        audio_io_handle_t id, uint32_t device, type_t type);
+                        audio_io_handle_t id, audio_devices_t device, type_t type);
         virtual             ~PlaybackThread();
 
                     status_t    dump(int fd, const Vector<String16>& args);
@@ -1185,7 +1185,7 @@
         MixerThread (const sp<AudioFlinger>& audioFlinger,
                      AudioStreamOut* output,
                      audio_io_handle_t id,
-                     uint32_t device,
+                     audio_devices_t device,
                      type_t type = MIXER);
         virtual             ~MixerThread();
 
@@ -1240,7 +1240,7 @@
     public:
 
         DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
-                            audio_io_handle_t id, uint32_t device);
+                            audio_io_handle_t id, audio_devices_t device);
         virtual                 ~DirectOutputThread();
 
         // Thread virtuals
@@ -1329,7 +1329,7 @@
                                      bool reRegister);
               // return thread associated with primary hardware device, or NULL
               PlaybackThread *primaryPlaybackThread_l() const;
-              uint32_t primaryOutputDevice_l() const;
+              audio_devices_t primaryOutputDevice_l() const;
 
               sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
 
@@ -1407,7 +1407,7 @@
                         uint32_t sampleRate,
                         audio_channel_mask_t channelMask,
                         audio_io_handle_t id,
-                        uint32_t device);
+                        audio_devices_t device);
                 virtual     ~RecordThread();
 
         // Thread
@@ -1575,7 +1575,7 @@
         effect_descriptor_t& desc() { return mDescriptor; }
         wp<EffectChain>&     chain() { return mChain; }
 
-        status_t         setDevice(uint32_t device);
+        status_t         setDevice(audio_devices_t device);
         status_t         setVolume(uint32_t *left, uint32_t *right, bool controller);
         status_t         setMode(audio_mode_t mode);
         status_t         start();
@@ -1738,7 +1738,7 @@
         sp<EffectModule> getEffectFromId_l(int id);
         sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
         bool setVolume_l(uint32_t *left, uint32_t *right);
-        void setDevice_l(uint32_t device);
+        void setDevice_l(audio_devices_t device);
         void setMode_l(audio_mode_t mode);
 
         void setInBuffer(int16_t *buffer, bool ownsBuffer = false) {