Merge changes I91c0080e,Ibfbf84a5

* changes:
  vulkan: Update Vulkan headers to 1.0.61
  vulkan: Update Vulkan headers to 1.0.60
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 7f46087..2db0ee7 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -197,7 +197,7 @@
  * A sensor event.
  */
 
-/* NOTE: Must match hardware/sensors.h */
+/* NOTE: changes to these structs have to be backward compatible */
 typedef struct ASensorVector {
     union {
         float v[3];
@@ -259,7 +259,7 @@
     };
 } AAdditionalInfoEvent;
 
-/* NOTE: Must match hardware/sensors.h */
+/* NOTE: changes to this struct has to be backward compatible */
 typedef struct ASensorEvent {
     int32_t version; /* sizeof(struct ASensorEvent) */
     int32_t sensor;
@@ -388,13 +388,13 @@
 #endif
 
 #if __ANDROID_API__ >= __ANDROID_API_O__
-/*
+/**
  * Get a reference to the sensor manager. ASensorManager is a singleton
  * per package as different packages may have access to different sensors.
  *
  * Example:
  *
- *    ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz");
+ *     ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz");
  *
  */
 ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName);
@@ -503,14 +503,12 @@
  * {@link ASensor_isDirectChannelTypeSupported}, respectively.
  *
  * Example:
- * \code{.cpp}
- *      ASensorManager *manager = ...;
- *      ASensor *sensor = ...;
- *      int channelId = ...;
  *
