Merge "MPEG4Writer: Enforce CSD size check only for MPEG-4 audio/video" into nyc-mr1-dev
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index c41c686..75515ac 100644
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -195,6 +195,11 @@
         TONE_JAPAN_RADIO_ACK,       // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
         // UK Supervisory tones
         TONE_UK_RINGTONE,           // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
+        // AUSTRALIA Supervisory tones
+        TONE_AUSTRALIA_RINGTONE,    // Ring tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
+        TONE_AUSTRALIA_BUSY,        // Busy tone: 425 Hz repeated in a 0.375s on, 0.375s off pattern.
+        TONE_AUSTRALIA_CALL_WAITING,// Call waiting tone: 425Hz tone repeated in a 0.2s on, 0.2s off, 0.2s on, 4.4s off pattern.
+        TONE_AUSTRALIA_CONGESTION,  // Congestion tone: 425Hz tone repeated in a 0.375s on, 0.375s off pattern
         NUM_ALTERNATE_TONES
     };
 
@@ -202,6 +207,7 @@
         ANSI,
         JAPAN,
         UK,
+        AUSTRALIA,
         CEPT,
         NUM_REGIONS
     };
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index ffe896e..2f53637 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -747,9 +747,30 @@
                         { .duration = 0, .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                              // TONE_UK_RINGTONE
-
-
-
+        { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
+                        { .duration = 2000, .waveFreq = { 0 }, 0, 0},
+                        { .duration = 0, .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_AUSTRALIA_RINGTONE
+        { .segments = { { .duration = 375, .waveFreq = { 425, 0 }, 0, 0 },
+                        { .duration = 375, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_AUSTRALIA_BUSY
+        { .segments = { { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 425, 0 }, 0, 0 },
+                        { .duration = 4400, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_AUSTRALIA_CALL_WAITING
+        { .segments = { { .duration = 375, .waveFreq = { 425, 0 }, 0, 0 },
+                        { .duration = 375, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_AUSTRALIA_CONGESTION
 };
 
 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
@@ -784,8 +805,17 @@
             TONE_SUP_ERROR,              // TONE_SUP_ERROR
             TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
             TONE_UK_RINGTONE             // TONE_SUP_RINGTONE
+        },
+        {   // AUSTRALIA
+            TONE_ANSI_DIAL,             // TONE_SUP_DIAL
+            TONE_AUSTRALIA_BUSY,        // TONE_SUP_BUSY
+            TONE_AUSTRALIA_CONGESTION,  // TONE_SUP_CONGESTION
+            TONE_SUP_RADIO_ACK,         // TONE_SUP_RADIO_ACK
+            TONE_SUP_RADIO_NOTAVAIL,    // TONE_SUP_RADIO_NOTAVAIL
+            TONE_SUP_ERROR,             // TONE_SUP_ERROR
+            TONE_AUSTRALIA_CALL_WAITING,// TONE_SUP_CALL_WAITING
+            TONE_AUSTRALIA_RINGTONE     // TONE_SUP_RINGTONE
         }
-
 };
 
 
@@ -841,6 +871,8 @@
         mRegion = JAPAN;
     } else if (strstr(value, "uk") != NULL) {
         mRegion = UK;
+    } else if (strstr(value, "au") != NULL) {
+        mRegion = AUSTRALIA;
     } else {
         mRegion = CEPT;
     }
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d790821..3cfed5e 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1938,6 +1938,7 @@
                     continue;
                 }
                 callbackData->mSwitching = true; // begin track switch
+                callbackData->setOutput(NULL);
 #else
                 // tryBeginTrackSwitch() returns false if the callback has the lock.
                 if (!mCallbackData->tryBeginTrackSwitch()) {
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index c9c49f5..eb1f193 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <limits>
+
 #include "include/SampleTable.h"
 #include "include/SampleIterator.h"
 
@@ -45,6 +47,8 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+const off64_t kMaxOffset = std::numeric_limits<off64_t>::max();
+
 struct SampleTable::CompositionDeltaLookup {
     CompositionDeltaLookup();
 
@@ -233,11 +237,11 @@
 
     mNumSampleToChunkOffsets = U32_AT(&header[4]);
 
-    if ((data_size - 8) / 12 < mNumSampleToChunkOffsets) {
+    if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) {
         return ERROR_MALFORMED;
     }
 
-    if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <=
+    if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <=
             (uint64_t)mNumSampleToChunkOffsets) {
         ALOGE("Sample-to-chunk table size too large.");
         return ERROR_OUT_OF_RANGE;
@@ -269,21 +273,19 @@
         return OK;
     }
 
-    if ((off64_t)(SIZE_MAX - 8 -
+    if ((off64_t)(kMaxOffset - 8 -
             ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry)))
             < mSampleToChunkOffset) {
         return ERROR_MALFORMED;
     }
 
     for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
-        uint8_t buffer[12];
-
-        if ((off64_t)(SIZE_MAX - 8 - (i * 12)) < mSampleToChunkOffset) {
-            return ERROR_MALFORMED;
-        }
+        uint8_t buffer[sizeof(SampleToChunkEntry)];
 
         if (mDataSource->readAt(
-                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
+                    mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry),
+                    buffer,
+                    sizeof(buffer))
                 != (ssize_t)sizeof(buffer)) {
             return ERROR_IO;
         }
@@ -384,8 +386,7 @@
     }
 
     mTimeToSampleCount = U32_AT(&header[4]);
-    if ((uint64_t)mTimeToSampleCount >
-        (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) {
+    if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
         // Choose this bound because
         // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
         //    time-to-sample entry in the time-to-sample table.
@@ -469,7 +470,7 @@
 
     mNumCompositionTimeDeltaEntries = numEntries;
     uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t);
-    if (allocSize > SIZE_MAX) {
+    if (allocSize > kMaxTotalSize) {
         ALOGE("Composition-time-to-sample table size too large.");
         return ERROR_OUT_OF_RANGE;
     }
@@ -536,7 +537,7 @@
     }
 
     uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t);
-    if (allocSize > SIZE_MAX) {
+    if (allocSize > kMaxTotalSize) {
         ALOGE("Sync sample table size too large.");
         return ERROR_OUT_OF_RANGE;
     }
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index aea6b67..0be7199 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -430,7 +430,7 @@
 {
     ALOGV("AudioMixer::deleteTrackName(%d)", name);
     name -= TRACK0;
-    ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
+    LOG_ALWAYS_FATAL_IF(name < 0 || name >= (int)MAX_NUM_TRACKS, "bad track name %d", name);
     ALOGV("deleteTrackName(%d)", name);
     track_t& track(mState.tracks[ name ]);
     if (track.enabled) {
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index e6c8abc..e3e518c 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -216,9 +216,10 @@
     return mHandles.size();
 }
 
-void AudioFlinger::EffectModule::updateState() {
+bool AudioFlinger::EffectModule::updateState() {
     Mutex::Autolock _l(mLock);
 
+    bool started = false;
     switch (mState) {
     case RESTART:
         reset_l();
@@ -233,6 +234,7 @@
         }
         if (start_l() == NO_ERROR) {
             mState = ACTIVE;
+            started = true;
         } else {
             mState = IDLE;
         }
@@ -256,6 +258,8 @@
     default: //IDLE , ACTIVE, DESTROYED
         break;
     }
+
+    return started;
 }
 
 void AudioFlinger::EffectModule::process()
@@ -462,10 +466,22 @@
     }
 }
 
+// start() must be called with PlaybackThread::mLock or EffectChain::mLock held
 status_t AudioFlinger::EffectModule::start()
 {
-    Mutex::Autolock _l(mLock);
-    return start_l();
+    sp<EffectChain> chain;
+    status_t status;
+    {
+        Mutex::Autolock _l(mLock);
+        status = start_l();
+        if (status == NO_ERROR) {
+            chain = mChain.promote();
+        }
+    }
+    if (chain != 0) {
+        chain->resetVolume_l();
+    }
+    return status;
 }
 
 status_t AudioFlinger::EffectModule::start_l()
@@ -489,10 +505,6 @@
     }
     if (status == 0) {
         addEffectToHal_l();
-        sp<EffectChain> chain = mChain.promote();
-        if (chain != 0) {
-            chain->forceVolume();
-        }
     }
     return status;
 }
@@ -1349,7 +1361,7 @@
                                         audio_session_t sessionId)
     : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
       mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
-      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX), mForceVolume(false)
+      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
 {
     mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
     if (thread == NULL) {
@@ -1471,8 +1483,12 @@
             mEffects[i]->process();
         }
     }
+    bool doResetVolume = false;
     for (size_t i = 0; i < size; i++) {
-        mEffects[i]->updateState();
+        doResetVolume = mEffects[i]->updateState() || doResetVolume;
+    }
+    if (doResetVolume) {
+        resetVolume_l();
     }
 }
 
