Merge "Added bitwise-or and bitwise-and to BitSet"
diff --git a/include/android/input.h b/include/android/input.h
index c8ac938..fead769 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -692,7 +692,7 @@
 
 /* Get the time that a historical movement occurred between this event and
  * the previous event, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
+int64_t AMotionEvent_getHistoricalEventTime(const AInputEvent* motion_event,
         size_t history_index);
 
 /* Get the historical raw X coordinate of this event for the given pointer index that
@@ -719,14 +719,14 @@
  * occurred between this event and the previous motion event.
  * Whole numbers are pixels; the value may have a fraction for input devices
  * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalX(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical Y coordinate of this event for the given pointer index that
  * occurred between this event and the previous motion event.
  * Whole numbers are pixels; the value may have a fraction for input devices
  * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalY(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical pressure of this event for the given pointer index that
@@ -734,7 +734,7 @@
  * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
  * although values higher than 1 may be generated depending on the calibration of
  * the input device. */
-float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalPressure(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the current scaled value of the approximate size for the given pointer index that
@@ -744,7 +744,7 @@
  * touch is normalized with the device specific range of values
  * and scaled to a value between 0 and 1.  The value of size can be used to
  * determine fat touch events. */
-float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalSize(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical length of the major axis of an ellipse that describes the touch area
diff --git a/include/binder/TextOutput.h b/include/binder/TextOutput.h
index de2fbbe..974a194 100644
--- a/include/binder/TextOutput.h
+++ b/include/binder/TextOutput.h
@@ -25,6 +25,9 @@
 // ---------------------------------------------------------------------------
 namespace android {
 
+class String8;
+class String16;
+
 class TextOutput
 {
 public:
@@ -76,6 +79,8 @@
 TextOutput& operator<<(TextOutput& to, double);
 TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func);
 TextOutput& operator<<(TextOutput& to, const void*);
+TextOutput& operator<<(TextOutput& to, const String8& val);
+TextOutput& operator<<(TextOutput& to, const String16& val);
 
 class TypeCode 
 {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index aa19d17..359742c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1473,6 +1473,8 @@
         if (objectsSize) {
             objects = (size_t*)malloc(objectsSize*sizeof(size_t));
             if (!objects) {
+                free(data);
+
                 mError = NO_MEMORY;
                 return NO_MEMORY;
             }
@@ -1553,7 +1555,7 @@
             mError = NO_MEMORY;
             return NO_MEMORY;
         }
-        
+
         if(!(mDataCapacity == 0 && mObjects == NULL
              && mObjectsCapacity == 0)) {
             ALOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
diff --git a/libs/binder/TextOutput.cpp b/libs/binder/TextOutput.cpp
index 9637334..db3e858 100644
--- a/libs/binder/TextOutput.cpp
+++ b/libs/binder/TextOutput.cpp
@@ -18,6 +18,9 @@
 
 #include <binder/Debug.h>
 
+#include <utils/String8.h>
+#include <utils/String16.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -119,6 +122,18 @@
     return to;
 }
 
+TextOutput& operator<<(TextOutput& to, const String8& val)
+{
+    to << val.string();
+    return to;
+}
+
+TextOutput& operator<<(TextOutput& to, const String16& val)
+{
+    to << String8(val).string();
+    return to;
+}
+
 static void textOutputPrinter(void* cookie, const char* txt)
 {
     ((TextOutput*)cookie)->print(txt, strlen(txt));
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 74d3973..334e164 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1177,6 +1177,11 @@
 {
     clearError();
 
+#if EGL_TRACE
+    if (getEGLDebugLevel() > 0)
+        GLTrace_eglReleaseThread();
+#endif
+
     // If there is context bound to the thread, release it
     egl_display_t::loseCurrent(get_context(getContext()));
 
@@ -1184,12 +1189,7 @@
     if (cnx->dso && cnx->egl.eglReleaseThread) {
         cnx->egl.eglReleaseThread();
     }
-
     egl_tls_t::clearTLS();
-#if EGL_TRACE
-    if (getEGLDebugLevel() > 0)
-        GLTrace_eglReleaseThread();
-#endif
     return EGL_TRUE;
 }
 
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index 52312a2..f3739aa 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -29,8 +29,8 @@
 
 namespace android {
 
-pthread_key_t egl_tls_t::sKey = -1;
-pthread_mutex_t egl_tls_t::sLockKey = PTHREAD_MUTEX_INITIALIZER;
+pthread_key_t egl_tls_t::sKey = TLS_KEY_NOT_INITIALIZED;
+pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT;
 
 egl_tls_t::egl_tls_t()
     : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
@@ -59,12 +59,12 @@
 
 void egl_tls_t::validateTLSKey()
 {
-    if (sKey == -1) {
-        pthread_mutex_lock(&sLockKey);
-        if (sKey == -1)
-            pthread_key_create(&sKey, NULL);
-        pthread_mutex_unlock(&sLockKey);
-    }
+    struct TlsKeyInitializer {
+        static void create() {
+            pthread_key_create(&sKey, (void (*)(void*))&eglReleaseThread);
+        }
+    };
+    pthread_once(&sOnceKey, TlsKeyInitializer::create);
 }
 
 void egl_tls_t::setErrorEtcImpl(
@@ -104,11 +104,11 @@
 }
 
 void egl_tls_t::clearTLS() {
-    if (sKey != -1) {
+    if (sKey != TLS_KEY_NOT_INITIALIZED) {
         egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
         if (tls) {
-            delete tls;
             pthread_setspecific(sKey, 0);
+            delete tls;
         }
     }
 }
@@ -120,10 +120,13 @@
 }
 
 EGLint egl_tls_t::getError() {
-    if (sKey == -1)
+    if (sKey == TLS_KEY_NOT_INITIALIZED) {
         return EGL_SUCCESS;
+    }
     egl_tls_t* tls = (egl_tls_t*)pthread_getspecific(sKey);
-    if (!tls) return EGL_SUCCESS;
+    if (!tls) {
+        return EGL_SUCCESS;
+    }
     EGLint error = tls->error;
     tls->error = EGL_SUCCESS;
     return error;
@@ -135,8 +138,9 @@
 }
 
 EGLContext egl_tls_t::getContext() {
-    if (sKey == -1)
+    if (sKey == TLS_KEY_NOT_INITIALIZED) {
         return EGL_NO_CONTEXT;
+    }
     egl_tls_t* tls = (egl_tls_t *)pthread_getspecific(sKey);
     if (!tls) return EGL_NO_CONTEXT;
     return tls->ctx;
diff --git a/opengl/libs/EGL/egl_tls.h b/opengl/libs/EGL/egl_tls.h
index 56c5dba..5af4f5b 100644
--- a/opengl/libs/EGL/egl_tls.h
+++ b/opengl/libs/EGL/egl_tls.h
@@ -30,8 +30,9 @@
 class DbgContext;
 
 class egl_tls_t {
+    enum { TLS_KEY_NOT_INITIALIZED = -1 };
     static pthread_key_t sKey;
-    static pthread_mutex_t sLockKey;
+    static pthread_once_t sOnceKey;
 
     EGLint      error;
     EGLContext  ctx;
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp
index 3a8decc..0323e8f 100644
--- a/opengl/libs/GLES_trace/src/gltrace_context.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp
@@ -32,7 +32,7 @@
 static pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
 
 void createTLSKey() {
-    pthread_key_create(&sTLSKey, NULL);
+    pthread_key_create(&sTLSKey, (void (*)(void*))&releaseContext);
 }
 
 GLTraceContext *getGLTraceContext() {
diff --git a/services/sensorservice/Fusion.cpp b/services/sensorservice/Fusion.cpp
index 93d6127..4f63c31 100644
--- a/services/sensorservice/Fusion.cpp
+++ b/services/sensorservice/Fusion.cpp
@@ -220,22 +220,6 @@
     // initial covariance: Var{ x(t0) }
     // TODO: initialize P correctly
     P = 0;
-
-    // it is unclear how to set the initial covariance. It does affect
-    // how quickly the fusion converges. Experimentally it would take
-    // about 10 seconds at 200 Hz to estimate the gyro-drift with an
-    // initial covariance of 0, and about a second with an initial covariance
-    // of about 1 deg/s.
-    const float covv = 0;
-    const float covu = 0.5f * (float(M_PI) / 180);
-    mat33_t& Pv = P[0][0];
-    Pv[0][0] = covv;
-    Pv[1][1] = covv;
-    Pv[2][2] = covv;
-    mat33_t& Pu = P[1][1];
-    Pu[0][0] = covu;
-    Pu[1][1] = covu;
-    Pu[2][2] = covu;
 }
 
 bool Fusion::hasEstimate() const {
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index 4837b97..a0a17da 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -53,8 +53,8 @@
 
         // 200 Hz for gyro events is a good compromise between precision
         // and power/cpu usage.
-        mGyroRate = 200;
-        mTargetDelayNs = 1000000000LL/mGyroRate;
+        mEstimatedGyroRate = 200;
+        mTargetDelayNs = 1000000000LL/mEstimatedGyroRate;
         mFusion.init();
     }
 }
@@ -63,14 +63,15 @@
     if (event.type == mGyro.getType()) {
         if (mGyroTime != 0) {
             const float dT = (event.timestamp - mGyroTime) / 1000000000.0f;
+            mFusion.handleGyro(vec3_t(event.data), dT);
+            // here we estimate the gyro rate (useful for debugging)
             const float freq = 1 / dT;
             if (freq >= 100 && freq<1000) { // filter values obviously wrong
                 const float alpha = 1 / (1 + dT); // 1s time-constant
-                mGyroRate = freq + (mGyroRate - freq)*alpha;
+                mEstimatedGyroRate = freq + (mEstimatedGyroRate - freq)*alpha;
             }
         }
         mGyroTime = event.timestamp;
-        mFusion.handleGyro(vec3_t(event.data), 1.0f/mGyroRate);
     } else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD) {
         const vec3_t mag(event.data);
         mFusion.handleMag(mag);
@@ -142,7 +143,7 @@
             "b=< %g, %g, %g >\n",
             mEnabled ? "enabled" : "disabled",
             mClients.size(),
-            mGyroRate,
+            mEstimatedGyroRate,
             fusion.getAttitude().x,
             fusion.getAttitude().y,
             fusion.getAttitude().z,
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index 4c99bcb..3c2244e 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -44,7 +44,7 @@
     Sensor mGyro;
     Fusion mFusion;
     bool mEnabled;
-    float mGyroRate;
+    float mEstimatedGyroRate;
     nsecs_t mTargetDelayNs;
     nsecs_t mGyroTime;
     vec4_t mAttitude;
@@ -60,7 +60,7 @@
     mat33_t getRotationMatrix() const { return mFusion.getRotationMatrix(); }
     vec4_t getAttitude() const { return mAttitude; }
     vec3_t getGyroBias() const { return mFusion.getBias(); }
-    float getEstimatedRate() const { return mGyroRate; }
+    float getEstimatedRate() const { return mEstimatedGyroRate; }
 
     status_t activate(void* ident, bool enabled);
     status_t setDelay(void* ident, int64_t ns);