am e7800946: Merge change I49f02be9 into eclair

Merge commit 'e7800946a42c0ebe8e0b3f6eba04a96a9641aaff' into eclair-mr2

* commit 'e7800946a42c0ebe8e0b3f6eba04a96a9641aaff':
  Issue 2265163: Audio still reported routed through earpiece on sholes
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 008468c..622c596 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -268,7 +268,7 @@
      * Returned value:
      *  handle on audio hardware input
      */
-            audio_io_handle_t    getInput() { return mInput; }
+            audio_io_handle_t    getInput();
 
     /* obtains a buffer of "frameCount" frames. The buffer must be
      * filled entirely. If the track is stopped, obtainBuffer() returns
@@ -318,7 +318,8 @@
                                 int format,
                                 int channelCount,
                                 int frameCount,
-                                uint32_t flags);
+                                uint32_t flags,
+                                audio_io_handle_t input);
 
     sp<IAudioRecord>        mAudioRecord;
     sp<IMemory>             mCblkMemory;
@@ -345,8 +346,8 @@
     bool                    mMarkerReached;
     uint32_t                mNewPosition;
     uint32_t                mUpdatePeriod;
-    audio_io_handle_t       mInput;
     uint32_t                mFlags;
+    uint32_t                mChannels;
 };
 
 }; // namespace android
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index e63c0d2..c3828f0 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -46,7 +46,7 @@
 // ---------------------------------------------------------------------------
 
 AudioRecord::AudioRecord()
-    : mStatus(NO_INIT), mInput(0)
+    : mStatus(NO_INIT)
 {
 }
 
@@ -60,7 +60,7 @@
         callback_t cbf,
         void* user,
         int notificationFrames)
-    : mStatus(NO_INIT), mInput(0)
+    : mStatus(NO_INIT)
 {
     mStatus = set(inputSource, sampleRate, format, channels,
             frameCount, flags, cbf, user, notificationFrames);
@@ -79,7 +79,6 @@
         }
         mAudioRecord.clear();
         IPCThreadState::self()->flushCommands();
-        AudioSystem::releaseInput(mInput);
     }
 }
 
@@ -123,9 +122,9 @@
     }
     int channelCount = AudioSystem::popCount(channels);
 
-    mInput = AudioSystem::getInput(inputSource,
+    audio_io_handle_t input = AudioSystem::getInput(inputSource,
                                     sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
-    if (mInput == 0) {
+    if (input == 0) {
         LOGE("Could not get audio output for stream type %d", inputSource);
         return BAD_VALUE;
     }
@@ -168,7 +167,7 @@
 
     // create the IAudioRecord
     status_t status = openRecord(sampleRate, format, channelCount,
-                                 frameCount, flags);
+                                 frameCount, flags, input);
 
     if (status != NO_ERROR) {
         return status;
@@ -187,6 +186,7 @@
     // Update buffer size in case it has been limited by AudioFlinger during track creation
     mFrameCount = mCblk->frameCount;
     mChannelCount = (uint8_t)channelCount;
+    mChannels = channels;
     mActive = 0;
     mCbf = cbf;
     mNotificationFrames = notificationFrames;
@@ -265,29 +265,28 @@
      }
 
     if (android_atomic_or(1, &mActive) == 0) {
-        ret = AudioSystem::startInput(mInput);
-        if (ret == NO_ERROR) {
-            ret = mAudioRecord->start();
-            if (ret == DEAD_OBJECT) {
-                LOGV("start() dead IAudioRecord: creating a new one");
-                ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
-                        mFrameCount, mFlags);
-            }
+        ret = mAudioRecord->start();
+        if (ret == DEAD_OBJECT) {
+            LOGV("start() dead IAudioRecord: creating a new one");
+            ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
+                    mFrameCount, mFlags, getInput());
             if (ret == NO_ERROR) {
-                mNewPosition = mCblk->user + mUpdatePeriod;
-                mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
-                mCblk->waitTimeMs = 0;
-                if (t != 0) {
-                   t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
-                } else {
-                    setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
-                }
-            } else {
-                LOGV("start() failed");
-                AudioSystem::stopInput(mInput);
-                android_atomic_and(~1, &mActive);
+                ret = mAudioRecord->start();
             }
         }
+        if (ret == NO_ERROR) {
+            mNewPosition = mCblk->user + mUpdatePeriod;
+            mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+            mCblk->waitTimeMs = 0;
+            if (t != 0) {
+               t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
+            } else {
+                setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+            }
+        } else {
+            LOGV("start() failed");
+            android_atomic_and(~1, &mActive);
+        }
     }
 
     if (t != 0) {
@@ -318,7 +317,6 @@
         } else {
             setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
         }
-        AudioSystem::stopInput(mInput);
     }
 
     if (t != 0) {
@@ -395,7 +393,8 @@
         int format,
         int channelCount,
         int frameCount,
-        uint32_t flags)
+        uint32_t flags,
+        audio_io_handle_t input)
 {
     status_t status;
     const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -403,7 +402,7 @@
         return NO_INIT;
     }
 
-    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput,
+    sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
                                                        sampleRate, format,
                                                        channelCount,
                                                        frameCount,
@@ -425,7 +424,8 @@
     mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
     mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
     mCblk->out = 0;
-
+    mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+    mCblk->waitTimeMs = 0;
     return NO_ERROR;
 }
 
@@ -466,10 +466,10 @@
                     if (result == DEAD_OBJECT) {
                         LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
                         result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
-                                            mFrameCount, mFlags);
+                                            mFrameCount, mFlags, getInput());
                         if (result == NO_ERROR) {
                             cblk = mCblk;
-                            cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+                            mAudioRecord->start();
                         }
                     }
                     cblk->lock.lock();
@@ -516,6 +516,14 @@
     cblk->stepUser(audioBuffer->frameCount);
 }
 
+audio_io_handle_t AudioRecord::getInput()
+{
+   return AudioSystem::getInput(mInputSource,
+                                mCblk->sampleRate,
+                                mFormat, mChannels,
+                                (AudioSystem::audio_in_acoustics)mFlags);
+}
+
 // -------------------------------------------------------------------------
 
 ssize_t AudioRecord::read(void* buffer, size_t userSize)
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index cedd79d..ad0f42e 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -97,7 +97,6 @@
         }
         mAudioTrack.clear();
         IPCThreadState::self()->flushCommands();
-        AudioSystem::releaseOutput(getOutput());
     }
 }
 
@@ -318,8 +317,6 @@
      }
 
     if (android_atomic_or(1, &mActive) == 0) {
-        audio_io_handle_t output = getOutput();
-        AudioSystem::startOutput(output, (AudioSystem::stream_type)mStreamType);
         mNewPosition = mCblk->server + mUpdatePeriod;
         mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
         mCblk->waitTimeMs = 0;
@@ -333,10 +330,13 @@
         if (status == DEAD_OBJECT) {
             LOGV("start() dead IAudioTrack: creating a new one");
             status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
-                                 mFrameCount, mFlags, mSharedBuffer, output);
-            mNewPosition = mCblk->server + mUpdatePeriod;
-            mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
-            mCblk->waitTimeMs = 0;
+                                 mFrameCount, mFlags, mSharedBuffer, getOutput());
+            if (status == NO_ERROR) {
+                status = mAudioTrack->start();
+                if (status == NO_ERROR) {
+                    mNewPosition = mCblk->server + mUpdatePeriod;
+                }
+            }
         }
         if (status != NO_ERROR) {
             LOGV("start() failed");
@@ -346,7 +346,6 @@
             } else {
                 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
             }
-            AudioSystem::stopOutput(output, (AudioSystem::stream_type)mStreamType);
         }
     }
 
@@ -383,7 +382,6 @@
         } else {
             setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
         }
-        AudioSystem::stopOutput(getOutput(), (AudioSystem::stream_type)mStreamType);
     }
 
     if (t != 0) {
@@ -418,9 +416,7 @@
 {
     LOGV("pause");
     if (android_atomic_and(~1, &mActive) == 1) {
-        mActive = 0;
         mAudioTrack->pause();
-        AudioSystem::stopOutput(getOutput(), (AudioSystem::stream_type)mStreamType);
     }
 }
 
@@ -658,7 +654,8 @@
     }
 
     mCblk->volumeLR = (int32_t(int16_t(mVolume[LEFT] * 0x1000)) << 16) | int16_t(mVolume[RIGHT] * 0x1000);
-
+    mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+    mCblk->waitTimeMs = 0;
     return NO_ERROR;
 }
 
@@ -709,6 +706,7 @@
                             if (result == NO_ERROR) {
                                 cblk = mCblk;
                                 cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+                                mAudioTrack->start();
                             }
                         }
                         cblk->lock.lock();