Merge change I4961c959 into eclair

* changes:
  fix [2152536] ANR in browser
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 8e967fb..ba8b322 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -62,8 +62,6 @@
 static const char* kHardwareLockedString = "Hardware lock is taken\n";
 
 //static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-static const unsigned long kBufferRecoveryInUsecs = 2000;
-static const unsigned long kMaxBufferRecoveryInUsecs = 20000;
 static const float MAX_GAIN = 4096.0f;
 
 // retry counts for buffer fill timeout
@@ -1070,10 +1068,10 @@
     // in both cases "unstop" the track
     if (track->isPaused()) {
         track->mState = TrackBase::RESUMING;
-        LOGV("PAUSED => RESUMING (%d)", track->name());
+        LOGV("PAUSED => RESUMING (%d) on thread %p", track->name(), this);
     } else {
         track->mState = TrackBase::ACTIVE;
-        LOGV("? => ACTIVE (%d)", track->name());
+        LOGV("? => ACTIVE (%d) on thread %p", track->name(), this);
     }
     // set retry count for buffer fill
     track->mRetryCount = kMaxTrackStartupRetries;
@@ -1175,7 +1173,8 @@
 
 bool AudioFlinger::MixerThread::threadLoop()
 {
-    unsigned long sleepTime = 0;
+    uint32_t sleepTime = 0;
+    uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     int16_t* curBuf = mMixBuffer;
     Vector< sp<Track> > tracksToRemove;
     size_t enabledTracks = 0;
@@ -1200,6 +1199,7 @@
                 // FIXME: Relaxed timing because of a certain device that can't meet latency
                 // Should be reduced to 2x after the vendor fixes the driver issue
                 maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
+                maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
             }
 
             const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -1235,7 +1235,6 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    sleepTime = 0;
                     continue;
                 }
             }
@@ -1249,28 +1248,23 @@
             sleepTime = 0;
             standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            sleepTime += kBufferRecoveryInUsecs;
-            if (sleepTime > kMaxBufferRecoveryInUsecs) {
-                sleepTime = kMaxBufferRecoveryInUsecs;
-            }
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, write 0s to audio
-            // hardware to avoid underrun.
-            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
+            // If no tracks are ready, sleep once for the duration of an output
+            // buffer size, then write 0s to the output
+            if (sleepTime == 0) {
+                sleepTime = maxBufferRecoveryInUsecs;
+            } else if (mBytesWritten != 0) {
                 memset (curBuf, 0, mixBufferSize);
                 sleepTime = 0;
             }
         }
 
         if (mSuspended) {
-            sleepTime = kMaxBufferRecoveryInUsecs;
+            sleepTime = maxBufferRecoveryInUsecs;
         }
         // sleepTime == 0 means we must write to audio hardware
         if (sleepTime == 0) {
             mLastWriteTime = systemTime();
             mInWrite = true;
-            LOGV("mOutput->write() thread %p frames %d", this, mFrameCount);
             int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
             if (bytesWritten > 0) mBytesWritten += bytesWritten;
             mNumWrites++;
@@ -1393,7 +1387,7 @@
                 // No buffers for this track. Give it a few chances to
                 // fill a buffer, then remove it from active list.
                 if (--(track->mRetryCount) <= 0) {
-                    LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                    LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
                     tracksToRemove->add(track);
                 }
                 // For tracks using static shared memory buffer, make sure that we have
@@ -1583,6 +1577,16 @@
     return NO_ERROR;
 }
 
+uint32_t AudioFlinger::MixerThread::getMaxBufferRecoveryInUsecs()
+{
+    uint32_t time = ((mFrameCount * 1000) / mSampleRate) * 1000;
+    // Add some margin with regard to scheduling precision
+    if (time > 10000) {
+        time -= 10000;
+    }
+    return time;
+}
+
 // ----------------------------------------------------------------------------
 AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output)
     :   PlaybackThread(audioFlinger, output),
@@ -1598,7 +1602,8 @@
 
 bool AudioFlinger::DirectOutputThread::threadLoop()
 {
-    unsigned long sleepTime = 0;
+    uint32_t sleepTime = 0;
+    uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     sp<Track> trackToRemove;
     sp<Track> activeTrack;
     nsecs_t standbyTime = systemTime();
@@ -1615,6 +1620,7 @@
 
             if (checkForNewParameters_l()) {
                 mixBufferSize = mFrameCount*mFrameSize;
+                maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
             }
 
             // put audio hardware into standby after short delay
@@ -1648,7 +1654,6 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    sleepTime = 0;
                     continue;
                 }
             }
