Merge change Ia5ef9acd into eclair

* changes:
  remove an old STOPSHIP comment
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index daec6e8..2024cc0 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1111,7 +1111,6 @@
 {
     track->mState = TrackBase::TERMINATED;
     if (mActiveTracks.indexOf(track) < 0) {
-        LOGV("remove track (%d) and delete from mixer", track->name());
         mTracks.remove(track);
         deleteTrackName_l(track->name());
     }
@@ -1511,6 +1510,7 @@
 // deleteTrackName_l() must be called with ThreadBase::mLock held
 void AudioFlinger::MixerThread::deleteTrackName_l(int name)
 {
+    LOGV("remove track (%d) and delete from mixer", name);
     mAudioMixer->deleteTrackName(name);
 }
 
@@ -1922,6 +1922,9 @@
 
 AudioFlinger::DuplicatingThread::~DuplicatingThread()
 {
+    for (size_t i = 0; i < mOutputTracks.size(); i++) {
+        mOutputTracks[i]->destroy();
+    }
     mOutputTracks.clear();
 }
 
@@ -2044,17 +2047,6 @@
         outputTracks.clear();
     }
 
-    { // scope for the mLock
-
-        Mutex::Autolock _l(mLock);
-        if (!mStandby) {
-            LOGV("DuplicatingThread() exiting out of standby");
-            for (size_t i = 0; i < mOutputTracks.size(); i++) {
-                mOutputTracks[i]->destroy();
-            }
-        }
-    }
-
     return false;
 }
 
@@ -2277,10 +2269,8 @@
     LOGV("PlaybackThread::Track destructor");
     sp<ThreadBase> thread = mThread.promote();
     if (thread != 0) {
-        thread->mLock.lock();
+        Mutex::Autolock _l(thread->mLock);
         mState = TERMINATED;
-        thread->mLock.unlock();
-        AudioSystem::releaseOutput(thread->id());
     }
 }
 
@@ -2298,8 +2288,11 @@
     { // scope for mLock
         sp<ThreadBase> thread = mThread.promote();
         if (thread != 0) {
-            if (!isOutputTrack() && (mState == ACTIVE || mState == RESUMING)) {
-                AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+            if (!isOutputTrack()) {
+                if (mState == ACTIVE || mState == RESUMING) {
+                    AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+                }
+                AudioSystem::releaseOutput(thread->id());
             }
             Mutex::Autolock _l(thread->mLock);
             PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
@@ -3085,23 +3078,34 @@
             }
             if (mActiveTrack != 0) {
                 if (mActiveTrack->mState == TrackBase::PAUSING) {
+                    if (!mStandby) {
+                        mInput->standby();
+                        mStandby = true;
+                    }
                     mActiveTrack.clear();
                     mStartStopCond.broadcast();
                 } else if (mActiveTrack->mState == TrackBase::RESUMING) {
-                    mRsmpInIndex = mFrameCount;
                     if (mReqChannelCount != mActiveTrack->channelCount()) {
                         mActiveTrack.clear();
-                    } else {
-                        mActiveTrack->mState = TrackBase::ACTIVE;
+                        mStartStopCond.broadcast();
+                    } else if (mBytesRead != 0) {
+                        // record start succeeds only if first read from audio input
+                        // succeeds
+                        if (mBytesRead > 0) {
+                            mActiveTrack->mState = TrackBase::ACTIVE;
+                        } else {
+                            mActiveTrack.clear();
+                        }
+                        mStartStopCond.broadcast();
                     }
-                    mStartStopCond.broadcast();
+                    mStandby = false;
                 }
-                mStandby = false;
             }
         }
 
         if (mActiveTrack != 0) {
-            if (mActiveTrack->mState != TrackBase::ACTIVE) {
+            if (mActiveTrack->mState != TrackBase::ACTIVE &&
+                mActiveTrack->mState != TrackBase::RESUMING) {
                 usleep(5000);
                 continue;
             }
@@ -3139,18 +3143,19 @@
                             }
                         }
                         if (framesOut && mFrameCount == mRsmpInIndex) {
-                            ssize_t bytesRead;
                             if (framesOut == mFrameCount &&
                                 (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
-                                bytesRead = mInput->read(buffer.raw, mInputBytes);
+                                mBytesRead = mInput->read(buffer.raw, mInputBytes);
                                 framesOut = 0;
                             } else {
-                                bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+                                mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
                                 mRsmpInIndex = 0;
                             }
-                            if (bytesRead < 0) {
+                            if (mBytesRead < 0) {
                                 LOGE("Error reading audio input");
-                                sleep(1);
+                                if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                                    sleep(1);
+                                }
                                 mRsmpInIndex = mFrameCount;
                                 framesOut = 0;
                                 buffer.frameCount = 0;
@@ -3219,7 +3224,7 @@
             if (recordTrack != mActiveTrack.get()) {
                 status = -EBUSY;
             } else if (mActiveTrack->mState == TrackBase::PAUSING) {
-                mActiveTrack->mState = TrackBase::RESUMING;
+                mActiveTrack->mState = TrackBase::ACTIVE;
             }
             return status;
         }
@@ -3234,6 +3239,8 @@
             return status;
         }
         mActiveTrack->mState = TrackBase::RESUMING;
+        mRsmpInIndex = mFrameCount;
+        mBytesRead = 0;
         // signal thread to start
         LOGV("Signal record thread");
         mWaitWorkCV.signal();
@@ -3274,6 +3281,7 @@
                 mLock.unlock();
                 AudioSystem::stopInput(mId);
                 mLock.lock();
+                LOGV("Record stopped OK");
             }
         }
     }
