Merge "Finalize wifi watchdog default settings"
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 392193b..5ccf87f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -78,12 +78,8 @@
 // conditionals don't get stripped...  but that is probably what we want.
 #if !LOG_NDEBUG
 static const char *kReturnStrings[] = {
-#if 1 /* TODO: error update strings */
-    "unknown",
-#else
+    "BR_ERROR",
     "BR_OK",
-    "BR_TIMEOUT",
-    "BR_WAKEUP",
     "BR_TRANSACTION",
     "BR_REPLY",
     "BR_ACQUIRE_RESULT",
@@ -94,25 +90,19 @@
     "BR_RELEASE",
     "BR_DECREFS",
     "BR_ATTEMPT_ACQUIRE",
-    "BR_EVENT_OCCURRED",
     "BR_NOOP",
     "BR_SPAWN_LOOPER",
     "BR_FINISHED",
     "BR_DEAD_BINDER",
-    "BR_CLEAR_DEATH_NOTIFICATION_DONE"
-#endif
+    "BR_CLEAR_DEATH_NOTIFICATION_DONE",
+    "BR_FAILED_REPLY"
 };
 
 static const char *kCommandStrings[] = {
-#if 1 /* TODO: error update strings */
-    "unknown",
-#else
-    "BC_NOOP",
     "BC_TRANSACTION",
     "BC_REPLY",
     "BC_ACQUIRE_RESULT",
     "BC_FREE_BUFFER",
-    "BC_TRANSACTION_COMPLETE",
     "BC_INCREFS",
     "BC_ACQUIRE",
     "BC_RELEASE",
@@ -120,18 +110,12 @@
     "BC_INCREFS_DONE",
     "BC_ACQUIRE_DONE",
     "BC_ATTEMPT_ACQUIRE",
-    "BC_RETRIEVE_ROOT_OBJECT",
-    "BC_SET_THREAD_ENTRY",
     "BC_REGISTER_LOOPER",
     "BC_ENTER_LOOPER",
     "BC_EXIT_LOOPER",
-    "BC_SYNC",
-    "BC_STOP_PROCESS",
-    "BC_STOP_SELF",
     "BC_REQUEST_DEATH_NOTIFICATION",
     "BC_CLEAR_DEATH_NOTIFICATION",
     "BC_DEAD_BINDER_DONE"
-#endif
 };
 
 static const char* getReturnString(size_t idx)