@@ -1653,8 +1669,8 @@
     }
 }
 
-// setVolume_l() must be called with PlaybackThread::mLock held
-bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
+// setVolume_l() must be called with PlaybackThread::mLock or EffectChain::mLock held
+bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
 {
     uint32_t newLeft = *left;
     uint32_t newRight = *right;
@@ -1672,7 +1688,7 @@
         }
     }
 
-    if (!isVolumeForced() && ctrlIdx == mVolumeCtrlIdx &&
+    if (!force && ctrlIdx == mVolumeCtrlIdx &&
             *left == mLeftVolume && *right == mRightVolume) {
         if (hasControl) {
             *left = mNewLeftVolume;
@@ -1714,6 +1730,16 @@
     return hasControl;
 }
 
+// resetVolume_l() must be called with PlaybackThread::mLock or EffectChain::mLock held
+void AudioFlinger::EffectChain::resetVolume_l()
+{
+    if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
+        uint32_t left = mLeftVolume;
+        uint32_t right = mRightVolume;
+        (void)setVolume_l(&left, &right, true);
+    }
+}
+
 void AudioFlinger::EffectChain::syncHalEffectsState()
 {
     Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 3b62652..322c06a 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -60,7 +60,7 @@
 
     int         id() const { return mId; }
     void process();
-    void updateState();
+    bool updateState();
     status_t command(uint32_t cmdCode,
                      uint32_t cmdSize,
                      void *pCmdData,
@@ -277,7 +277,8 @@
     sp<EffectModule> getEffectFromId_l(int id);
     sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
     // FIXME use float to improve the dynamic range
-    bool setVolume_l(uint32_t *left, uint32_t *right);
+    bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false);
+    void resetVolume_l();
     void setDevice_l(audio_devices_t device);
     void setMode_l(audio_mode_t mode);
     void setAudioSource_l(audio_source_t source);
@@ -323,13 +324,6 @@
     // At least one non offloadable effect in the chain is enabled
     bool isNonOffloadableEnabled();
 
-    // use release_cas because we don't care about the observed value, just want to make sure the
-    // new value is observable.
-    void forceVolume() { android_atomic_release_cas(false, true, &mForceVolume); }
-    // use acquire_cas because we are interested in the observed value and
-    // we are the only observers.
-    bool isVolumeForced() { return (android_atomic_acquire_cas(true, false, &mForceVolume) == 0); }
-
     void syncHalEffectsState();
 
     bool hasSoftwareEffect() const;
@@ -393,5 +387,4 @@
              // timeLow fields among effect type UUIDs.
              // Updated by updateSuspendedSessions_l() only.
              KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
-    volatile int32_t mForceVolume; // force next volume command because a new effect was enabled
 };
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d093c32..aa2561e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5772,12 +5772,15 @@
                                             mChannelMask,
                                             frameCount,
                                             IPCThreadState::self()->getCallingUid());