@@ -3324,10 +3332,12 @@
     int channelCount;
 
     if (framesReady == 0) {
-        ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
-        if (bytesRead < 0) {
+        mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+        if (mBytesRead < 0) {
             LOGE("RecordThread::getNextBuffer() Error reading audio input");
-            sleep(1);
+            if (mActiveTrack->mState == TrackBase::ACTIVE) {
+                sleep(1);
+            }
             buffer->raw = 0;
             buffer->frameCount = 0;
             return NOT_ENOUGH_DATA;
@@ -3545,9 +3555,11 @@
         if (pFormat) *pFormat = format;
         if (pChannels) *pChannels = channels;
         if (pLatencyMs) *pLatencyMs = thread->latency();
+
+        return mNextThreadId;
     }
 
-    return mNextThreadId;
+    return 0;
 }
 
 int AudioFlinger::openDuplicateOutput(int output1, int output2)
@@ -3693,9 +3705,11 @@
         if (pChannels) *pChannels = reqChannels;
 
         input->standby();
+
+        return mNextThreadId;
     }
 
-    return mNextThreadId;
+    return 0;
 }
 
 status_t AudioFlinger::closeInput(int input)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 5a17294..8c29da8 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -744,6 +744,7 @@
                 size_t                              mInputBytes;
                 int                                 mReqChannelCount;
                 uint32_t                            mReqSampleRate;