@@ -154,30 +138,36 @@
 {
     const binder_transaction_data* btd =
         (const binder_transaction_data*)data;
-    out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
+    if (btd->target.handle < 1024) {
+        /* want to print descriptors in decimal; guess based on value */
+        out << "target.desc=" << btd->target.handle;
+    } else {
+        out << "target.ptr=" << btd->target.ptr;
+    }
+    out << " (cookie " << btd->cookie << ")" << endl
         << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
         << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
         << " bytes)" << endl
         << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
-        << " bytes)" << endl;
+        << " bytes)";
     return btd+1;
 }
 
 static const void* printReturnCommand(TextOutput& out, const void* _cmd)
 {
-    static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
-    
+    static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
     const int32_t* cmd = (const int32_t*)_cmd;
     int32_t code = *cmd++;
-    if (code == BR_ERROR) {
+    size_t cmdIndex = code & 0xff;
+    if (code == (int32_t) BR_ERROR) {
         out << "BR_ERROR: " << (void*)(*cmd++) << endl;
         return cmd;
-    } else if (code < 0 || code >= N) {
+    } else if (cmdIndex >= N) {
         out << "Unknown reply: " << code << endl;
         return cmd;
     }
+    out << kReturnStrings[cmdIndex];
     
-    out << kReturnStrings[code];
     switch (code) {
         case BR_TRANSACTION:
         case BR_REPLY: {
@@ -213,6 +203,11 @@
             const int32_t c = *cmd++;
             out << ": death cookie " << (void*)c;
         } break;
+
+        default:
+            // no details to show for: BR_OK, BR_DEAD_REPLY,
+            // BR_TRANSACTION_COMPLETE, BR_FINISHED
+            break;
     }
     
     out << endl;
@@ -221,16 +216,17 @@
 
 static const void* printCommand(TextOutput& out, const void* _cmd)
 {
-    static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
-    
+    static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
     const int32_t* cmd = (const int32_t*)_cmd;
     int32_t code = *cmd++;
-    if (code < 0 || code >= N) {
+    size_t cmdIndex = code & 0xff;
+
+    if (cmdIndex >= N) {
         out << "Unknown command: " << code << endl;
         return cmd;
     }
-    
-    out << kCommandStrings[code];
+    out << kCommandStrings[cmdIndex];
+
     switch (code) {
         case BC_TRANSACTION:
         case BC_REPLY: {
@@ -254,7 +250,7 @@
         case BC_RELEASE:
         case BC_DECREFS: {
             const int32_t d = *cmd++;
-            out << ": descriptor=" << (void*)d;
+            out << ": desc=" << d;
         } break;
     
         case BC_INCREFS_DONE:
@@ -267,7 +263,7 @@
         case BC_ATTEMPT_ACQUIRE: {
             const int32_t p = *cmd++;
             const int32_t d = *cmd++;
-            out << ": decriptor=" << (void*)d << ", pri=" << p;
+            out << ": desc=" << d << ", pri=" << p;
         } break;
         
         case BC_REQUEST_DEATH_NOTIFICATION:
@@ -281,6 +277,11 @@
             const int32_t c = *cmd++;
             out << ": death cookie " << (void*)c;
         } break;
+
+        default:
+            // no details to show for: BC_REGISTER_LOOPER, BC_ENTER_LOOPER,
+            // BC_EXIT_LOOPER
+            break;
     }
     
     out << endl;
@@ -592,6 +593,7 @@
 
 status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
 {
+    LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
     mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
     mOut.writeInt32(0); // xxx was thread priority
     mOut.writeInt32(handle);
@@ -772,7 +774,7 @@
     } else {
         bwr.read_size = 0;
     }
-    
+
     IF_LOG_COMMANDS() {
         TextOutput::Bundle _b(alog);
         if (outAvail != 0) {
@@ -789,7 +791,7 @@
     
     // Return immediately if there is nothing to do.
     if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
-    
+
     bwr.write_consumed = 0;
     bwr.read_consumed = 0;
     status_t err;
@@ -809,7 +811,7 @@
             alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
         }
     } while (err == -EINTR);
-    
+
     IF_LOG_COMMANDS() {
         alog << "Our err: " << (void*)err << ", write consumed: "
             << bwr.write_consumed << " (of " << mOut.dataSize()
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
index 4dfa578..ceca435 100644
--- a/libs/utils/Static.cpp
+++ b/libs/utils/Static.cpp
@@ -56,7 +56,9 @@
 protected:
     virtual status_t writeLines(const struct iovec& vec, size_t N)
     {
-        android_writevLog(&vec, N);
+        //android_writevLog(&vec, N);       <-- this is now a no-op
+        if (N != 1) LOGI("WARNING: writeLines N=%d\n", N);
+        LOGI("%.*s", vec.iov_len, (const char*) vec.iov_base);
         return NO_ERROR;
     }
 };
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0ff1cce..c9567d5 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -22,6 +22,7 @@
 
 #include <utils/Errors.h>
 #include <utils/String8.h>
+#include <utils/Vector.h>
 
 #include <hardware/hardware.h>
 
@@ -29,6 +30,7 @@
 
 #include <EGL/egl.h>
 
+#include "LayerBase.h"
 #include "HWComposer.h"
 #include "SurfaceFlinger.h"
 
@@ -133,7 +135,8 @@
     return mList ? mList->hwLayers : 0;
 }
 
-void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
+void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
+        const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
     if (mHwc && mList) {
         result.append("Hardware Composer state:\n");
 
@@ -143,11 +146,12 @@
 
         for (size_t i=0 ; i<mList->numHwLayers ; i++) {
             const hwc_layer_t& l(mList->hwLayers[i]);
-            snprintf(buffer, SIZE, "  %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] |  [%5d,%5d,%5d,%5d]\n",
+            snprintf(buffer, SIZE, "  %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] |  [%5d,%5d,%5d,%5d] %s\n",
                     l.compositionType ? "OVERLAY" : "FB",
                     l.hints, l.flags, l.transform, l.blending,
                     l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
-                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom);
+                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
+                    visibleLayersSortedByZ[i]->getName().string());
             result.append(buffer);
         }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 77c1a4b..8758a80 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -25,12 +25,14 @@
 #include <hardware/hwcomposer.h>
 
 #include <utils/StrongPointer.h>
+#include <utils/Vector.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
 
 class String8;
 class SurfaceFlinger;
+class LayerBase;
 
 class HWComposer
 {
@@ -63,7 +65,8 @@
     hwc_layer_t* getLayers() const;
 
     // for debugging
-    void dump(String8& out, char* scratch, size_t SIZE) const;
+    void dump(String8& out, char* scratch, size_t SIZE,
+            const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
 
 private:
     struct cb_context {
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 603fb60..e5ce814 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -43,7 +43,7 @@
     : dpy(display), contentDirty(false),
       sequence(uint32_t(android_atomic_inc(&sSequence))),
       mFlinger(flinger), mFiltering(false),
-      mNeedsFiltering(false),
+      mNeedsFiltering(false), mInOverlay(false),
       mOrientation(0),
       mTransactionFlags(0),
       mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
@@ -344,6 +344,14 @@
     hwcl->handle = NULL;
 }
 
+void LayerBase::setOverlay(bool inOverlay) {
+    mInOverlay = inOverlay;
+}
+
+bool LayerBase::isOverlay() const {
+    return mInOverlay;
+}
+
 void LayerBase::setFiltering(bool filtering)
 {
     mFiltering = filtering;
@@ -472,12 +480,13 @@
 {
     const Layer::State& s(drawingState());
     snprintf(buffer, SIZE,
-            "+ %s %p\n"
+            "+ %s %p (%s)\n"
             "      "
             "z=%9d, pos=(%g,%g), size=(%4d,%4d), "
             "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-            getTypeId(), this, s.z, s.transform.tx(), s.transform.ty(), s.w, s.h,
+            getTypeId(), this, getName().string(),
+            s.z, s.transform.tx(), s.transform.ty(), s.w, s.h,
             isOpaque(), needsDithering(), contentDirty,
             s.alpha, s.flags,
             s.transform[0][0], s.transform[0][1],
@@ -553,9 +562,7 @@
 
     sp<Client> client(mClientRef.promote());
     snprintf(buffer, SIZE,
-            "      name=%s\n"
             "      client=%p, identity=%u\n",
-            getName().string(),
             client.get(), getIdentity());
 
     result.append(buffer);
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index d20f06a..ee50428 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -109,8 +109,10 @@
     virtual const char* getTypeId() const { return "LayerBase"; }
 
     virtual void setGeometry(hwc_layer_t* hwcl);
-
     virtual void setPerFrameData(hwc_layer_t* hwcl);
+            void setOverlay(bool inOverlay);
+            bool isOverlay() const;
+
 
     /**
      * draw - performs some global clipping optimizations
@@ -242,6 +244,11 @@
                 // Whether filtering is needed b/c of the drawingstate
                 bool            mNeedsFiltering;
 
+                // this layer is currently handled by the hwc. this is
+                // updated at composition time, always frmo the composition
+                // thread.
+                bool            mInOverlay;
+
 protected:
                 // cached during validateVisibility()
                 int32_t         mOrientation;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4a3a8ea..df13640 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -817,20 +817,6 @@
     mHwWorkListDirty = false;
     HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
     if (hwc.initCheck() == NO_ERROR) {
-
-        const DisplayHardware& hw(graphicPlane(0).displayHardware());
-        uint32_t flags = hw.getFlags();
-        if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
-            (flags & DisplayHardware::BUFFER_PRESERVED))
-        {
-            // we need to redraw everything (the whole screen)
-            // NOTE: we could be more subtle here and redraw only
-            // the area which will end-up in an overlay. But since this
-            // shouldn't happen often, we invalidate everything.
-            mDirtyRegion.set(hw.bounds());
-            mInvalidRegion = mDirtyRegion;
-        }
-
         const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
         const size_t count = currentLayers.size();
         hwc.createWorkList(count);
@@ -890,30 +876,30 @@
         }
     }
 
-    // compose all surfaces
+    Region expandDirty = setupHardwareComposer(mDirtyRegion);
+    mDirtyRegion.orSelf(expandDirty);
+    mInvalidRegion.orSelf(mDirtyRegion);
     composeSurfaces(mDirtyRegion);
 
     // clear the dirty regions
     mDirtyRegion.clear();
 }
 
-void SurfaceFlinger::composeSurfaces(const Region& dirty)
+Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
 {
-    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
-        // should never happen unless the window manager has a bug
-        // draw something...
-        drawWormhole();
-    }
-
-    status_t err = NO_ERROR;
-    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
-    size_t count = layers.size();
+    Region dirtyOut(dirty);
 
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     HWComposer& hwc(hw.getHwComposer());
     hwc_layer_t* const cur(hwc.getLayers());
+    if (!cur) {
+        return dirtyOut;
+    }
 
-    LOGE_IF(cur && hwc.getNumLayers() != count,
+    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    size_t count = layers.size();
+
+    LOGE_IF(hwc.getNumLayers() != count,
             "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
             hwc.getNumLayers(), count);
 
@@ -926,57 +912,95 @@
      *  update the per-frame h/w composer data for each layer
      *  and build the transparent region of the FB
      */
-    Region transparent;
-    if (cur) {
-        for (size_t i=0 ; i<count ; i++) {
-            const sp<LayerBase>& layer(layers[i]);
-            layer->setPerFrameData(&cur[i]);
-        }
-        err = hwc.prepare();
-        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
+    for (size_t i=0 ; i<count ; i++) {
+        const sp<LayerBase>& layer(layers[i]);
+        layer->setPerFrameData(&cur[i]);
+    }
+    status_t err = hwc.prepare();
+    LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
 
-        if (err == NO_ERROR) {
-            for (size_t i=0 ; i<count ; i++) {
-                if (cur[i].hints & HWC_HINT_CLEAR_FB) {
-                    const sp<LayerBase>& layer(layers[i]);
-                    if (layer->isOpaque()) {
-                        transparent.orSelf(layer->visibleRegionScreen);
-                    }
-                }
+    if (err == NO_ERROR) {
+        Region transparent;
+        for (size_t i=0 ; i<count ; i++) {
+            // what's happening here is tricky.
+            // we want to clear all the layers with the CLEAR_FB flags
+            // that are opaque.
+            // however, since some GPU have are efficient at preserving
+            // the backbuffer, we want to take advantage of that so we do the
+            // clear only in the dirty region (other areas will be preserved
+            // on those GPUs).
+            //   NOTE: on non backbuffer preserving GPU, the dirty region
+            //   has already been expanded as needed, so the code is correct
+            //   there too.
+            // However, the content of the framebuffer cannot be trusted when
+            // we switch to/from FB/OVERLAY, in which case we need to
+            // expand the dirty region to those areas too.
+            //
+            // Also we want to make sure to not clear areas that belong to
+            // layers above that won't redraw (we would just erasing them),
+            // that is, we can't erase anything outside the dirty region.
+
+            const sp<LayerBase>& layer(layers[i]);
+            if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
+                transparent.orSelf(layer->visibleRegionScreen);
             }
 
-            /*
-             *  clear the area of the FB that need to be transparent
-             */
-            transparent.andSelf(dirty);
-            if (!transparent.isEmpty()) {
-                glClearColor(0,0,0,0);
-                Region::const_iterator it = transparent.begin();
-                Region::const_iterator const end = transparent.end();
-                const int32_t height = hw.getHeight();
-                while (it != end) {
-                    const Rect& r(*it++);
-                    const GLint sy = height - (r.top + r.height());
-                    glScissor(r.left, sy, r.width(), r.height());
-                    glClear(GL_COLOR_BUFFER_BIT);
-                }
+            bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) &&
+                !(cur[i].flags & HWC_SKIP_LAYER);
+
+            if (isOverlay != layer->isOverlay()) {
+                // we transitioned to/from overlay, so add this layer
+                // to the dirty region so the framebuffer can be either
+                // cleared or redrawn.
+                dirtyOut.orSelf(layer->visibleRegionScreen);
+            }
+            layer->setOverlay(isOverlay);
+        }
+
+
+        /*
+         *  clear the area of the FB that need to be transparent
+         */
+        // don't erase stuff outside the dirty region
+        transparent.andSelf(dirtyOut);
+        if (!transparent.isEmpty()) {
+            glClearColor(0,0,0,0);
+            Region::const_iterator it = transparent.begin();
+            Region::const_iterator const end = transparent.end();
+            const int32_t height = hw.getHeight();
+            while (it != end) {
+                const Rect& r(*it++);
+                const GLint sy = height - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glClear(GL_COLOR_BUFFER_BIT);
             }
         }
     }
+    return dirtyOut;
+}
 
+void SurfaceFlinger::composeSurfaces(const Region& dirty)
+{
+    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
+        // should never happen unless the window manager has a bug
+        // draw something...
+        drawWormhole();
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    HWComposer& hwc(hw.getHwComposer());
+    hwc_layer_t* const cur(hwc.getLayers());
 
     /*
      * and then, render the layers targeted at the framebuffer
      */
+    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    size_t count = layers.size();
     for (size_t i=0 ; i<count ; i++) {
-        if (cur) {
-            if ((cur[i].compositionType != HWC_FRAMEBUFFER) &&
+        if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) &&
                 !(cur[i].flags & HWC_SKIP_LAYER)) {
-                // skip layers handled by the HAL
-                continue;
-            }
+            continue;
         }
-
         const sp<LayerBase>& layer(layers[i]);
         const Region clip(dirty.intersect(layer->visibleRegionScreen));
         if (!clip.isEmpty()) {
@@ -1597,7 +1621,7 @@
                 hwc.initCheck()==NO_ERROR ? "present" : "not present",
                 (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
         result.append(buffer);
-        hwc.dump(result, buffer, SIZE);
+        hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
 
         /*
          * Dump gralloc state
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5f8eb08..126ca39 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -277,6 +277,7 @@
             void        handleWorkList();
             void        handleRepaint();
             void        postFramebuffer();
+            Region      setupHardwareComposer(const Region& dirty);
             void        composeSurfaces(const Region& dirty);
             void        repaintEverything();