Merge "Don't let email addresses in database names get into the EventLog."
diff --git a/camera/libcameraservice/FakeCamera.cpp b/camera/libcameraservice/FakeCamera.cpp
index 3daf47d..6749899 100644
--- a/camera/libcameraservice/FakeCamera.cpp
+++ b/camera/libcameraservice/FakeCamera.cpp
@@ -234,7 +234,7 @@
             uint8_t   y0, y1, u, v;
 
             pixels =  inputRGB[i];
-            temp = (ALPHA*(pixels & 0x001F) + BETA*(pixels>>11) );
+            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
             y0   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
 
             G_ds    += (pixels>>1) & 0x03E0;
@@ -242,7 +242,7 @@
             R_ds    += (pixels>>6) & 0x03E0;
 
             pixels =  inputRGB[i+1];
-            temp = (ALPHA*(pixels & 0x001F) + BETA*(pixels>>11) );
+            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
             y1   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
 
             G_ds    += (pixels>>1) & 0x03E0;
@@ -255,8 +255,8 @@
 
             tmp = R_ds - B_ds;
 
-            u = cb_tab[(((R_ds-G_ds)<<SHIFT2) + DELTA*tmp)>>(SHIFT2+2)];
-            v = cr_tab[(((B_ds-G_ds)<<SHIFT2) - GAMMA*tmp)>>(SHIFT2+2)];
+            u = cb_tab[(((B_ds-G_ds)<<SHIFT2) - GAMMA*tmp)>>(SHIFT2+2)];
+            v = cr_tab[(((R_ds-G_ds)<<SHIFT2) + DELTA*tmp)>>(SHIFT2+2)];
 
             tempY[0] = y0;
             tempY[1] = y1;
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index c7b12d3..0c7ca83 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -158,12 +158,35 @@
             time = Math.max(time, moratoriumTimeMillis);
         }
         time = Math.max(time, lastSuccessTimeMillis + options.minTriggerMillis);