@@ -1761,23 +1766,16 @@
             sleepTime = 0;
             standbyTime = systemTime() + kStandbyTimeInNsecs;
         } else {
-            sleepTime += kBufferRecoveryInUsecs;
-            if (sleepTime > kMaxBufferRecoveryInUsecs) {
-                sleepTime = kMaxBufferRecoveryInUsecs;
-            }
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, write 0s to audio
-            // hardware to avoid underrun.
-            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs &&
-                AudioSystem::isLinearPCM(mFormat)) {
+            if (sleepTime == 0) {
+                sleepTime = maxBufferRecoveryInUsecs;
+            } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
                 memset (mMixBuffer, 0, mFrameCount * mFrameSize);
                 sleepTime = 0;
             }
         }
 
         if (mSuspended) {
-            sleepTime = kMaxBufferRecoveryInUsecs;
+            sleepTime = maxBufferRecoveryInUsecs;
         }
         // sleepTime == 0 means we must write to audio hardware
         if (sleepTime == 0) {
@@ -1861,6 +1859,21 @@
     return reconfig;
 }
 
+uint32_t AudioFlinger::DirectOutputThread::getMaxBufferRecoveryInUsecs()
+{
+    uint32_t time;
+    if (AudioSystem::isLinearPCM(mFormat)) {
+        time = ((mFrameCount * 1000) / mSampleRate) * 1000;
+        // Add some margin with regard to scheduling precision
+        if (time > 10000) {
+            time -= 10000;
+        }
+    } else {
+        time = 10000;
+    }
+    return time;
+}
+
 // ----------------------------------------------------------------------------
 
 AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread)
@@ -1877,13 +1890,15 @@
 
 bool AudioFlinger::DuplicatingThread::threadLoop()
 {
-    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    uint32_t sleepTime = 0;
+    uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
     int16_t* curBuf = mMixBuffer;
     Vector< sp<Track> > tracksToRemove;
     size_t enabledTracks = 0;
     nsecs_t standbyTime = systemTime();
     size_t mixBufferSize = mFrameCount*mFrameSize;
     SortedVector< sp<OutputTrack> > outputTracks;
+    uint32_t writeFrames = 0;
 
     while (!exitPending())
     {
@@ -1896,6 +1911,7 @@
 
             if (checkForNewParameters_l()) {
                 mixBufferSize = mFrameCount*mFrameSize;
+                maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
             }
 
             const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -1935,7 +1951,6 @@
                     }
 
                     standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    sleepTime = kBufferRecoveryInUsecs;
                     continue;
                 }
             }
@@ -1947,29 +1962,30 @@
             // mix buffers...
             mAudioMixer->process(curBuf);
             sleepTime = 0;
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
+            writeFrames = mFrameCount;
         } else {
-            sleepTime += kBufferRecoveryInUsecs;
-            if (sleepTime > kMaxBufferRecoveryInUsecs) {
-                sleepTime = kMaxBufferRecoveryInUsecs;
-            }
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, write 0s to audio
-            // hardware to avoid underrun.
-            if (mBytesWritten != 0 && sleepTime >= kMaxBufferRecoveryInUsecs) {
-                memset (curBuf, 0, mixBufferSize);
-                sleepTime = 0;
+            if (sleepTime == 0) {
+                sleepTime = maxBufferRecoveryInUsecs;
+            } else if (mBytesWritten != 0) {
+                // flush remaining overflow buffers in output tracks
+                for (size_t i = 0; i < outputTracks.size(); i++) {
+                    if (outputTracks[i]->isActive()) {
+                        sleepTime = 0;
+                        writeFrames = 0;
+                        break;
+                    }
+                }
             }
         }
 
         if (mSuspended) {
-            sleepTime = kMaxBufferRecoveryInUsecs;
+            sleepTime = maxBufferRecoveryInUsecs;
         }
         // sleepTime == 0 means we must write to audio hardware
         if (sleepTime == 0) {
+            standbyTime = systemTime() + kStandbyTimeInNsecs;
             for (size_t i = 0; i < outputTracks.size(); i++) {
-                outputTracks[i]->write(curBuf, mFrameCount);
+                outputTracks[i]->write(curBuf, writeFrames);
             }
             mStandby = false;
             mBytesWritten += mixBufferSize;
@@ -2026,7 +2042,6 @@
     LOGV("removeOutputTrack(): unkonwn thread: %p", thread);
 }
 
-
 // ----------------------------------------------------------------------------
 
 // TrackBase constructor must be called with AudioFlinger::mLock held
@@ -2300,7 +2315,7 @@
 getNextBuffer_exit:
      buffer->raw = 0;
      buffer->frameCount = 0;
-     LOGV("getNextBuffer() no more data");
+     LOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
      return NOT_ENOUGH_DATA;
 }
 