-    if (outputTrack->cblk() != NULL) {
-        thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f);
-        mOutputTracks.add(outputTrack);
-        ALOGV("addOutputTrack() track %p, on thread %p", outputTrack.get(), thread);
-        updateWaitTime_l();
+    status_t status = outputTrack != 0 ? outputTrack->initCheck() : (status_t) NO_MEMORY;
+    if (status != NO_ERROR) {
+        ALOGE("addOutputTrack() initCheck failed %d", status);
+        return;
     }
+    thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f);
+    mOutputTracks.add(outputTrack);
+    ALOGV("addOutputTrack() track %p, on thread %p", outputTrack.get(), thread);
+    updateWaitTime_l();
 }
 
 void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index c0bb4e7..b752541 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -273,6 +273,9 @@
         }
 
         closeAllInputs();
+        // As the input device list can impact the output device selection, update
+        // getDeviceForStrategy() cache
+        updateDevicesAndOutputs();
 
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
             audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 4510d36..d0df6d1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2119,6 +2119,8 @@
     }
 
     finishCameraOps();
+    // Notify flashlight that a camera device is closed.
+    mCameraService->mFlashlight->deviceClosed(String8::format("%d", mCameraId));
     ALOGI("%s: Disconnected client for camera %d for PID %d", __FUNCTION__, mCameraId, mClientPid);
 
     // client shouldn't be able to call into us anymore
@@ -2216,10 +2218,6 @@
         // Transition device state to CLOSED
         mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
                 String8::format("%d", mCameraId));
-
-        // Notify flashlight that a camera device is closed.
-        mCameraService->mFlashlight->deviceClosed(
-                String8::format("%d", mCameraId));
     }
     // Always stop watching, even if no camera op is active
     if (mOpsCallback != NULL) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index bf94aca..40f8e75 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3135,7 +3135,7 @@
         mFlushLock.lock();
     }
 
-    ALOGVV("%s: %d: submitting %d requests in a batch.", __FUNCTION__, __LINE__,
+    ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
             mNextRequests.size());
     for (auto& nextRequest : mNextRequests) {
         // Submit request and block until ready for next one
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 299435a..7229929 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -472,6 +472,12 @@
                 __FUNCTION__, mTransform, strerror(-res), res);
     }
 
+    // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
+    // We need skip these cases as timeout will disable the non-blocking (async) mode.
+    if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
+        mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+    }
+
     /**
      * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
      * buffers to be statically allocated for internal static buffer registration, while the
@@ -701,6 +707,17 @@
     return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
 }
 
+bool Camera3OutputStream::isConsumedByHWTexture() const {
+    uint32_t usage = 0;
+    status_t res = getEndpointUsage(&usage);
+    if (res != OK) {
+        ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
+        return false;
+    }
+
+    return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0;
+}
+
 }; // namespace camera3
 
 }; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 5507cfc..d450a69 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -128,6 +128,11 @@
     bool isConsumedByHWComposer() const;
 
     /**
+     * Return if this output stream is consumed by hardware texture.
+     */
+    bool isConsumedByHWTexture() const;
+
+    /**
      * Return if the consumer configuration of this stream is deferred.
      */
     virtual bool isConsumerConfigurationDeferred() const;
@@ -181,6 +186,9 @@
     sp<Surface> mConsumer;
 
   private:
+
+    static const nsecs_t       kDequeueBufferTimeout   = 1000000000; // 1 sec
+
     int               mTransform;
 
     virtual status_t  setTransformLocked(int transform);