-        time = Math.max(time, lastErrorTimeMillis + options.backoffFixedMillis +
-                options.backoffIncrementalMillis * errorCount);
+        if (errorCount > 0) {
+            time = Math.max(time, lastErrorTimeMillis + options.backoffFixedMillis +
+                    options.backoffIncrementalMillis * errorCount);
+        }
         return time;
     }
 
     /**
+     * Return the last time the operation completed.  Does not modify any state.
+     *
+     * @return the wall clock time when {@link #onSuccess()} was last called.
+     */
+    public long getLastSuccessTimeMillis() {
+        return mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0);
+    }
+
+    /**
+     * Return the last time the operation was attempted.  Does not modify any state.
+     *
+     * @return the wall clock time when {@link #onSuccess()} or {@link
+     * #onTransientError()} was last called.
+     */
+    public long getLastAttemptTimeMillis() {
+        return Math.max(
+                mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0),
+                mStorage.getLong(PREFIX + "lastErrorTimeMillis", 0));
+    }
+
+    /**
      * Fetch a {@link SharedPreferences} property, but force it to be before
      * a certain time, updating the value if necessary.  This is to recover
      * gracefully from clock rollbacks which could otherwise strand our timers.
@@ -273,9 +296,7 @@
      * where there is reason to hope things might start working better.
      */
     public void resetTransientError() {
-        mStorage.edit()
-                .remove(PREFIX + "lastErrorTimeMillis")
-                .remove(PREFIX + "errorCount").commit();
+        mStorage.edit().remove(PREFIX + "errorCount").commit();
     }
 
     /**
diff --git a/common/tests/src/com/android/common/OperationSchedulerTest.java b/common/tests/src/com/android/common/OperationSchedulerTest.java
index 28178b5..f728eea 100644
--- a/common/tests/src/com/android/common/OperationSchedulerTest.java
+++ b/common/tests/src/com/android/common/OperationSchedulerTest.java
@@ -28,6 +28,8 @@
         OperationScheduler scheduler = new OperationScheduler(storage);
         OperationScheduler.Options options = new OperationScheduler.Options();
         assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
+        assertEquals(0, scheduler.getLastSuccessTimeMillis());
+        assertEquals(0, scheduler.getLastAttemptTimeMillis());
 
         long beforeTrigger = System.currentTimeMillis();
         scheduler.setTriggerTimeMillis(beforeTrigger + 1000000);
@@ -49,6 +51,9 @@
         long beforeError = System.currentTimeMillis();
         scheduler.onTransientError();
         long afterError = System.currentTimeMillis();
+        assertEquals(0, scheduler.getLastSuccessTimeMillis());
+        assertTrue(beforeError <= scheduler.getLastAttemptTimeMillis());
+        assertTrue(afterError >= scheduler.getLastAttemptTimeMillis());
         assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
         options.backoffFixedMillis = 1000000;
         options.backoffIncrementalMillis = 500000;
@@ -59,9 +64,18 @@
         beforeError = System.currentTimeMillis();
         scheduler.onTransientError();
         afterError = System.currentTimeMillis();
+        assertTrue(beforeError <= scheduler.getLastAttemptTimeMillis());
+        assertTrue(afterError >= scheduler.getLastAttemptTimeMillis());
         assertTrue(beforeError + 2000000 <= scheduler.getNextTimeMillis(options));
         assertTrue(afterError + 2000000 >= scheduler.getNextTimeMillis(options));
 
+        // Reset transient error: no backoff interval
+        scheduler.resetTransientError();
+        assertEquals(0, scheduler.getLastSuccessTimeMillis());
+        assertEquals(beforeTrigger + 1500000, scheduler.getNextTimeMillis(options));
+        assertTrue(beforeError <= scheduler.getLastAttemptTimeMillis());
+        assertTrue(afterError >= scheduler.getLastAttemptTimeMillis());
+
         // Permanent error holds true even if transient errors are reset
         // However, we remember that the transient error was reset...
         scheduler.onPermanentError();
@@ -75,6 +89,10 @@
         long beforeSuccess = System.currentTimeMillis();
         scheduler.onSuccess();
         long afterSuccess = System.currentTimeMillis();
+        assertTrue(beforeSuccess <= scheduler.getLastAttemptTimeMillis());
+        assertTrue(afterSuccess >= scheduler.getLastAttemptTimeMillis());
+        assertTrue(beforeSuccess <= scheduler.getLastSuccessTimeMillis());
+        assertTrue(afterSuccess >= scheduler.getLastSuccessTimeMillis());
         assertEquals(Long.MAX_VALUE, scheduler.getNextTimeMillis(options));
 
         // The moratorium is not reset by success!
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 2bcad5b..925fd06 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <utils/Vector.h>
-#include <binder/Parcel.h>
 
 #include <ui/Rect.h>
 
@@ -39,7 +38,6 @@
                         Region();
                         Region(const Region& rhs);
     explicit            Region(const Rect& rhs);
-    explicit            Region(const Parcel& parcel);
     explicit            Region(const void* buffer);
                         ~Region();
                         
@@ -118,10 +116,6 @@
             // be sorted in Y and X and must not make the region invalid.
             void        addRectUnchecked(int l, int t, int r, int b);
 
-            // flatten/unflatten a region to/from a Parcel
-            status_t    write(Parcel& parcel) const;
-            status_t    read(const Parcel& parcel);
-
             // flatten/unflatten a region to/from a raw buffer
             ssize_t     write(void* buffer, size_t size) const;
     static  ssize_t     writeEmpty(void* buffer, size_t size);
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 5b96e9d..a3d293f 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -52,6 +52,7 @@
       mTransformed(false),
       mUseLinearFiltering(false),
       mOrientation(0),
+      mLeft(0), mTop(0),
       mTransactionFlags(0),
       mPremultipliedAlpha(true),
       mInvalidate(0)
diff --git a/libs/surfaceflinger_client/LayerState.cpp b/libs/surfaceflinger_client/LayerState.cpp
index 114a9e9..01c4c7e 100644
--- a/libs/surfaceflinger_client/LayerState.cpp
+++ b/libs/surfaceflinger_client/LayerState.cpp
@@ -22,17 +22,37 @@
 
 status_t layer_state_t::write(Parcel& output) const
 {
+    status_t err;
+
+    size_t len = transparentRegion.write(NULL, 0);
+    err = output.writeInt32(len);
+    if (err < NO_ERROR) return err;
+
+    void* buf = output.writeInplace(len);
+    if (buf == NULL) return NO_MEMORY;
+
+    err = transparentRegion.write(buf, len);
+    if (err < NO_ERROR) return err;
+
+    // NOTE: regions are at the end of the structure
     size_t size = sizeof(layer_state_t);
-    transparentRegion.write(output);
     size -= sizeof(transparentRegion);
-    output.write(this, size);
-    return NO_ERROR;
+    err = output.write(this, size);
+    return err;
 }
 
 status_t layer_state_t::read(const Parcel& input)
 {
+    status_t err;
+    size_t len = input.readInt32();
+    void const* buf = input.readInplace(len);
+    if (buf == NULL) return NO_MEMORY;
+
+    err = transparentRegion.read(buf);
+    if (err < NO_ERROR) return err;
+
+    // NOTE: regions are at the end of the structure
     size_t size = sizeof(layer_state_t);
-    transparentRegion.read(input);
     size -= sizeof(transparentRegion);
     input.read(this, size);
     return NO_ERROR;
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index d21ed57..12db908 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -63,16 +63,10 @@
 {
 }
 
-Region::Region(const Parcel& parcel)
-{
-    status_t err = read(parcel);
-    LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err));
-}
-
 Region::Region(const void* buffer)
 {
     status_t err = read(buffer);
-    LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err));
+    LOGE_IF(err<0, "error %s reading Region from buffer", strerror(err));
 }
 
 Region::~Region()
@@ -532,37 +526,6 @@
 
 // ----------------------------------------------------------------------------
 
-status_t Region::write(Parcel& parcel) const
-{
-#if VALIDATE_REGIONS
-    validate(*this, "write(Parcel)");
-#endif
-    status_t err;
-    const size_t count = mStorage.size();
-    const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
-    void* buffer = parcel.writeInplace(sizeNeeded);
-    if (!buffer) return NO_MEMORY;
-    ssize_t written = Region::write(buffer, sizeNeeded);
-    if (written < 0) return status_t(written);
-    return NO_ERROR;
-}
-
-status_t Region::read(const Parcel& parcel)
-{
-    void const* buffer = parcel.readInplace(sizeof(int32_t));
-    if (!buffer) return NO_MEMORY;
-    const size_t count = *static_cast<int32_t const *>(buffer);
-    void const* dummy = parcel.readInplace((1+count)*sizeof(Rect));
-    if (!dummy) return NO_MEMORY;
-    const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
-    const ssize_t read = Region::read(buffer);
-    if (read < 0) return status_t(read);
-#if VALIDATE_REGIONS
-    validate(*this, "read(Parcel)");
-#endif
-    return NO_ERROR;
-}
-
 ssize_t Region::write(void* buffer, size_t size) const
 {
 #if VALIDATE_REGIONS
@@ -570,12 +533,14 @@
 #endif
     const size_t count = mStorage.size();
     const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
-    if (sizeNeeded > size) return NO_MEMORY;
-    int32_t* const p = static_cast<int32_t*>(buffer); 
-    *p = count;
-    memcpy(p+1, &mBounds, sizeof(Rect));
-    if (count) {
-        memcpy(p+5, mStorage.array(), count*sizeof(Rect));
+    if (buffer != NULL) {
+        if (sizeNeeded > size) return NO_MEMORY;
+        int32_t* const p = static_cast<int32_t*>(buffer);
+        *p = count;
+        memcpy(p+1, &mBounds, sizeof(Rect));
+        if (count) {
+            memcpy(p+5, mStorage.array(), count*sizeof(Rect));
+        }
     }
     return ssize_t(sizeNeeded);
 }