@@ -2341,7 +2356,7 @@
             if (playbackThread->mActiveTracks.indexOf(this) < 0) {
                 reset();
             }
-            LOGV("(> STOPPED) => STOPPED (%d)", mName);
+            LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread);
         }
     }
 }
@@ -2354,7 +2369,7 @@
         Mutex::Autolock _l(thread->mLock);
         if (mState == ACTIVE || mState == RESUMING) {
             mState = PAUSING;
-            LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
+            LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
         }
     }
 }
@@ -2566,7 +2581,7 @@
 
     uint32_t waitTimeLeftMs = mWaitTimeMs;
 
-    if (!mActive) {
+    if (!mActive && frames != 0) {
         start();
         sp<ThreadBase> thread = mThread.promote();
         if (thread != 0) {
@@ -2608,7 +2623,7 @@
                 break;
             }
             uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
-//            LOGV("OutputTrack::write() waitTimeMs %d waitTimeLeftMs %d", waitTimeMs, waitTimeLeftMs)
+            LOGV("OutputTrack::write() to thread %p waitTimeMs %d waitTimeLeftMs %d", mThread.unsafe_get(), waitTimeMs, waitTimeLeftMs);
             if (waitTimeLeftMs >= waitTimeMs) {
                 waitTimeLeftMs -= waitTimeMs;
             } else {
@@ -2663,7 +2678,7 @@
             pInBuffer->i16 = pInBuffer->mBuffer;
             memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
             mBufferQueue.add(pInBuffer);
-        } else {
+        } else if (mActive) {
             stop();
         }
     }
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 3699019..4bf73ce 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -524,6 +524,10 @@
         bool                            mMasterMute;
         SortedVector< wp<Track> >       mActiveTracks;
 
+        virtual int             getTrackName_l() = 0;
+        virtual void            deleteTrackName_l(int name) = 0;
+        virtual uint32_t        getMaxBufferRecoveryInUsecs() = 0;
+
     private:
 
         friend class AudioFlinger;
@@ -539,8 +543,7 @@
 
         status_t    addTrack_l(const sp<Track>& track);
         void        destroyTrack_l(const sp<Track>& track);
-        virtual int         getTrackName_l() = 0;
-        virtual void        deleteTrackName_l(int name) = 0;
+
         void        readOutputParameters();
 
         virtual status_t    dumpInternals(int fd, const Vector<String16>& args);
@@ -571,13 +574,14 @@
                                       int streamType);
                     void        putTracks(SortedVector < sp<Track> >& tracks,
                                       SortedVector < wp<Track> >& activeTracks);
-        virtual     int         getTrackName_l();
-        virtual     void        deleteTrackName_l(int name);
         virtual     bool        checkForNewParameters_l();
         virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
 
     protected:
         size_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove);
+        virtual     int         getTrackName_l();
+        virtual     void        deleteTrackName_l(int name);
+        virtual     uint32_t    getMaxBufferRecoveryInUsecs();
 
         AudioMixer*                     mAudioMixer;
     };
@@ -591,9 +595,12 @@
         // Thread virtuals
         virtual     bool        threadLoop();
 
+        virtual     bool        checkForNewParameters_l();
+
+    protected:
         virtual     int         getTrackName_l();
         virtual     void        deleteTrackName_l(int name);
-        virtual     bool        checkForNewParameters_l();
+        virtual     uint32_t    getMaxBufferRecoveryInUsecs();
 
     private:
         float mLeftVolume;
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f84933e..392a3ed 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -246,10 +246,10 @@
     LOGI("version   : %s", glGetString(GL_VERSION));
     LOGI("extensions: %s", gl_extensions);
 
-    if (strstr(gl_renderer, "PowerVR SGX 530")) {
-        LOGD("Assuming uncached graphics buffers.");
-        mFlags &= ~CACHED_BUFFERS;
-    }
+    //if (strstr(gl_renderer, "PowerVR SGX 530")) {
+    //    LOGD("Assuming uncached graphics buffers.");
+    //    mFlags &= ~CACHED_BUFFERS;
+    //}
     if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
         mFlags |= NPOT_EXTENSION;
     }