Merge "make libserviceutility a shared lib" into lmp-mr1-dev
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index d9646d9..ca3832d 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -167,10 +167,6 @@
         return INVALID_OPERATION;
     }
 
-    // handle default values first.
-    if (inputSource == AUDIO_SOURCE_DEFAULT) {
-        inputSource = AUDIO_SOURCE_MIC;
-    }
     if (pAttributes == NULL) {
         memset(&mAttributes, 0, sizeof(audio_attributes_t));
         mAttributes.source = inputSource;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e1c8a41..c2381b4 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1014,11 +1014,13 @@
 
                     // Notify mCrypto of video resolution changes
                     if (mCrypto != NULL) {
-                      int32_t height, width;
-                      if (mOutputFormat->findInt32("height", &height) &&
-                          mOutputFormat->findInt32("width", &width)) {
-                        mCrypto->notifyResolution(width, height);
-                      }
+                        int32_t left, top, right, bottom, width, height;
+                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
+                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
+                        } else if (mOutputFormat->findInt32("width", &width)
+                                && mOutputFormat->findInt32("height", &height)) {
+                            mCrypto->notifyResolution(width, height);
+                        }
                     }
 
                     break;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 7544052..4f0c6b1 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -166,7 +166,9 @@
             if (*handle == mPatches[index]->mHandle) {
                 ALOGV("createAudioPatch() removing patch handle %d", *handle);
                 halHandle = mPatches[index]->mHalHandle;
+                Patch *removedPatch = mPatches[index];
                 mPatches.removeAt(index);
+                delete removedPatch;
                 break;
             }
         }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index dacb12c..9fccda1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4083,6 +4083,10 @@
                 track->mRetryCount = kMaxTrackRetriesDirect;
                 mActiveTrack = t;
                 mixerStatus = MIXER_TRACKS_READY;
+                if (usesHwAvSync() && mHwPaused) {
+                    doHwResume = true;
+                    mHwPaused = false;
+                }
             }
         } else {
             // clear effect chain input buffer if the last active track started underruns
@@ -4111,9 +4115,6 @@
                         track->mState = TrackBase::STOPPED;
                     }
                     if (track->isStopped()) {
-                        if (track->mState == TrackBase::FLUSHED) {
-                            flushHw_l();
-                        }
                         track->reset();
                     }
                     tracksToRemove->add(track);
@@ -4130,6 +4131,10 @@
                     android_atomic_or(CBLK_DISABLED, &cblk->mFlags);
                 } else if (last) {
                     mixerStatus = MIXER_TRACKS_ENABLED;
+                    if (usesHwAvSync() && !mHwPaused && !mStandby) {
+                        doHwPause = true;
+                        mHwPaused = true;
+                    }
                 }
             }
         }
@@ -4192,7 +4197,7 @@
 void AudioFlinger::DirectOutputThread::threadLoop_sleepTime()
 {
     // do not write to HAL when paused
-    if (mHwPaused) {
+    if (mHwPaused || (usesHwAvSync() && mStandby)) {
         sleepTime = idleSleepTime;
         return;
     }
@@ -4237,7 +4242,7 @@
         trackPaused = mTracks[mTracks.size() - 1]->isPaused();
     }
 
-    return !mStandby && !trackPaused;
+    return !mStandby && !(trackPaused || (usesHwAvSync() && mHwPaused));
 }
 
 // getTrackName_l() must be called with ThreadBase::mLock held
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index f5d0e27..1088843 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -710,6 +710,9 @@
                                    audio_patch_handle_t *handle);
     virtual     status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
 
+                bool        usesHwAvSync() const { return (mType == DIRECT) && (mOutput != NULL) &&
+                                                (mOutput->flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC); }
+
 private:
 
     friend class AudioFlinger;      // for numerous
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 4bc3c7f..b8846c6 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -241,14 +241,21 @@
     if (mpAudioPolicy == NULL) {
         return NO_INIT;
     }
+
+    audio_source_t inputSource = attr->source;
+
     // already checked by client, but double-check in case the client wrapper is bypassed
-    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
-        attr->source != AUDIO_SOURCE_FM_TUNER) {
+    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&
+        inputSource != AUDIO_SOURCE_FM_TUNER) {
         return BAD_VALUE;
     }
 
-    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
-        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
+    if (inputSource == AUDIO_SOURCE_DEFAULT) {
+        inputSource = AUDIO_SOURCE_MIC;
+    }
+
+    if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
+        ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
         return BAD_VALUE;
     }
 
@@ -256,7 +263,7 @@
     {
         Mutex::Autolock _l(mLock);
         // the audio_in_acoustics_t parameter is ignored by get_input()
-        *input = mpAudioPolicy->get_input(mpAudioPolicy, attr->source, samplingRate,
+        *input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
                                              format, channelMask, (audio_in_acoustics_t) 0);
         audioPolicyEffects = mAudioPolicyEffects;
     }
@@ -266,7 +273,7 @@
 
     if (audioPolicyEffects != 0) {
         // create audio pre processors according to input source
-        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
+        status_t status = audioPolicyEffects->addInputEffects(*input, inputSource, session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
             ALOGW("Failed to add effects on input %d", input);
         }
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 8d1b3bb..0349327 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -1440,10 +1440,16 @@
     // handle legacy remote submix case where the address was not always specified
     String8 address = String8("");
     bool isSoundTrigger = false;
-    audio_source_t halInputSource = attr->source;
+    audio_source_t inputSource = attr->source;
+    audio_source_t halInputSource;
     AudioMix *policyMix = NULL;
 
-    if (attr->source == AUDIO_SOURCE_REMOTE_SUBMIX &&
+    if (inputSource == AUDIO_SOURCE_DEFAULT) {
+        inputSource = AUDIO_SOURCE_MIC;
+    }
+    halInputSource = inputSource;
+
+    if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
             strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
         device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
         address = String8(attr->tags + strlen("addr="));
@@ -1459,9 +1465,9 @@
         policyMix = &mPolicyMixes[index]->mMix;
         *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
     } else {
-        device = getDeviceAndMixForInputSource(attr->source, &policyMix);
+        device = getDeviceAndMixForInputSource(inputSource, &policyMix);
         if (device == AUDIO_DEVICE_NONE) {
-            ALOGW("getInputForAttr() could not find device for source %d", attr->source);
+            ALOGW("getInputForAttr() could not find device for source %d", inputSource);
             return BAD_VALUE;
         }
         if (policyMix != NULL) {
@@ -1483,7 +1489,7 @@
             *inputType = API_INPUT_LEGACY;
         }
         // adapt channel selection to input source
-        switch (attr->source) {
+        switch (inputSource) {
         case AUDIO_SOURCE_VOICE_UPLINK:
             channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
             break;
@@ -1496,7 +1502,7 @@
         default:
             break;
         }
-        if (attr->source == AUDIO_SOURCE_HOTWORD) {
+        if (inputSource == AUDIO_SOURCE_HOTWORD) {
             ssize_t index = mSoundTriggerSessions.indexOfKey(session);
             if (index >= 0) {
                 *input = mSoundTriggerSessions.valueFor(session);
@@ -1559,7 +1565,7 @@
     }
 
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
-    inputDesc->mInputSource = attr->source;
+    inputDesc->mInputSource = inputSource;
     inputDesc->mRefCount = 0;
     inputDesc->mOpenRefCount = 1;
     inputDesc->mSamplingRate = samplingRate;