+                ssize_t                             mBytesRead;
     };
 
     class RecordHandle : public android::BnAudioRecord {
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index eb51c22..b3fed58 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -22,9 +22,6 @@
 ifeq ($(TARGET_BOARD_PLATFORM), msm7k)
 	LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
 endif
-ifeq ($(TARGET_BOARD_PLATFORM), qsd8k)
-	LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
-endif
 
 # need "-lrt" on Linux simulator to pick up clock_gettime
 ifeq ($(TARGET_SIMULATOR),true)
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 79c003f..d9d9bfe 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -246,8 +246,7 @@
     LOGI("version   : %s", glGetString(GL_VERSION));
     LOGI("extensions: %s", gl_extensions);
 
-    if (strstr(gl_renderer, "PowerVR SGX 530") ||
-        strstr(gl_renderer, "Adreno")) {
+    if (strstr(gl_renderer, "Adreno")) {
         LOGD("Assuming uncached graphics buffers.");
         mFlags &= ~CACHED_BUFFERS;
     }
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 88ef7e4..eb017bf 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -266,7 +266,16 @@
     : mBufferHeap(buffers)
 {
     NativeBuffer& src(mNativeBuffer);
-    src.img.handle = 0;
+    src.crop.l = 0;
+    src.crop.t = 0;
+    src.crop.r = buffers.w;
+    src.crop.b = buffers.h;
+
+    src.img.w       = buffers.hor_stride ?: buffers.w;
+    src.img.h       = buffers.ver_stride ?: buffers.h;
+    src.img.format  = buffers.format;
+    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+    src.img.handle  = 0;
 
     gralloc_module_t const * module = LayerBuffer::getGrallocModule();
     if (module && module->perform) {
@@ -276,19 +285,12 @@
                 offset, buffers.heap->base(),
                 &src.img.handle);
 
-        if (err == NO_ERROR) {
-            src.crop.l = 0;
-            src.crop.t = 0;
-            src.crop.r = buffers.w;
-            src.crop.b = buffers.h;
-
-            src.img.w       = buffers.hor_stride ?: buffers.w;
-            src.img.h       = buffers.ver_stride ?: buffers.h;
-            src.img.format  = buffers.format;
-            src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
-        }
+        LOGE_IF(err, "CREATE_HANDLE_FROM_BUFFER (heapId=%d, size=%d, "
+             "offset=%ld, base=%p) failed (%s)",
+                buffers.heap->heapID(), buffers.heap->getSize(),
+                offset, buffers.heap->base(), strerror(-err));
     }
-}
+ }
 
 LayerBuffer::Buffer::~Buffer()
 {
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 9694cf1..965b7dd 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -417,9 +417,9 @@
 {
     while (true) {
         nsecs_t timeout = -1;
+        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
         if (UNLIKELY(isFrozen())) {
             // wait 5 seconds
-            const nsecs_t freezeDisplayTimeout = ms2ns(5000);
             const nsecs_t now = systemTime();
             if (mFreezeDisplayTime == 0) {
                 mFreezeDisplayTime = now;
@@ -429,23 +429,27 @@
         }
 
         MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+
+        // see if we timed out
+        if (isFrozen()) {
+            const nsecs_t now = systemTime();
+            nsecs_t frozenTime = (now - mFreezeDisplayTime);
+            if (frozenTime >= freezeDisplayTimeout) {
+                // we timed out and are still frozen
+                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+                        mFreezeDisplay, mFreezeCount);
+                mFreezeDisplayTime = 0;
+                mFreezeCount = 0;
+                mFreezeDisplay = false;
+            }
+        }
+
         if (msg != 0) {
-            mFreezeDisplayTime = 0;
             switch (msg->what) {
                 case MessageQueue::INVALIDATE:
                     // invalidate message, just return to the main loop
                     return;
             }
-        } else {
-            // we timed out
-            if (isFrozen()) {
-                // we timed out and are still frozen
-                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
-                        mFreezeDisplay, mFreezeCount);
-                mFreezeCount = 0;
-                mFreezeDisplay = false;
-                return;
-            }
         }
     }
 }
@@ -1646,6 +1650,7 @@
             }
             case 1007: // set mFreezeCount
                 mFreezeCount = data.readInt32();
+                mFreezeDisplayTime = 0;
                 return NO_ERROR;
             case 1010:  // interrogate.
                 reply->writeInt32(0);
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f9bfe6c..c0ab73d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -291,7 +291,11 @@
 
             friend class FreezeLock;
             sp<FreezeLock> getFreezeLock() const;
-            inline void incFreezeCount() { mFreezeCount++; }
+            inline void incFreezeCount() {
+                if (mFreezeCount == 0)
+                    mFreezeDisplayTime = 0;
+                mFreezeCount++;
+            }
             inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
             inline bool hasFreezeRequest() const { return mFreezeDisplay; }
             inline bool isFrozen() const {