- *      ASensorManager_configureDirectReport(
- *              manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
- * \endcode
+ *     ASensorManager *manager = ...;
+ *     ASensor *sensor = ...;
+ *     int channelId = ...;
+ *
+ *     ASensorManager_configureDirectReport(manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
  *
  * \param manager   the {@link ASensorManager} instance obtained from
  *                  {@link ASensorManager_getInstanceForPackage}.
@@ -530,50 +528,86 @@
 /*****************************************************************************/
 
 /**
- * Enable the selected sensor with a specified sampling period and max batch report latency.
- * Returns a negative error code on failure.
- * Note: To disable the selected sensor, use ASensorEventQueue_disableSensor() same as before.
+ * Enable the selected sensor with sampling and report parameters
+ *
+ * Enable the selected sensor at a specified sampling period and max batch report latency.
+ * To disable  sensor, use {@link ASensorEventQueue_disableSensor}.
+ *
+ * \param queue {@link ASensorEventQueue} for sensor event to be report to.
+ * \param sensor {@link ASensor} to be enabled.
+ * \param samplingPeriodUs sampling period of sensor in microseconds.
+ * \param maxBatchReportLatencyus maximum time interval between two batch of sensor events are
+ *                                delievered in microseconds. For sensor streaming, set to 0.
+ * \return 0 on success or a negative error code on failure.
  */
 int ASensorEventQueue_registerSensor(ASensorEventQueue* queue, ASensor const* sensor,
         int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs);
 
 /**
- * Enable the selected sensor. Returns a negative error code on failure.
+ * Enable the selected sensor at default sampling rate.
+ *
+ * Start event reports of a sensor to specified sensor event queue at a default rate.
+ *
+ * \param queue {@link ASensorEventQueue} for sensor event to be report to.
+ * \param sensor {@link ASensor} to be enabled.
+ *
+ * \return 0 on success or a negative error code on failure.
  */
 int ASensorEventQueue_enableSensor(ASensorEventQueue* queue, ASensor const* sensor);
 
 /**
- * Disable the selected sensor. Returns a negative error code on failure.
+ * Disable the selected sensor.
+ *
+ * Stop event reports from the sensor to specified sensor event queue.
+ *
+ * \param queue {@link ASensorEventQueue} to be changed
+ * \param sensor {@link ASensor} to be disabled
+ * \return 0 on success or a negative error code on failure.
  */
 int ASensorEventQueue_disableSensor(ASensorEventQueue* queue, ASensor const* sensor);
 
 /**
  * Sets the delivery rate of events in microseconds for the given sensor.
+ *
+ * This function has to be called after {@link ASensorEventQueue_enableSensor}.
  * Note that this is a hint only, generally event will arrive at a higher
  * rate. It is an error to set a rate inferior to the value returned by
  * ASensor_getMinDelay().
- * Returns a negative error code on failure.
+ *
+ * \param queue {@link ASensorEventQueue} to which sensor event is delivered.
+ * \param sensor {@link ASensor} of which sampling rate to be updated.
+ * \param usec sensor sampling period (1/sampling rate) in microseconds
+ * \return 0 on sucess or a negative error code on failure.
  */
 int ASensorEventQueue_setEventRate(ASensorEventQueue* queue, ASensor const* sensor, int32_t usec);
 
 /**
- * Returns true if there are one or more events available in the
- * sensor queue.  Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
+ * Determine if a sensor event queue has pending event to be processed.
+ *
+ * \param queue {@link ASensorEventQueue} to be queried
+ * \return 1 if the queue has events; 0 if it does not have events;
+ *         or a negative value if there is an error.
  */
 int ASensorEventQueue_hasEvents(ASensorEventQueue* queue);
 
 /**
- * Returns the next available events from the queue.  Returns a negative
- * value if no events are available or an error has occurred, otherwise
- * the number of events returned.
+ * Retrieve pending events in sensor event queue
+ *
+ * Retrieve next available events from the queue to a specified event array.
+ *
+ * \param queue {@link ASensorEventQueue} to get events from
+ * \param events pointer to an array of {@link ASensorEvents}.
+ * \param count max number of event that can be filled into array event.
+ * \return number of events returned on success; negative error code when
+ *         no events are pending or an error has occurred.
  *
  * Examples:
- *   ASensorEvent event;
- *   ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);
  *
- *   ASensorEvent eventBuffer[8];
- *   ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);
+ *     ASensorEvent event;
+ *     ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);
+ *
+ *     ASensorEvent eventBuffer[8];
+ *     ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);
  *
  */
 ssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue, ASensorEvent* events, size_t count);
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 0b390c5..1c3fab4 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -686,7 +686,7 @@
 #if LOG_REFCOUNTS
     ALOGV("IPCThreadState::expungeHandle(%ld)\n", handle);
 #endif
-    self()->mProcess->expungeHandle(handle, binder);
+    self()->mProcess->expungeHandle(handle, binder); // NOLINT
 }
 
 status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index e06cb5f..50bb7b2 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -20,6 +20,9 @@
 cc_library_shared {
     name: "libgui",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     clang: true,
     cppflags: [
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index c654f08..770c6b5 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -41,7 +41,7 @@
 #include <utils/String8.h>
 #include <utils/Trace.h>
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 #define CROP_EXT_STR "EGL_ANDROID_image_crop"
 #define PROT_CONTENT_EXT_STR "EGL_EXT_protected_content"
 #define EGL_PROTECTED_CONTENT_EXT 0x32C0
diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp
index 187b211..afa15c5 100644
--- a/libs/gui/SyncFeatures.cpp
+++ b/libs/gui/SyncFeatures.cpp
@@ -27,7 +27,7 @@
 
 #include <private/gui/SyncFeatures.h>
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
 namespace android {
 
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index bd598e4..d5b2f00 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -28,7 +28,7 @@
 #include <utils/Log.h>
 #include <utils/Thread.h>
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 #define CROP_EXT_STR "EGL_ANDROID_image_crop"
 
 namespace android {
diff --git a/libs/sensor/ISensorEventConnection.cpp b/libs/sensor/ISensorEventConnection.cpp
index 8a3a623..1cd8e01 100644
--- a/libs/sensor/ISensorEventConnection.cpp
+++ b/libs/sensor/ISensorEventConnection.cpp
@@ -36,7 +36,8 @@
     ENABLE_DISABLE,
     SET_EVENT_RATE,
     FLUSH_SENSOR,
-    CONFIGURE_CHANNEL
+    CONFIGURE_CHANNEL,
+    DESTROY,
 };
 
 class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
@@ -96,11 +97,22 @@
         remote()->transact(CONFIGURE_CHANNEL, data, &reply);
         return reply.readInt32();
     }
+
+    virtual void onLastStrongRef(const void* id) {
+        destroy();
+        BpInterface<ISensorEventConnection>::onLastStrongRef(id);
+    }
+
+protected:
+    virtual void destroy() {
+        Parcel data, reply;
+        remote()->transact(DESTROY, data, &reply);
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
 // translation unit (see clang warning -Wweak-vtables)
-BpSensorEventConnection::~BpSensorEventConnection() {}
+BpSensorEventConnection::~BpSensorEventConnection() { }
 
 IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
 
@@ -150,6 +162,10 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case DESTROY: {
+            destroy();
+            return NO_ERROR;
+        }
 
     }
     return BBinder::onTransact(code, data, reply, flags);
diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
index 74186df..f20668d 100644
--- a/libs/sensor/ISensorServer.cpp
+++ b/libs/sensor/ISensorServer.cpp
@@ -119,10 +119,12 @@
         return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
     }
 
-    virtual int setOperationParameter(
-            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+    virtual int setOperationParameter(int32_t handle, int32_t type,
+                                      const Vector<float> &floats,
+                                      const Vector<int32_t> &ints) {
         Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeInt32(handle);
         data.writeInt32(type);
         data.writeUint32(static_cast<uint32_t>(floats.size()));
         for (auto i : floats) {
@@ -203,10 +205,12 @@
         }
         case SET_OPERATION_PARAMETER: {
             CHECK_INTERFACE(ISensorServer, data, reply);
+            int32_t handle;
             int32_t type;
             Vector<float> floats;
             Vector<int32_t> ints;
 
+            handle = data.readInt32();
             type = data.readInt32();
             floats.resize(data.readUint32());
             for (auto &i : floats) {
@@ -217,7 +221,7 @@
                 i = data.readInt32();
             }
 
-            int32_t ret = setOperationParameter(type, floats, ints);
+            int32_t ret = setOperationParameter(handle, type, floats, ints);
             reply->writeInt32(ret);
             return NO_ERROR;
         }
diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS
new file mode 100644
index 0000000..6a38a1f
--- /dev/null
+++ b/libs/sensor/OWNERS
@@ -0,0 +1,2 @@
+ashutoshj@google.com
+pengxu@google.com
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index c2d477e..a0e368c 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -30,7 +30,7 @@
         mName(name), mHandle(0), mType(0),
         mMinValue(0), mMaxValue(0), mResolution(0),
         mPower(0), mMinDelay(0), mVersion(0), mFifoReservedEventCount(0),
-        mFifoMaxEventCount(0), mRequiredAppOp(0),
+        mFifoMaxEventCount(0), mRequiredAppOp(-1),
         mMaxDelay(0), mFlags(0) {
 }
 
@@ -38,7 +38,8 @@
         Sensor(*hwSensor, uuid_t(), halVersion) {
 }
 
-Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) {
+Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) :
+        Sensor("") {
     mName = hwSensor.name;
     mVendor = hwSensor.vendor;
     mVersion = hwSensor.version;
@@ -412,6 +413,10 @@
     return (mFlags & SENSOR_FLAG_DYNAMIC_SENSOR) != 0;
 }
 
+bool Sensor::isDataInjectionSupported() const {
+    return (mFlags & SENSOR_FLAG_DATA_INJECTION) != 0;
+}
+
 bool Sensor::hasAdditionalInfo() const {
     return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0;
 }
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 3fbc5eb..6fe72a1 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -305,12 +305,13 @@
 }
 
 int SensorManager::setOperationParameter(
-        int type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+        int handle, int type,
+        const Vector<float> &floats, const Vector<int32_t> &ints) {
     Mutex::Autolock _l(mLock);
     if (assertStateLocked() != NO_ERROR) {
         return NO_INIT;
     }
-    return mSensorServer->setOperationParameter(type, floats, ints);
+    return mSensorServer->setOperationParameter(handle, type, floats, ints);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/ISensorEventConnection.h b/libs/sensor/include/sensor/ISensorEventConnection.h
index 07cc7e8..b62e18c 100644
--- a/libs/sensor/include/sensor/ISensorEventConnection.h
+++ b/libs/sensor/include/sensor/ISensorEventConnection.h
@@ -42,6 +42,8 @@
     virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
     virtual status_t flush() = 0;
     virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) = 0;
+protected:
+    virtual void destroy() = 0; // synchronously release resource hold by remote object
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
index 8d50062..edf3e0f 100644
--- a/libs/sensor/include/sensor/ISensorServer.h
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -52,7 +52,7 @@
             uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;
 
     virtual int setOperationParameter(
-            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
+            int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/Sensor.h b/libs/sensor/include/sensor/Sensor.h
index 043e635..6926f7f 100644
--- a/libs/sensor/include/sensor/Sensor.h
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -90,6 +90,7 @@
     uint32_t getFlags() const;
     bool isWakeUpSensor() const;
     bool isDynamicSensor() const;
+    bool isDataInjectionSupported() const;
     bool hasAdditionalInfo() const;
     int32_t getHighestDirectReportRateLevel() const;
     bool isDirectChannelTypeSupported(int32_t sharedMemType) const;
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index 5fc85d3..23f7a91 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -64,7 +64,7 @@
     int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
     void destroyDirectChannel(int channelNativeHandle);
     int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
-    int setOperationParameter(int type, const Vector<float> &floats, const Vector<int32_t> &ints);
+    int setOperationParameter(int handle, int type, const Vector<float> &floats, const Vector<int32_t> &ints);
 
 private:
     // DeathRecipient interface
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 740940c..28b8ab3 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -15,6 +15,9 @@
 cc_library_shared {
     name: "libui",
     vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
 
     clang: true,
     cppflags: [
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index b9fa640..5b0e7f6 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -95,7 +95,7 @@
 {
     int32_t fenceFd = -1;
     status_t error = unlockAsync(handle, &fenceFd);
-    if (error == NO_ERROR) {
+    if (error == NO_ERROR && fenceFd >= 0) {
         sync_wait(fenceFd, -1);
         close(fenceFd);
     }
diff --git a/opengl/Android.bp b/opengl/Android.bp
index aec5a95..9ca8b0b 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -52,6 +52,30 @@
     license: "include/KHR/NOTICE",
 }
 
+llndk_library {
+    name: "libEGL",
+    symbol_file: "libs/libEGL.map.txt",
+    export_include_dirs: ["include"],
+}
+
+llndk_library {
+    name: "libGLESv1_CM",
+    symbol_file: "libs/libGLESv1_CM.map.txt",
+    export_include_dirs: ["include"],
+}
+
+llndk_library {
+    name: "libGLESv2",
+    symbol_file: "libs/libGLESv2.map.txt",
+    export_include_dirs: ["include"],
+}
+
+llndk_library {
+    name: "libGLESv3",
+    symbol_file: "libs/libGLESv3.map.txt",
+    export_include_dirs: ["include"],
+}
+
 cc_library_headers {
     name: "gl_headers",
     vendor_available: true,
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 8a9e4b3..59424cd 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -84,7 +84,6 @@
 cc_defaults {
     name: "egl_libs_defaults",
     defaults: ["gl_libs_defaults"],
-    vendor_available: true,
     cflags: [
         "-DLOG_TAG=\"libEGL\"",
     ],
@@ -144,7 +143,6 @@
 cc_defaults {
     name: "gles_libs_defaults",
     defaults: ["gl_libs_defaults"],
-    vendor_available: true,
     arch: {
         arm: {
             instruction_set: "arm",
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 4914c44..60b22b8 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1251,7 +1251,7 @@
     return setError(EGL_BAD_PARAMETER, (const char *)0);
 }
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name)
 {
     clearError();
 
diff --git a/opengl/libs/libEGL.map.txt b/opengl/libs/libEGL.map.txt
index 89269a0..fa26e33 100644
--- a/opengl/libs/libEGL.map.txt
+++ b/opengl/libs/libEGL.map.txt
@@ -21,6 +21,7 @@
     eglDestroyStreamKHR; # introduced=23
     eglDestroySurface;
     eglDestroySyncKHR; # introduced-arm=18 introduced-arm64=21 introduced-mips=18 introduced-mips64=21 introduced-x86=18 introduced-x86_64=21
+    eglDupNativeFenceFDANDROID; # vndk
     eglGetConfigAttrib;
     eglGetConfigs;
     eglGetCurrentContext;
@@ -44,6 +45,7 @@
     eglQueryStreamTimeKHR; # introduced=23
     eglQueryStreamu64KHR; # introduced=23
     eglQueryString;
+    eglQueryStringImplementationANDROID; # vndk
     eglQuerySurface;
     eglReleaseTexImage;
     eglReleaseThread;
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index ee88667..67c0969 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -30,7 +30,7 @@
 #include <EGLUtils.h>
 
 using namespace android;
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
 static void printGLString(const char *name, GLenum s) {
     // fprintf(stderr, "printGLString %s, %d\n", name, s);
diff --git a/opengl/tests/lib/include/EGLUtils.h b/opengl/tests/lib/include/EGLUtils.h
new file mode 100644
index 0000000..9dc6bcf
--- /dev/null
+++ b/opengl/tests/lib/include/EGLUtils.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef ANDROID_UI_EGLUTILS_H
+#define ANDROID_UI_EGLUTILS_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <vector>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <system/window.h>
+#include <utils/Errors.h>
+#include <utils/String8.h>
+
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class EGLUtils
+{
+public:
+
+    static inline const char *strerror(EGLint err);
+
+    static inline status_t selectConfigForPixelFormat(
+            EGLDisplay dpy,
+            EGLint const* attrs,
+            int32_t format,
+            EGLConfig* outConfig);
+
+    static inline status_t selectConfigForNativeWindow(
+            EGLDisplay dpy,
+            EGLint const* attrs,
+            EGLNativeWindowType window,
+            EGLConfig* outConfig);
+
+    static inline String8 printGLString(const char* name, GLenum s);
+    static inline String8 printEGLString(EGLDisplay dpy, const char* name, GLenum s);
+    static inline String8 checkEglError(const char* op, EGLBoolean returnVal);
+    static inline String8 checkGlError(const char* op);
+    static inline String8 printEGLConfiguration(EGLDisplay dpy, EGLConfig config);
+    static inline bool printEGLConfigurations(EGLDisplay dpy, String8& msg);
+    static inline bool printEGLConfigurations(FILE* output, EGLDisplay dpy);
+    static inline String8 decodeColorSpace(EGLint colorSpace);
+    static inline bool hasEglExtension(EGLDisplay dpy, const char* name);
+    static inline bool hasExtension(const char* exts, const char* name);
+};
+
+// ----------------------------------------------------------------------------
+
+const char *EGLUtils::strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+status_t EGLUtils::selectConfigForPixelFormat(
+        EGLDisplay dpy,
+        EGLint const* attrs,
+        int32_t format,
+        EGLConfig* outConfig)
+{
+    EGLint numConfigs = -1, n=0;
+
+    if (!attrs)
+        return BAD_VALUE;
+
+    if (outConfig == NULL)
+        return BAD_VALUE;
+
+    // Get all the "potential match" configs...
+    if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
+        return BAD_VALUE;
+
+    std::vector<EGLConfig> configs(numConfigs);
+    if (eglChooseConfig(dpy, attrs, configs.data(), numConfigs, &n) == EGL_FALSE) {
+        return BAD_VALUE;
+    }
+
+    int i;
+    EGLConfig config = NULL;
+    for (i=0 ; i<n ; i++) {
+        EGLint nativeVisualId = 0;
+        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+        if (nativeVisualId>0 && format == nativeVisualId) {
+            config = configs[i];
+            break;
+        }
+    }
+
+    if (i<n) {
+        *outConfig = config;
+        return NO_ERROR;
+    }
+
+    return NAME_NOT_FOUND;
+}
+
+status_t EGLUtils::selectConfigForNativeWindow(
+        EGLDisplay dpy,
+        EGLint const* attrs,
+        EGLNativeWindowType window,
+        EGLConfig* outConfig)
+{
+    int err;
+    int format;
+
+    if (!window)
+        return BAD_VALUE;
+
+    if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) {
+        return err;
+    }
+
+    return selectConfigForPixelFormat(dpy, attrs, format, outConfig);
+}
+
+String8 EGLUtils::printGLString(const char* name, GLenum s) {
+    String8 msg;
+    const char* v = reinterpret_cast<const char*>(glGetString(s));
+    msg.appendFormat("GL %s = %s\n", name, v);
+    return msg;
+}
+
+String8 EGLUtils::printEGLString(EGLDisplay dpy, const char* name, GLenum s) {
+    String8 msg;
+    const char* v = static_cast<const char*>(eglQueryString(dpy, s));
+    msg.appendFormat("GL %s = %s\n", name, v);
+    const char* va = (const char*)eglQueryStringImplementationANDROID(dpy, s);
+    msg.appendFormat("ImplementationANDROID: %s = %s\n", name, va);
+    return msg;
+}
+
+String8 EGLUtils::checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    String8 msg;
+    if (returnVal != EGL_TRUE) {
+        msg.appendFormat("%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
+        msg.appendFormat("after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), error);
+    }
+    return msg;
+}
+
+String8 EGLUtils::checkGlError(const char* op) {
+    String8 msg;
+    for (GLint error = glGetError(); error != GL_NO_ERROR; error = glGetError()) {
+        msg.appendFormat("after %s() glError (0x%x)\n", op, error);
+    }
+    return msg;
+}
+
+String8 EGLUtils::printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+#define X(VAL) \
+    { VAL, #VAL }
+    struct {
+        EGLint attribute;
+        const char* name;
+    } names[] = {
+            X(EGL_BUFFER_SIZE),
+            X(EGL_ALPHA_SIZE),
+            X(EGL_BLUE_SIZE),
+            X(EGL_GREEN_SIZE),
+            X(EGL_RED_SIZE),
+            X(EGL_DEPTH_SIZE),
+            X(EGL_STENCIL_SIZE),
+            X(EGL_CONFIG_CAVEAT),
+            X(EGL_CONFIG_ID),
+            X(EGL_LEVEL),
+            X(EGL_MAX_PBUFFER_HEIGHT),
+            X(EGL_MAX_PBUFFER_PIXELS),
+            X(EGL_MAX_PBUFFER_WIDTH),
+            X(EGL_NATIVE_RENDERABLE),
+            X(EGL_NATIVE_VISUAL_ID),
+            X(EGL_NATIVE_VISUAL_TYPE),
+            X(EGL_SAMPLES),
+            X(EGL_SAMPLE_BUFFERS),
+            X(EGL_SURFACE_TYPE),
+            X(EGL_TRANSPARENT_TYPE),
+            X(EGL_TRANSPARENT_RED_VALUE),
+            X(EGL_TRANSPARENT_GREEN_VALUE),
+            X(EGL_TRANSPARENT_BLUE_VALUE),
+            X(EGL_BIND_TO_TEXTURE_RGB),
+            X(EGL_BIND_TO_TEXTURE_RGBA),
+            X(EGL_MIN_SWAP_INTERVAL),
+            X(EGL_MAX_SWAP_INTERVAL),
+            X(EGL_LUMINANCE_SIZE),
+            X(EGL_ALPHA_MASK_SIZE),
+            X(EGL_COLOR_BUFFER_TYPE),
+            X(EGL_RENDERABLE_TYPE),
+            X(EGL_CONFORMANT),
+    };
+#undef X
+
+    String8 msg;
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            msg.appendFormat(" %s: %d (0x%x)", names[j].name, value, value);
+        }
+    }
+    msg.append("\n");
+    return msg;
+}
+
+bool EGLUtils::printEGLConfigurations(EGLDisplay dpy, String8& msg) {
+    EGLint numConfig = 0;
+    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
+    msg.append(checkEglError("eglGetConfigs", returnVal));
+    if (!returnVal) {
+        return false;
+    }
+
+    msg.appendFormat("Number of EGL configuration: %d\n", numConfig);
+
+    std::vector<EGLConfig> configs(numConfig);
+
+    returnVal = eglGetConfigs(dpy, configs.data(), numConfig, &numConfig);
+    msg.append(checkEglError("eglGetConfigs", returnVal));
+    if (!returnVal) {
+        return false;
+    }
+
+    for (int i = 0; i < numConfig; i++) {
+        msg.appendFormat("Configuration %d\n", i);
+        msg.append(printEGLConfiguration(dpy, configs[i]));
+    }
+
+    return true;
+}
+
+bool EGLUtils::printEGLConfigurations(FILE* output, EGLDisplay dpy) {
+    String8 msg;
+    bool status = printEGLConfigurations(dpy, msg);
+    fprintf(output, "%s", msg.c_str());
+    return status;
+}
+
+String8 EGLUtils::decodeColorSpace(EGLint colorSpace) {
+    switch (colorSpace) {
+        case EGL_GL_COLORSPACE_SRGB_KHR:
+            return String8("EGL_GL_COLORSPACE_SRGB_KHR");
+        case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
+            return String8("EGL_GL_COLORSPACE_DISPLAY_P3_EXT");
+        case  EGL_GL_COLORSPACE_LINEAR_KHR:
+            return String8("EGL_GL_COLORSPACE_LINEAR_KHR");
+        default:
+            return String8::format("UNKNOWN ColorSpace %d", colorSpace);
+    }
+}
+
+bool EGLUtils::hasExtension(const char* exts, const char* name) {
+    size_t nameLen = strlen(name);
+    if (exts) {
+        for (const char* match = strstr(exts, name); match; match = strstr(match + nameLen, name)) {
+            if (match[nameLen] == '\0' || match[nameLen] == ' ') {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool EGLUtils::hasEglExtension(EGLDisplay dpy, const char* name) {
+    return hasExtension(eglQueryString(dpy, EGL_EXTENSIONS), name);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+#endif /* ANDROID_UI_EGLUTILS_H */
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 8c2300e..8d381b1 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -1,3 +1,73 @@
 subdirs = [
     "hidl"
 ]
+cc_library_shared {
+    name: "libsensorservice",
+
+    srcs: [
+        "BatteryService.cpp",
+        "CorrectedGyroSensor.cpp",
+        "Fusion.cpp",
+        "GravitySensor.cpp",
+        "LinearAccelerationSensor.cpp",
+        "OrientationSensor.cpp",
+        "RecentEventLogger.cpp",
+        "RotationVectorSensor.cpp",
+        "SensorDevice.cpp",
+        "SensorDirectConnection.cpp",
+        "SensorEventConnection.cpp",
+        "SensorFusion.cpp",
+        "SensorInterface.cpp",
+        "SensorList.cpp",
+        "SensorRecord.cpp",
+        "SensorService.cpp",
+        "SensorServiceUtils.cpp",
+    ],
+
+    cflags: [
+        "-DLOG_TAG=\"SensorService\"",
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-fvisibility=hidden"
+    ],
+
+    shared_libs: [
+        "libcutils",
+        "libhardware",
+        "libhardware_legacy",
+        "libutils",
+        "liblog",
+        "libbinder",
+        "libsensor",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "android.hardware.sensors@1.0",
+    ],
+
+    static_libs: ["android.hardware.sensors@1.0-convert"],
+
+    // our public headers depend on libsensor
+    export_shared_lib_headers: ["libsensor"],
+}
+
+cc_binary {
+    name: "sensorservice",
+
+    srcs: ["main_sensorservice.cpp"],
+
+    shared_libs: [
+        "libsensorservice",
+        "libbinder",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
deleted file mode 100644
index cfb7231..0000000
--- a/services/sensorservice/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    BatteryService.cpp \
-    CorrectedGyroSensor.cpp \
-    Fusion.cpp \
-    GravitySensor.cpp \
-    LinearAccelerationSensor.cpp \
-    OrientationSensor.cpp \
-    RecentEventLogger.cpp \
-    RotationVectorSensor.cpp \
-    SensorDevice.cpp \
-    SensorDirectConnection.cpp \
-    SensorEventConnection.cpp \
-    SensorFusion.cpp \
-    SensorInterface.cpp \
-    SensorList.cpp \
-    SensorRecord.cpp \
-    SensorService.cpp \
-    SensorServiceUtils.cpp \
-
-LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
-
-LOCAL_CFLAGS += -Wall -Werror -Wextra
-
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libhardware \
-    libhardware_legacy \
-    libutils \
-    liblog \
-    libbinder \
-    libsensor \
-    libcrypto \
-    libbase \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    android.hardware.sensors@1.0
-
-LOCAL_STATIC_LIBRARIES := \
-    android.hardware.sensors@1.0-convert
-
-# our public headers depend on libsensor
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
-    libsensor \
-
-LOCAL_MODULE:= libsensorservice
-
-include $(BUILD_SHARED_LIBRARY)
-
-#####################################################################
-# build executable
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    main_sensorservice.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libsensorservice \
-    libbinder \
-    libutils
-
-LOCAL_CFLAGS := -Wall -Werror -Wextra
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= sensorservice
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS
new file mode 100644
index 0000000..6a38a1f
--- /dev/null
+++ b/services/sensorservice/OWNERS
@@ -0,0 +1,2 @@
+ashutoshj@google.com
+pengxu@google.com
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 7d9b0b7..da3b275 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -223,8 +223,13 @@
 }
 
 void SensorDevice::autoDisable(void *ident, int handle) {
-    Info& info( mActivationCount.editValueFor(handle) );
     Mutex::Autolock _l(mLock);
+    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+    if (activationIndex < 0) {
+        ALOGW("Handle %d cannot be found in activation record", handle);
+        return;
+    }
+    Info& info(mActivationCount.editValueAt(activationIndex));
     info.removeBatchParamsForIdent(ident);
 }
 
@@ -235,7 +240,12 @@
     bool actuateHardware = false;
 
     Mutex::Autolock _l(mLock);
-    Info& info( mActivationCount.editValueFor(handle) );
+    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+    if (activationIndex < 0) {
+        ALOGW("Handle %d cannot be found in activation record", handle);
+        return BAD_VALUE;
+    }
+    Info& info(mActivationCount.editValueAt(activationIndex));
 
     ALOGD_IF(DEBUG_CONNECTIONS,
              "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
@@ -329,7 +339,12 @@
              ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
 
     Mutex::Autolock _l(mLock);
-    Info& info(mActivationCount.editValueFor(handle));
+    ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+    if (activationIndex < 0) {
+        ALOGW("Handle %d cannot be found in activation record", handle);
+        return BAD_VALUE;
+    }
+    Info& info(mActivationCount.editValueAt(activationIndex));
 
     if (info.batchParams.indexOfKey(ident) < 0) {
         BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 870635b..538d728 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -27,12 +27,21 @@
         const String16& opPackageName)
         : mService(service), mUid(uid), mMem(*mem),
         mHalChannelHandle(halChannelHandle),
-        mOpPackageName(opPackageName) {
+        mOpPackageName(opPackageName), mDestroyed(false) {
     ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
 }
 
 SensorService::SensorDirectConnection::~SensorDirectConnection() {
     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this);
+    destroy();
+}
+
+void SensorService::SensorDirectConnection::destroy() {
+    Mutex::Autolock _l(mDestroyLock);
+    // destroy once only
+    if (mDestroyed) {
+        return;
+    }
 
     stopAll();
     mService->cleanupConnection(this);
@@ -40,6 +49,7 @@
         native_handle_close(mMem.handle);
         native_handle_delete(const_cast<struct native_handle*>(mMem.handle));
     }
+    mDestroyed = true;
 }
 
 void SensorService::SensorDirectConnection::onFirstRef() {
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index 27458d4..5c398a8 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -47,7 +47,7 @@
     // stop all active sensor report. if backupRecord is set to false,
     // those report can be recovered by recoverAll
     // called by SensorService when enter restricted mode
-    void stopAll(bool clearRecord = false);
+    void stopAll(bool backupRecord = false);
 
     // recover sensor reports previously stopped by stopAll(true)
     // called by SensorService when return to NORMAL mode.
@@ -63,7 +63,7 @@
     virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
     virtual status_t flush();
     virtual int32_t configureChannel(int handle, int rateLevel);
-
+    virtual void destroy();
 private:
     const sp<SensorService> mService;
     const uid_t mUid;
@@ -74,6 +74,9 @@
     mutable Mutex mConnectionLock;
     std::unordered_map<int, int> mActivated;
     std::unordered_map<int, int> mActivatedBackup;
+
+    mutable Mutex mDestroyLock;
+    bool mDestroyed;
 };
 
 } // namepsace android
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index fad046c..0a05dd1 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -32,7 +32,8 @@
         const String16& opPackageName)
     : mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
       mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
-      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
+      mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
+      mDestroyed(false) {
     mChannel = new BitTube(mService->mSocketBufferSize);
 #if DEBUG_CONNECTIONS
     mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -42,10 +43,22 @@
 
 SensorService::SensorEventConnection::~SensorEventConnection() {
     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
+    destroy();
+}
+
+void SensorService::SensorEventConnection::destroy() {
+    Mutex::Autolock _l(mDestroyLock);
+
+    // destroy once only
+    if (mDestroyed) {
+        return;
+    }
+
     mService->cleanupConnection(this);
     if (mEventCache != NULL) {
         delete mEventCache;
     }
+    mDestroyed = true;
 }
 
 void SensorService::SensorEventConnection::onFirstRef() {
@@ -477,7 +490,14 @@
     // separately before the next batch of events.
     for (int j = 0; j < numEventsDropped; ++j) {
         if (scratch[j].type == SENSOR_TYPE_META_DATA) {
-            FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
+            ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
+            if (index < 0) {
+                ALOGW("%s: sensor 0x%x is not found in connection",
+                      __func__, scratch[j].meta_data.sensor);
+                continue;
+            }
+
+            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
             flushInfo.mPendingFlushEventsToSend++;
             ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
                      flushInfo.mPendingFlushEventsToSend);
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index c81e015..6f282cd 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -75,6 +75,7 @@
     virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
     virtual status_t flush();
     virtual int32_t configureChannel(int handle, int rateLevel);
+    virtual void destroy();
 
     // Count the number of flush complete events which are about to be dropped in the buffer.
     // Increment mPendingFlushEventsToSend in mSensorInfo. These flush complete events will be sent
@@ -164,6 +165,8 @@
     int mTotalAcksNeeded, mTotalAcksReceived;
 #endif
 
+    mutable Mutex mDestroyLock;
+    bool mDestroyed;
 };
 
 } // namepsace android
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index ab08cac..aa306d8 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -124,14 +124,15 @@
     forEachSensor([&result] (const Sensor& s) -> bool {
             result.appendFormat(
                     "%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
-                        ") | perm: %s\n",
+                        ") | perm: %s | flags: 0x%08x\n",
                     s.getHandle(),
                     s.getName().string(),
                     s.getVendor().string(),
                     s.getVersion(),
                     s.getStringType().string(),
                     s.getType(),
-                    s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a");
+                    s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a",
+                    static_cast<int>(s.getFlags()));
 
             result.append("\t");
             const int reportingMode = s.getReportingMode();
@@ -173,9 +174,14 @@
                 result.appendFormat("non-wakeUp | ");
             }
 
+            if (s.isDataInjectionSupported()) {
+                result.appendFormat("data-injection, ");
+            }
+
             if (s.isDynamicSensor()) {
                 result.appendFormat("dynamic, ");
             }
+
             if (s.hasAdditionalInfo()) {
                 result.appendFormat("has-additional-info, ");
             }
@@ -190,7 +196,6 @@
                 if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) {
                     result.append("gralloc, ");
                 }
-                result.appendFormat("flag =0x%08x", static_cast<int>(s.getFlags()));
                 result.append("\n");
             }
             return true;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index d60768c..dc491d9 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -394,6 +394,7 @@
             }
         } else if (!mSensors.hasAnySensor()) {
             result.append("No Sensors on the device\n");
+            result.appendFormat("devInitCheck : %d\n", SensorDevice::getInstance().initCheck());
         } else {
             // Default dump the sensor list and debugging information.
             //
@@ -932,8 +933,14 @@
     }
 
     uid_t uid = IPCThreadState::self()->getCallingUid();
-    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
-            requestedMode == DATA_INJECTION, opPackageName));
+    pid_t pid = IPCThreadState::self()->getCallingPid();
+
+    String8 connPackageName =
+            (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;
+    String16 connOpPackageName =
+            (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
+    sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
+            requestedMode == DATA_INJECTION, connOpPackageName));
     if (requestedMode == DATA_INJECTION) {
         if (mActiveConnections.indexOf(result) < 0) {
             mActiveConnections.add(result);
@@ -1032,17 +1039,16 @@
 }
 
 int SensorService::setOperationParameter(
-            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+            int32_t handle, int32_t type,
+            const Vector<float> &floats, const Vector<int32_t> &ints) {
     Mutex::Autolock _l(mLock);
 
-    // check permission
-    int32_t uid;
-    bool hasPermission = checkCallingPermission(sLocationHardwarePermission, nullptr, &uid);
-    if (!hasPermission || (uid != 1000 && uid != 0)) {
+    if (!checkCallingPermission(sLocationHardwarePermission, nullptr, nullptr)) {
         return PERMISSION_DENIED;
     }
 
     bool isFloat = true;
+    bool isCustom = false;
     size_t expectSize = INT32_MAX;
     switch (type) {
         case AINFO_LOCAL_GEOMAGNETIC_FIELD:
@@ -1060,7 +1066,21 @@
             expectSize = 1;
             break;
         default:
-            return BAD_VALUE;
+            // CUSTOM events must only contain float data; it may have variable size
+            if (type < AINFO_CUSTOM_START || type >= AINFO_DEBUGGING_START ||
+                    ints.size() ||
+                    sizeof(additional_info_event_t::data_float)/sizeof(float) < floats.size() ||
+                    handle < 0) {
+                return BAD_VALUE;
+            }
+            isFloat = true;
+            isCustom = true;
+            expectSize = floats.size();
+            break;
+    }
+
+    if (!isCustom && handle != -1) {
+        return BAD_VALUE;
     }
 
     // three events: first one is begin tag, last one is end tag, the one in the middle
@@ -1070,7 +1090,7 @@
     for (sensors_event_t* i = event; i < event + 3; i++) {
         *i = (sensors_event_t) {
             .version = sizeof(sensors_event_t),
-            .sensor = SENSORS_HANDLE_BASE - 1, // sensor that never exists
+            .sensor = handle,
             .type = SENSOR_TYPE_ADDITIONAL_INFO,
             .timestamp = timestamp++,
             .additional_info = (additional_info_event_t) {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 2a9d6e8..3e18394 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -159,7 +159,7 @@
     virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
             uint32_t size, int32_t type, int32_t format, const native_handle *resource);
     virtual int setOperationParameter(
-            int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
+            int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
     virtual status_t dump(int fd, const Vector<String16>& args);
 
     String8 getSensorName(int handle) const;
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
index 8bbc4c5..02c13fa 100644
--- a/services/sensorservice/hidl/Android.bp
+++ b/services/sensorservice/hidl/Android.bp
@@ -14,6 +14,7 @@
         "libbase",
         "libhidlbase",
         "libhidltransport",
+        "libhwbinder",
         "libutils",
         "libsensor",
         "android.frameworks.sensorservice@1.0",
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
index 25a3dc5..fee6da1 100644
--- a/services/sensorservice/hidl/SensorManager.cpp
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -24,12 +24,14 @@
 
 #include <sched.h>
 
-#include <thread>
 
 #include "EventQueue.h"
 #include "DirectReportChannel.h"
 #include "utils.h"
 
+#include <hwbinder/IPCThreadState.h>
+#include <utils/String8.h>
+
 namespace android {
 namespace frameworks {
 namespace sensorservice {
@@ -40,20 +42,24 @@
 using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Void;
-using ::android::sp;
 
 static const char* POLL_THREAD_NAME = "hidl_ssvc_poll";
 
 SensorManager::SensorManager(JavaVM* vm)
-        : mJavaVm(vm) {
+        : mLooper(new Looper(false /*allowNonCallbacks*/)), mStopThread(true), mJavaVm(vm) {
 }
 
 SensorManager::~SensorManager() {
     // Stops pollAll inside the thread.
-    std::unique_lock<std::mutex> lock(mLooperMutex);
+    std::lock_guard<std::mutex> lock(mThreadMutex);
+
+    mStopThread = true;
     if (mLooper != nullptr) {
         mLooper->wake();
     }
+    if (mPollThread.joinable()) {
+        mPollThread.join();
+    }
 }
 
 // Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
@@ -128,12 +134,13 @@
 }
 
 /* One global looper for all event queues created from this SensorManager. */
-sp<::android::Looper> SensorManager::getLooper() {
-    std::unique_lock<std::mutex> lock(mLooperMutex);
-    if (mLooper == nullptr) {
-        std::condition_variable looperSet;
+sp<Looper> SensorManager::getLooper() {
+    std::lock_guard<std::mutex> lock(mThreadMutex);
 
-        std::thread{[&mutex = mLooperMutex, &looper = mLooper, &looperSet, javaVm = mJavaVm] {
+    if (!mPollThread.joinable()) {
+        // if thread not initialized, start thread
+        mStopThread = false;
+        std::thread pollThread{[&stopThread = mStopThread, looper = mLooper, javaVm = mJavaVm] {
 
             struct sched_param p = {0};
             p.sched_priority = 10;
@@ -142,16 +149,11 @@
                         << strerror(errno);
             }
 
-            std::unique_lock<std::mutex> lock(mutex);
-            if (looper != nullptr) {
-                LOG(INFO) << "Another thread has already set the looper, exiting this one.";
-                return;
-            }
-            looper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS /* opts */);
-            lock.unlock();
+            // set looper
+            Looper::setForThread(looper);
 
-            // Attach the thread to JavaVM so that pollAll do not crash if the event
-            // is from Java.
+            // Attach the thread to JavaVM so that pollAll do not crash if the thread
+            // eventually calls into Java.
             JavaVMAttachArgs args{
                 .version = JNI_VERSION_1_2,
                 .name = POLL_THREAD_NAME,
@@ -162,19 +164,30 @@
                 LOG(FATAL) << "Cannot attach SensorManager looper thread to Java VM.";
             }
 
-            looperSet.notify_one();
-            int pollResult = looper->pollAll(-1 /* timeout */);
-            if (pollResult != ALOOPER_POLL_WAKE) {
-                LOG(ERROR) << "Looper::pollAll returns unexpected " << pollResult;
+            LOG(INFO) << POLL_THREAD_NAME << " started.";
+            for (;;) {
+                int pollResult = looper->pollAll(-1 /* timeout */);
+                if (pollResult == Looper::POLL_WAKE) {
+                    if (stopThread == true) {
+                        LOG(INFO) << POLL_THREAD_NAME << ": requested to stop";
+                        break;
+                    } else {
+                        LOG(INFO) << POLL_THREAD_NAME << ": spurious wake up, back to work";
+                    }
+                } else {
+                    LOG(ERROR) << POLL_THREAD_NAME << ": Looper::pollAll returns unexpected "
+                               << pollResult;
+                    break;
+                }
             }
 
             if (javaVm->DetachCurrentThread() != JNI_OK) {
                 LOG(ERROR) << "Cannot detach SensorManager looper thread from Java VM.";
             }
 
-            LOG(INFO) << "Looper thread is terminated.";
-        }}.detach();
-        looperSet.wait(lock, [this]{ return this->mLooper != nullptr; });
+            LOG(INFO) << POLL_THREAD_NAME << " is terminated.";
+        }};
+        mPollThread = std::move(pollThread);
     }
     return mLooper;
 }
@@ -196,7 +209,15 @@
     }
 
     sp<::android::Looper> looper = getLooper();
-    sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue();
+    if (looper == nullptr) {
+        LOG(ERROR) << "::android::SensorManager::createEventQueue cannot initialize looper";
+        _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+        return Void();
+    }
+
+    String8 package(String8::format("hidl_client_pid_%d",
+                                    android::hardware::IPCThreadState::self()->getCallingPid()));
+    sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue(package);
     if (internalQueue == nullptr) {
         LOG(WARNING) << "::android::SensorManager::createEventQueue returns nullptr.";
         _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
index e66c8e5..ddcee28 100644
--- a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -20,6 +20,7 @@
 #include <jni.h>
 
 #include <mutex>
+#include <thread>
 
 #include <android/frameworks/sensorservice/1.0/ISensorManager.h>
 #include <android/frameworks/sensorservice/1.0/types.h>
@@ -38,6 +39,7 @@
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_memory;
 using ::android::hardware::Return;
+using ::android::sp;
 
 struct SensorManager final : public ISensorManager {
 
@@ -54,13 +56,15 @@
 private:
     // Block until ::android::SensorManager is initialized.
     ::android::SensorManager& getInternalManager();
-    sp<::android::Looper> getLooper();
+    sp<Looper> getLooper();
 
     std::mutex mInternalManagerMutex;
     ::android::SensorManager* mInternalManager = nullptr; // does not own
+    sp<Looper> mLooper;
 
-    std::mutex mLooperMutex;
-    sp<::android::Looper> mLooper;
+    volatile bool mStopThread;
+    std::mutex mThreadMutex; //protects mPollThread
+    std::thread mPollThread;
 
     JavaVM* mJavaVm;
 };
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 7564269..ed220f8 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -26,7 +26,7 @@
 #include <vector>
 #include <SurfaceFlinger.h>
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bcd7afe..310435b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -94,7 +94,7 @@
  */
 #define DEBUG_SCREENSHOTS   false
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
 namespace android {
 
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 0904fab..28178b9 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -94,7 +94,7 @@
  */
 #define DEBUG_SCREENSHOTS   false
 
-EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
+extern "C" EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name);
 
 namespace android {
 // ---------------------------------------------------------------------------