Merge "Adding support for the '.mxmf' MIDI file extension."
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 9aa84a03..cc689bb 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -715,15 +715,13 @@
     }
 
     /**
-     * Registers the current activity to be notified periodically by
-     * the named provider.  Periodically, the supplied LocationListener will
-     * be called with the current Location or with status updates.
+     * Requests a single location update from the named provider.
      *
      * <p> It may take a while to receive the most recent location. If
      * an immediate location is required, applications may use the
      * {@link #getLastKnownLocation(String)} method.
      *
-     * <p> In case the provider is disabled by the user, updates will stop,
+     * <p> In case the provider is disabled by the user, the update will not be received,
      * and the {@link LocationListener#onProviderDisabled(String)}
      * method will be called. As soon as the provider is enabled again,
      * the {@link LocationListener#onProviderEnabled(String)} method will
@@ -733,8 +731,8 @@
      *
      * @param provider the name of the provider with which to register
      * @param listener a {#link LocationListener} whose
-     * {@link LocationListener#onLocationChanged} method will be called for
-     * each location update
+     * {@link LocationListener#onLocationChanged} method will be called when
+     * the location update is available
      * @param looper a Looper object whose message queue will be used to
      * implement the callback mechanism.
      * If looper is null then the callbacks will be called on the main thread.
@@ -754,15 +752,13 @@
     }
 
     /**
-     * Registers the current activity to be notified periodically based on
-     * the specified criteria.  Periodically, the supplied LocationListener will
-     * be called with the current Location or with status updates.
+     * Requests a single location update based on the specified criteria.
      *
      * <p> It may take a while to receive the most recent location. If
      * an immediate location is required, applications may use the
      * {@link #getLastKnownLocation(String)} method.
      *
-     * <p> In case the provider is disabled by the user, updates will stop,
+     * <p> In case the provider is disabled by the user, the update will not be received,
      * and the {@link LocationListener#onProviderDisabled(String)}
      * method will be called. As soon as the provider is enabled again,
      * the {@link LocationListener#onProviderEnabled(String)} method will
@@ -773,8 +769,8 @@
      * @param criteria contains parameters for the location manager to choose the
      * appropriate provider and parameters to compute the location
      * @param listener a {#link LocationListener} whose
-     * {@link LocationListener#onLocationChanged} method will be called for
-     * each location update
+     * {@link LocationListener#onLocationChanged} method will be called when
+     * the location update is available
      * @param looper a Looper object whose message queue will be used to
      * implement the callback mechanism.
      * If looper is null then the callbacks will be called on the current thread.
@@ -795,16 +791,20 @@
     }
 
     /**
-     * Registers the current activity to be notified periodically by
-     * the named provider.  Periodically, the supplied PendingIntent will
-     * be broadcast with the current Location or with status updates.
-     *
-     * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+     * Requests a single location update from the named provider.
      *
      * <p> It may take a while to receive the most recent location. If
      * an immediate location is required, applications may use the
      * {@link #getLastKnownLocation(String)} method.
      *
+     * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+     *
+     * <p> In case the provider is disabled by the user, the update will not be received,
+     * and the {@link LocationListener#onProviderDisabled(String)}
+     * method will be called. As soon as the provider is enabled again,
+     * the {@link LocationListener#onProviderEnabled(String)} method will
+     * be called and location updates will start again.
+     *
      * @param provider the name of the provider with which to register
      * @param intent a {#link PendingIntent} to be sent for the location update
      *
@@ -823,16 +823,20 @@
     }
 
     /**
-     * Registers the current activity to be notified periodically based on
-     * the specified criteria.  Periodically, the supplied PendingIntent will
-     * be broadcast with the current Location or with status updates.
-     *
-     * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+     * Requests a single location update based on the specified criteria.
      *
      * <p> It may take a while to receive the most recent location. If
      * an immediate location is required, applications may use the
      * {@link #getLastKnownLocation(String)} method.
      *
+     * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+     *
+     * <p> In case the provider is disabled by the user, the update will not be received,
+     * and the {@link LocationListener#onProviderDisabled(String)}
+     * method will be called. As soon as the provider is enabled again,
+     * the {@link LocationListener#onProviderEnabled(String)} method will
+     * be called and location updates will start again.
+     *
      * @param criteria contains parameters for the location manager to choose the
      * appropriate provider and parameters to compute the location
      * @param intent a {#link PendingIntent} to be sent for the location update
diff --git a/media/libstagefright/foundation/ALooper.cpp b/media/libstagefright/foundation/ALooper.cpp
index b7087f8..a5b316d 100644
--- a/media/libstagefright/foundation/ALooper.cpp
+++ b/media/libstagefright/foundation/ALooper.cpp
@@ -33,18 +33,30 @@
 struct ALooper::LooperThread : public Thread {
     LooperThread(ALooper *looper, bool canCallJava)
         : Thread(canCallJava),
-          mLooper(looper) {
+          mLooper(looper),
+          mThreadId(NULL) {
+    }
+
+    virtual status_t readyToRun() {
+        mThreadId = androidGetThreadId();
+
+        return Thread::readyToRun();
     }
 
     virtual bool threadLoop() {
         return mLooper->loop();
     }
 
+    bool isCurrentThread() const {
+        return mThreadId == androidGetThreadId();
+    }
+
 protected:
     virtual ~LooperThread() {}
 
 private:
     ALooper *mLooper;
+    android_thread_id_t mThreadId;
 
     DISALLOW_EVIL_CONSTRUCTORS(LooperThread);
 };
@@ -136,7 +148,9 @@
 
     mQueueChangedCondition.signal();
 
-    if (!runningLocally) {
+    if (!runningLocally && !thread->isCurrentThread()) {
+        // If not running locally and this thread _is_ the looper thread,
+        // the loop() function will return and never be called again.
         thread->requestExitAndWait();
     }
 
@@ -197,6 +211,11 @@
 
     gLooperRoster.deliverMessage(event.mMessage);
 
+    // NOTE: It's important to note that at this point our "ALooper" object
+    // may no longer exist (its final reference may have gone away while
+    // delivering the message). We have made sure, however, that loop()
+    // won't be called again.
+
     return true;
 }
 
diff --git a/opengl/libs/GLES2_dbg/src/api.h b/opengl/libs/GLES2_dbg/src/api.h
index 93aef62..b9fc341 100644
--- a/opengl/libs/GLES2_dbg/src/api.h
+++ b/opengl/libs/GLES2_dbg/src/api.h
@@ -22,8 +22,7 @@
     unsigned readSize = GetBytesPerPixel(readFormat, readType) * width * height; \
     void * readData = dbg->GetReadPixelsBuffer(readSize); \
     dbg->hooks->gl.glReadPixels(x, y, width, height, readFormat, readType, readData); \
-    const unsigned compressedSize = dbg->CompressReadPixelBuffer(); \
-    msg.set_data(dbg->lzf_buf, compressedSize); \
+    dbg->CompressReadPixelBuffer(msg.mutable_data()); \
     msg.set_data_type(msg.ReferencedImage); \
     msg.set_pixel_format(readFormat); \
     msg.set_pixel_type(readType);
@@ -43,8 +42,7 @@
         DbgContext * const dbg = getDbgContextThreadSpecific(); \
         const unsigned size = GetBytesPerPixel(format, type) * width * height; \
         assert(0 < size); \
-        unsigned compressedSize = dbg->Compress(pixels, size); \
-        msg.set_data(dbg->lzf_buf, compressedSize); \
+        dbg->Compress(pixels, size, msg.mutable_data()); \
     }
 
 #define EXTEND_Debug_glTexSubImage2D EXTEND_Debug_glTexImage2D
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
index 3ef0752..cc7336c 100644
--- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
+++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
@@ -26,8 +26,7 @@
 
 DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
                        const unsigned MAX_VERTEX_ATTRIBS)
-        : lzf_buf(NULL), lzf_bufSize(0)
-        , lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
+        : lzf_buf(NULL), lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
         , version(version), hooks(hooks)
         , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
         , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
@@ -109,16 +108,26 @@
     }
 }
 
-unsigned DbgContext::Compress(const void * in_data, unsigned in_len)
+void DbgContext::Compress(const void * in_data, unsigned int in_len,
+                          std::string * const outStr)
 {
-    if (lzf_bufSize < in_len * 1.05f) {
-        lzf_bufSize = in_len * 1.05f;
-        lzf_buf = (char *)realloc(lzf_buf, lzf_bufSize);
+    if (!lzf_buf)
+        lzf_buf = (char *)malloc(LZF_CHUNK_SIZE);
+    const uint32_t totalDecompSize = in_len;
+    outStr->append((const char *)&totalDecompSize, sizeof(totalDecompSize));
+    for (unsigned int i = 0; i < in_len; i += LZF_CHUNK_SIZE) {
+        uint32_t chunkSize = LZF_CHUNK_SIZE;
+        if (i + LZF_CHUNK_SIZE > in_len)
+            chunkSize = in_len - i;
+        const uint32_t compSize = lzf_compress((const char *)in_data + i, chunkSize,
+                                               lzf_buf, LZF_CHUNK_SIZE);
+        outStr->append((const char *)&chunkSize, sizeof(chunkSize));
+        outStr->append((const char *)&compSize, sizeof(compSize));
+        if (compSize > 0)
+            outStr->append(lzf_buf, compSize);
+        else // compressed chunk bigger than LZF_CHUNK_SIZE (and uncompressed)
+            outStr->append((const char *)in_data + i, chunkSize);
     }
-    unsigned compressedSize = lzf_compress((const char *)in_data,
-                                           in_len, lzf_buf, lzf_bufSize);
-    assert (0 < compressedSize);
-    return compressedSize;
 }
 
 void * DbgContext::GetReadPixelsBuffer(const unsigned size)
@@ -140,13 +149,13 @@
     return lzf_ref[lzf_readIndex];
 }
 
-unsigned DbgContext::CompressReadPixelBuffer()
+void DbgContext::CompressReadPixelBuffer(std::string * const outStr)
 {
     unsigned * const ref = lzf_ref[lzf_readIndex ^ 1];
     unsigned * const src = lzf_ref[lzf_readIndex];
     for (unsigned i = 0; i < lzf_refSize / sizeof(*ref) + 1; i++)
         ref[i] ^= src[i];
-    return Compress(ref, lzf_refSize);
+    Compress(ref, lzf_refSize, outStr);
 }
 
 void DbgContext::glUseProgram(GLuint program)
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
index 7e9aa4e..9218da5 100644
--- a/opengl/libs/GLES2_dbg/src/header.h
+++ b/opengl/libs/GLES2_dbg/src/header.h
@@ -56,21 +56,18 @@
 namespace android
 {
 
-struct GLFunctionBitfield
-{
+struct GLFunctionBitfield {
     unsigned char field [24]; // 8 * 24 = 192
-    
-    void Bit(const glesv2debugger::Message_Function function, bool bit)
-    {
+
+    void Bit(const glesv2debugger::Message_Function function, bool bit) {
         const unsigned byte = function / 8, mask = 1 << (function % 8);
         if (bit)
             field[byte] |= mask;
         else
             field[byte] &= ~mask;
     }
-    
-    bool Bit(const glesv2debugger::Message_Function function) const
-    {
+
+    bool Bit(const glesv2debugger::Message_Function function) const {
         const unsigned byte = function / 8, mask = 1 << (function % 8);
         return field[byte] & mask;
     }
@@ -78,7 +75,8 @@
 
 struct DbgContext {
 private:
-    unsigned lzf_bufSize;
+    static const unsigned int LZF_CHUNK_SIZE = 256 * 1024;
+    char * lzf_buf; // malloc / free; for lzf chunk compression
 
     // used as buffer and reference frame for ReadPixels; malloc/free
     unsigned * lzf_ref [2];
@@ -86,14 +84,12 @@
     unsigned lzf_refSize, lzf_refBufSize; // bytes
 
 public:
-    char * lzf_buf; // auto malloc/free; output of lzf_compress
-
     const unsigned version; // 0 is GLES1, 1 is GLES2
     const gl_hooks_t * const hooks;
     const unsigned MAX_VERTEX_ATTRIBS;
-    
+
     GLFunctionBitfield expectResponse;
-    
+
     struct VertexAttrib {
         GLenum type; // element data type
         unsigned size; // number of data per element
@@ -122,21 +118,23 @@
     GLuint program;
     unsigned maxAttrib; // number of slots used by program
 
-    DbgContext(const unsigned version, const gl_hooks_t * const hooks, const unsigned MAX_VERTEX_ATTRIBS);
+    DbgContext(const unsigned version, const gl_hooks_t * const hooks,
+               const unsigned MAX_VERTEX_ATTRIBS);
     ~DbgContext();
 
     void Fetch(const unsigned index, std::string * const data) const;
-    unsigned Compress(const void * in_data, unsigned in_len); // compressed to lzf_buf
+    void Compress(const void * in_data, unsigned in_len, std::string * const outStr);
     void * GetReadPixelsBuffer(const unsigned size);
     bool IsReadPixelBuffer(const void * const ptr)  {
         return ptr == lzf_ref[lzf_readIndex];
     }
-    unsigned CompressReadPixelBuffer();
+    void CompressReadPixelBuffer(std::string * const outStr);
 
     void glUseProgram(GLuint program);
     void glEnableVertexAttribArray(GLuint index);
     void glDisableVertexAttribArray(GLuint index);
-    void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+    void glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
+                               GLboolean normalized, GLsizei stride, const GLvoid* ptr);
     void glBindBuffer(GLenum target, GLuint buffer);
     void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
     void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
@@ -148,7 +146,8 @@
 #define DBGCONTEXT(ctx) DbgContext * const ctx = getDbgContextThreadSpecific();
 
 struct FunctionCall {
-    virtual const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) = 0;
+    virtual const int * operator()(gl_hooks_t::gl_t const * const _c,
+                                   glesv2debugger::Message & msg) = 0;
     virtual ~FunctionCall() {}
 };
 
@@ -168,5 +167,5 @@
 float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
 void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd);
 const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
-                  glesv2debugger::Message & msg, const int * const prevRet);
+                         glesv2debugger::Message & msg, const int * const prevRet);
 }; // namespace android {
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
index a9cf9e7..471e5ad 100644
--- a/opengl/libs/GLES2_dbg/src/vertex.cpp
+++ b/opengl/libs/GLES2_dbg/src/vertex.cpp
@@ -39,7 +39,6 @@
     msg.set_arg6(reinterpret_cast<int>(pixels));
 
     const unsigned size = width * height * GetBytesPerPixel(format, type);
-    unsigned compressed = 0;
     if (!expectResponse)
         cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
     Send(msg, cmd);
@@ -56,13 +55,12 @@
             msg.set_type(glesv2debugger::Message_Type_AfterCall);
             msg.set_expect_response(expectResponse);
             if (dbg->IsReadPixelBuffer(pixels)) {
-                compressed = dbg->CompressReadPixelBuffer();
+                dbg->CompressReadPixelBuffer(msg.mutable_data());
                 msg.set_data_type(msg.ReferencedImage);
             } else {
-                compressed = dbg->Compress(pixels, size);
+                dbg->Compress(pixels, size, msg.mutable_data());
                 msg.set_data_type(msg.NonreferencedImage);
             }
-            msg.set_data(dbg->lzf_buf, compressed);
             if (!expectResponse)
                 cmd.set_function(glesv2debugger::Message_Function_SKIP);
             Send(msg, cmd);