Merge "Cancel touches as well as pointer gestures." into mnc-dev
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index f2c76d5..0c3ae02 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -177,7 +177,7 @@
     return 0;
 }
 
-int move_complete_app(const char *from_uuid, const char *to_uuid,
+int copy_complete_app(const char *from_uuid, const char *to_uuid,
         const char *package_name, const char *data_app_name, appid_t appid,
         const char* seinfo) {
     std::vector<userid_t> users = get_known_users(from_uuid);
@@ -264,19 +264,9 @@
         }
     }
 
-    // Delete old app and data
-    {
-        std::string from(create_data_app_package_path(from_uuid, data_app_name));
-        if (delete_dir_contents(from.c_str(), 1, NULL) != 0) {
-            LOG(WARNING) << "Failed to delete " << from;
-        }
-    }
-    for (auto user : users) {
-        std::string from(create_data_user_package_path(from_uuid, user, package_name));
-        if (delete_dir_contents(from.c_str(), 1, NULL) != 0) {
-            LOG(WARNING) << "Failed to delete " << from;
-        }
-    }
+    // We let the framework scan the new location and persist that before
+    // deleting the data in the old location; this ordering ensures that
+    // we can recover from things like battery pulls.
     return 0;
 
 fail:
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 297b3a1..13e3168 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -124,10 +124,10 @@
     return delete_user_data(parse_null(arg[0]), arg[1], atoi(arg[2])); /* uuid, pkgname, userid */
 }
 
-static int do_mv_complete_app(char **arg, char reply[REPLY_MAX] __unused)
+static int do_cp_complete_app(char **arg, char reply[REPLY_MAX] __unused)
 {
     // from_uuid, to_uuid, package_name, data_app_name, appid, seinfo
-    return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]);
+    return copy_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]);
 }
 
 static int do_mk_user_data(char **arg, char reply[REPLY_MAX] __unused)
@@ -206,7 +206,7 @@
     { "rmcodecache",          3, do_rm_code_cache },
     { "getsize",              8, do_get_size },
     { "rmuserdata",           3, do_rm_user_data },
-    { "mvcompleteapp",        6, do_mv_complete_app },
+    { "cpcompleteapp",        6, do_cp_complete_app },
     { "movefiles",            0, do_movefiles },
     { "linklib",              4, do_linklib },
     { "mkuserdata",           5, do_mk_user_data },
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 744ed3a..7ec5793 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -225,7 +225,7 @@
 int delete_user_data(const char *uuid, const char *pkgname, userid_t userid);
 int make_user_data(const char *uuid, const char *pkgname, uid_t uid,
         userid_t userid, const char* seinfo);
-int move_complete_app(const char* from_uuid, const char *to_uuid,
+int copy_complete_app(const char* from_uuid, const char *to_uuid,
         const char *package_name, const char *data_app_name, appid_t appid,
         const char* seinfo);
 int make_user_config(userid_t userid);
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
index 4feb6db..3dca2a3 100644
--- a/include/gui/ISensorServer.h
+++ b/include/gui/ISensorServer.h
@@ -40,7 +40,7 @@
     virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int mode, const String16& opPackageName) = 0;
-    virtual status_t enableDataInjection(int enable) = 0;
+    virtual int32_t isDataInjectionEnabled() = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index 4c34e12..3796067 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -107,7 +107,7 @@
     ssize_t getSensorList(Sensor const* const** list) const;
     Sensor const* getDefaultSensor(int type);
     sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
-    status_t enableDataInjection(bool enable);
+    bool isDataInjectionEnabled();
 
 private:
     // DeathRecipient interface
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 38fb757..87e5b4d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -922,8 +922,8 @@
                     mCore->mSidebandStream.clear();
                     mCore->mDequeueCondition.broadcast();
                     listener = mCore->mConsumerListener;
-                } else {
-                    BQ_LOGE("disconnect(P): connected to another API "
+                } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+                    BQ_LOGE("disconnect(P): still connected to another API "
                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
                     status = BAD_VALUE;
                 }
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 5dde9f9..f581b5c 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -77,10 +77,9 @@
         return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
     }
 
-    virtual status_t enableDataInjection(int enable) {
+    virtual int isDataInjectionEnabled() {
         Parcel data, reply;
         data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
-        data.writeInt32(enable);
         remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
         return reply.readInt32();
     }
@@ -121,8 +120,7 @@
         }
         case ENABLE_DATA_INJECTION: {
             CHECK_INTERFACE(ISensorServer, data, reply);
-            int32_t enable = data.readInt32();
-            status_t ret = enableDataInjection(enable);
+            int32_t ret = isDataInjectionEnabled();
             reply->writeInt32(static_cast<int32_t>(ret));
             return NO_ERROR;
         }
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 8b2018f..4b7986e 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <linux/errno.h>
 
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -150,13 +151,20 @@
 }
 
 status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) {
-   // Blocking call.
-   ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
-   if (size < 0) {
-       ALOGE("injectSensorEvent failure %zd %d", size, mSensorChannel->getFd());
-       return INVALID_OPERATION;
-   }
-   return NO_ERROR;
+    do {
+        // Blocking call.
+        ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL);
+        if (size >= 0) {
+            return NO_ERROR;
+        } else if (size < 0 && errno == EAGAIN) {
+            // If send is returning a "Try again" error, sleep for 100ms and try again. In all
+            // other cases log a failure and exit.
+            usleep(100000);
+        } else {
+            ALOGE("injectSensorEvent failure %s %zd", strerror(errno), size);
+            return INVALID_OPERATION;
+        }
+    } while (true);
 }
 
 void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 8c9f95b..dd37781 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -153,12 +153,12 @@
     return queue;
 }
 
-status_t SensorManager::enableDataInjection(bool enable) {
+bool SensorManager::isDataInjectionEnabled() {
     Mutex::Autolock _l(mLock);
     if (assertStateLocked() == NO_ERROR) {
-        return mSensorServer->enableDataInjection(enable);
+        return mSensorServer->isDataInjectionEnabled();
     }
-    return INVALID_OPERATION;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 5444631..8378907 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -91,11 +91,19 @@
         "EGL_KHR_gl_colorspace "
 #endif
         "EGL_KHR_gl_texture_2D_image "
+        "EGL_KHR_gl_texture_3D_image "
         "EGL_KHR_gl_texture_cubemap_image "
         "EGL_KHR_gl_renderbuffer_image "
         "EGL_KHR_reusable_sync "
         "EGL_KHR_fence_sync "
         "EGL_KHR_create_context "
+        "EGL_KHR_config_attribs "
+        "EGL_KHR_surfaceless_context "
+        "EGL_KHR_stream "
+        "EGL_KHR_stream_fifo "
+        "EGL_KHR_stream_producer_eglsurface "
+        "EGL_KHR_stream_consumer_gltexture "
+        "EGL_KHR_stream_cross_process_fd "
         "EGL_EXT_create_context_robustness "
         "EGL_NV_system_time "
         "EGL_ANDROID_image_native_buffer "      // mandatory
@@ -164,6 +172,31 @@
     // EGL_KHR_partial_update
     { "eglSetDamageRegionKHR",
             (__eglMustCastToProperFunctionPointerType)&eglSetDamageRegionKHR },
+
+    { "eglCreateStreamKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamKHR },
+    { "eglDestroyStreamKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglDestroyStreamKHR },
+    { "eglStreamAttribKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglStreamAttribKHR },
+    { "eglQueryStreamKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamKHR },
+    { "eglQueryStreamu64KHR",
+            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamu64KHR },
+    { "eglQueryStreamTimeKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglQueryStreamTimeKHR },
+    { "eglCreateStreamProducerSurfaceKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamProducerSurfaceKHR },
+    { "eglStreamConsumerGLTextureExternalKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerGLTextureExternalKHR },
+    { "eglStreamConsumerAcquireKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerAcquireKHR },
+    { "eglStreamConsumerReleaseKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglStreamConsumerReleaseKHR },
+    { "eglGetStreamFileDescriptorKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglGetStreamFileDescriptorKHR },
+    { "eglCreateStreamFromFileDescriptorKHR",
+            (__eglMustCastToProperFunctionPointerType)&eglCreateStreamFromFileDescriptorKHR },
 };
 
 /*
@@ -562,6 +595,15 @@
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     egl_surface_t * const s = get_surface(surface);
+    ANativeWindow* window = s->win.get();
+    if (window) {
+        int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+        if (result != OK) {
+            ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) "
+                  "failed (%#x)",
+                  window, result);
+        }
+    }
     EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
     if (result == EGL_TRUE) {
         _s.terminate();
@@ -1518,6 +1560,212 @@
     return result;
 }
 
+EGLStreamKHR eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_NO_STREAM_KHR;
+
+    EGLStreamKHR result = EGL_NO_STREAM_KHR;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglCreateStreamKHR) {
+        result = cnx->egl.eglCreateStreamKHR(
+                dp->disp.dpy, attrib_list);
+    }
+    return result;
+}
+
+EGLBoolean eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglDestroyStreamKHR) {
+        result = cnx->egl.eglDestroyStreamKHR(
+                dp->disp.dpy, stream);
+    }
+    return result;
+}
+
+EGLBoolean eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream,
+        EGLenum attribute, EGLint value)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglStreamAttribKHR) {
+        result = cnx->egl.eglStreamAttribKHR(
+                dp->disp.dpy, stream, attribute, value);
+    }
+    return result;
+}
+
+EGLBoolean eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
+        EGLenum attribute, EGLint *value)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglQueryStreamKHR) {
+        result = cnx->egl.eglQueryStreamKHR(
+                dp->disp.dpy, stream, attribute, value);
+    }
+    return result;
+}
+
+EGLBoolean eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream,
+        EGLenum attribute, EGLuint64KHR *value)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglQueryStreamu64KHR) {
+        result = cnx->egl.eglQueryStreamu64KHR(
+                dp->disp.dpy, stream, attribute, value);
+    }
+    return result;
+}
+
+EGLBoolean eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream,
+        EGLenum attribute, EGLTimeKHR *value)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglQueryStreamTimeKHR) {
+        result = cnx->egl.eglQueryStreamTimeKHR(
+                dp->disp.dpy, stream, attribute, value);
+    }
+    return result;
+}
+
+EGLSurface eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config,
+        EGLStreamKHR stream, const EGLint *attrib_list)
+{
+    clearError();
+
+    egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_NO_SURFACE;
+
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglCreateStreamProducerSurfaceKHR) {
+        EGLSurface surface = cnx->egl.eglCreateStreamProducerSurfaceKHR(
+                dp->disp.dpy, config, stream, attrib_list);
+        if (surface != EGL_NO_SURFACE) {
+            egl_surface_t* s = new egl_surface_t(dp.get(), config, NULL,
+                    surface, cnx);
+            return s;
+        }
+    }
+    return EGL_NO_SURFACE;
+}
+
+EGLBoolean eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
+        EGLStreamKHR stream)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglStreamConsumerGLTextureExternalKHR) {
+        result = cnx->egl.eglStreamConsumerGLTextureExternalKHR(
+                dp->disp.dpy, stream);
+    }
+    return result;
+}
+
+EGLBoolean eglStreamConsumerAcquireKHR(EGLDisplay dpy,
+        EGLStreamKHR stream)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglStreamConsumerAcquireKHR) {
+        result = cnx->egl.eglStreamConsumerAcquireKHR(
+                dp->disp.dpy, stream);
+    }
+    return result;
+}
+
+EGLBoolean eglStreamConsumerReleaseKHR(EGLDisplay dpy,
+        EGLStreamKHR stream)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_FALSE;
+
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglStreamConsumerReleaseKHR) {
+        result = cnx->egl.eglStreamConsumerReleaseKHR(
+                dp->disp.dpy, stream);
+    }
+    return result;
+}
+
+EGLNativeFileDescriptorKHR eglGetStreamFileDescriptorKHR(
+        EGLDisplay dpy, EGLStreamKHR stream)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_NO_FILE_DESCRIPTOR_KHR;
+
+    EGLNativeFileDescriptorKHR result = EGL_NO_FILE_DESCRIPTOR_KHR;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglGetStreamFileDescriptorKHR) {
+        result = cnx->egl.eglGetStreamFileDescriptorKHR(
+                dp->disp.dpy, stream);
+    }
+    return result;
+}
+
+EGLStreamKHR eglCreateStreamFromFileDescriptorKHR(
+        EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor)
+{
+    clearError();
+
+    const egl_display_ptr dp = validate_display(dpy);
+    if (!dp) return EGL_NO_STREAM_KHR;
+
+    EGLStreamKHR result = EGL_NO_STREAM_KHR;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglCreateStreamFromFileDescriptorKHR) {
+        result = cnx->egl.eglCreateStreamFromFileDescriptorKHR(
+                dp->disp.dpy, file_descriptor);
+    }
+    return result;
+}
+
 // ----------------------------------------------------------------------------
 // EGL_EGLEXT_VERSION 15
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in
index 1e27cb6..498b2fc 100644
--- a/opengl/libs/EGL/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -61,18 +61,18 @@
 
 /* EGL_EGLEXT_VERSION 15 */
 
-//    EGL_ENTRY(EGLStreamKHR, eglCreateStreamKHR,     EGLDisplay, const EGLint *)
-//    EGL_ENTRY(EGLBoolean,   eglDestroyStreamKHR,    EGLDisplay, EGLStreamKHR)
-//    EGL_ENTRY(EGLBoolean,   eglStreamAttribKHR,     EGLDisplay, EGLStreamKHR, EGLenum, EGLint)
-//    EGL_ENTRY(EGLBoolean,   eglQueryStreamKHR,      EGLDisplay, EGLStreamKHR, EGLenum, EGLint *)
-//    EGL_ENTRY(EGLBoolean,   eglQueryStreamu64KHR,   EGLDisplay, EGLStreamKHR, EGLenum, EGLuint64KHR *)
-//    EGL_ENTRY(EGLBoolean,   eglStreamConsumerGLTextureExternalKHR,  EGLDisplay, EGLStreamKHR)
-//    EGL_ENTRY(EGLBoolean,   eglStreamConsumerAcquireKHR,            EGLDisplay, EGLStreamKHR)
-//    EGL_ENTRY(EGLBoolean,   eglStreamConsumerReleaseKHR,            EGLDisplay, EGLStreamKHR)
-//    EGL_ENTRY(EGLSurface,   eglCreateStreamProducerSurfaceKHR,      EGLDisplay, EGLConfig, EGLStreamKHR, const EGLint *)
-//    EGL_ENTRY(EGLBoolean,   eglQueryStreamTimeKHR,  EGLDisplay, EGLStreamKHR, EGLenum, EGLTimeKHR*)
-//    EGL_ENTRY(EGLNativeFileDescriptorKHR,   eglGetStreamFileDescriptorKHR,          EGLDisplay, EGLStreamKHR)
-//    EGL_ENTRY(EGLStreamKHR, eglCreateStreamFromFileDescriptorKHR,   EGLDisplay, EGLNativeFileDescriptorKHR)
+EGL_ENTRY(EGLStreamKHR, eglCreateStreamKHR,     EGLDisplay, const EGLint *)
+EGL_ENTRY(EGLBoolean,   eglDestroyStreamKHR,    EGLDisplay, EGLStreamKHR)
+EGL_ENTRY(EGLBoolean,   eglStreamAttribKHR,     EGLDisplay, EGLStreamKHR, EGLenum, EGLint)
+EGL_ENTRY(EGLBoolean,   eglQueryStreamKHR,      EGLDisplay, EGLStreamKHR, EGLenum, EGLint *)
+EGL_ENTRY(EGLBoolean,   eglQueryStreamu64KHR,   EGLDisplay, EGLStreamKHR, EGLenum, EGLuint64KHR *)
+EGL_ENTRY(EGLBoolean,   eglStreamConsumerGLTextureExternalKHR,  EGLDisplay, EGLStreamKHR)
+EGL_ENTRY(EGLBoolean,   eglStreamConsumerAcquireKHR,            EGLDisplay, EGLStreamKHR)
+EGL_ENTRY(EGLBoolean,   eglStreamConsumerReleaseKHR,            EGLDisplay, EGLStreamKHR)
+EGL_ENTRY(EGLSurface,   eglCreateStreamProducerSurfaceKHR,      EGLDisplay, EGLConfig, EGLStreamKHR, const EGLint *)
+EGL_ENTRY(EGLBoolean,   eglQueryStreamTimeKHR,  EGLDisplay, EGLStreamKHR, EGLenum, EGLTimeKHR*)
+EGL_ENTRY(EGLNativeFileDescriptorKHR,   eglGetStreamFileDescriptorKHR,          EGLDisplay, EGLStreamKHR)
+EGL_ENTRY(EGLStreamKHR, eglCreateStreamFromFileDescriptorKHR,   EGLDisplay, EGLNativeFileDescriptorKHR)
 EGL_ENTRY(EGLint,       eglWaitSyncKHR,         EGLDisplay, EGLSyncKHR, EGLint)
 
 /* ANDROID extensions */
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 550107c..71aa160 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -66,7 +66,6 @@
 
 const char* SensorService::WAKE_LOCK_NAME = "SensorService";
 // Permissions.
-static const String16 sDataInjectionPermission("android.permission.LOCATION_HARDWARE");
 static const String16 sDump("android.permission.DUMP");
 
 SensorService::SensorService()
@@ -246,12 +245,12 @@
                 IPCThreadState::self()->getCallingPid(),
                 IPCThreadState::self()->getCallingUid());
     } else {
-        if (args.size() > 1) {
+        if (args.size() > 2) {
            return INVALID_OPERATION;
         }
         Mutex::Autolock _l(mLock);
         SensorDevice& dev(SensorDevice::getInstance());
-        if (args.size() == 1 && args[0] == String16("restrict")) {
+        if (args.size() == 2 && args[0] == String16("restrict")) {
             // If already in restricted mode. Ignore.
             if (mCurrentOperatingMode == RESTRICTED) {
                 return status_t(NO_ERROR);
@@ -268,6 +267,7 @@
             for (size_t i=0 ; i< mActiveSensors.size(); ++i) {
                 mActiveSensors.valueAt(i)->clearAllPendingFlushConnections();
             }
+            mWhiteListedPackage.setTo(String8(args[1]));
             return status_t(NO_ERROR);
         } else if (args.size() == 1 && args[0] == String16("enable")) {
             // If currently in restricted mode, reset back to NORMAL mode else ignore.
@@ -275,7 +275,30 @@
                 mCurrentOperatingMode = NORMAL;
                 dev.enableAllSensors();
             }
+            if (mCurrentOperatingMode == DATA_INJECTION) {
+               resetToNormalModeLocked();
+            }
+            mWhiteListedPackage.clear();
             return status_t(NO_ERROR);
+        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
+            if (mCurrentOperatingMode == NORMAL) {
+                dev.disableAllSensors();
+                status_t err = dev.setMode(DATA_INJECTION);
+                if (err == NO_ERROR) {
+                    mCurrentOperatingMode = DATA_INJECTION;
+                } else {
+                    // Re-enable sensors.
+                    dev.enableAllSensors();
+                }
+                mWhiteListedPackage.setTo(String8(args[1]));
+                return NO_ERROR;
+            } else if (mCurrentOperatingMode == DATA_INJECTION) {
+                // Already in DATA_INJECTION mode. Treat this as a no_op.
+                return NO_ERROR;
+            } else {
+                // Transition to data injection mode supported only from NORMAL mode.
+                return INVALID_OPERATION;
+            }
         } else if (mSensorList.size() == 0) {
             result.append("No Sensors on the device\n");
         } else {
@@ -362,10 +385,10 @@
                    result.appendFormat(" NORMAL\n");
                    break;
                case RESTRICTED:
-                   result.appendFormat(" RESTRICTED\n");
+                   result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string());
                    break;
                case DATA_INJECTION:
-                   result.appendFormat(" DATA_INJECTION\n");
+                   result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
             }
             result.appendFormat("%zd active connections\n", mActiveConnections.size());
 
@@ -712,12 +735,15 @@
     if (requestedMode != NORMAL && requestedMode != DATA_INJECTION) {
         return NULL;
     }
-    // DATA_INJECTION mode needs to have the required permissions set.
-    if (requestedMode == DATA_INJECTION && !hasDataInjectionPermissions()) {
-        return NULL;
-    }
 
     Mutex::Autolock _l(mLock);
+    // To create a client in DATA_INJECTION mode to inject data, SensorService should already be
+    // operating in DI mode.
+    if (requestedMode == DATA_INJECTION) {
+        if (mCurrentOperatingMode != DATA_INJECTION) return NULL;
+        if (!isWhiteListedPackage(packageName)) return NULL;
+    }
+
     uid_t uid = IPCThreadState::self()->getCallingUid();
     sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
             requestedMode == DATA_INJECTION, opPackageName));
@@ -732,35 +758,9 @@
     return result;
 }
 
-status_t SensorService::enableDataInjection(int requestedMode) {
-    if (!hasDataInjectionPermissions()) {
-        return INVALID_OPERATION;
-    }
+int SensorService::isDataInjectionEnabled() {
     Mutex::Autolock _l(mLock);
-    ALOGD_IF(DEBUG_CONNECTIONS, "SensorService::enableDataInjection %d", requestedMode);
-    SensorDevice& dev(SensorDevice::getInstance());
-    status_t err(NO_ERROR);
-    if (requestedMode == DATA_INJECTION) {
-        if (mCurrentOperatingMode == NORMAL) {
-           dev.disableAllSensors();
-           err = dev.setMode(requestedMode);
-           if (err == NO_ERROR) {
-               mCurrentOperatingMode = DATA_INJECTION;
-           } else {
-               // Re-enable sensors.
-               dev.enableAllSensors();
-           }
-       } else if (mCurrentOperatingMode == DATA_INJECTION) {
-           // Already in DATA_INJECTION mode. Treat this as a no_op.
-           return NO_ERROR;
-       } else {
-           // Transition to data injection mode supported only from NORMAL mode.
-           return INVALID_OPERATION;
-       }
-    } else if (requestedMode == NORMAL && mCurrentOperatingMode != NORMAL) {
-       err = resetToNormalModeLocked();
-    }
-    return err;
+    return (mCurrentOperatingMode == DATA_INJECTION);
 }
 
 status_t SensorService::resetToNormalMode() {
@@ -838,7 +838,8 @@
     }
 
     Mutex::Autolock _l(mLock);
-    if (mCurrentOperatingMode == RESTRICTED && !isWhiteListedPackage(connection->getPackageName())) {
+    if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION)
+           && !isWhiteListedPackage(connection->getPackageName())) {
         return INVALID_OPERATION;
     }
 
@@ -1106,15 +1107,6 @@
     return true;
 }
 
-bool SensorService::hasDataInjectionPermissions() {
-    if (!PermissionCache::checkCallingPermission(sDataInjectionPermission)) {
-        ALOGE("Permission Denial trying to activate data injection without"
-              " the required permission");
-        return false;
-    }
-    return true;
-}
-
 void SensorService::checkWakeLockState() {
     Mutex::Autolock _l(mLock);
     checkWakeLockStateLocked();
@@ -1159,8 +1151,7 @@
 }
 
 bool SensorService::isWhiteListedPackage(const String8& packageName) {
-    // TODO: Come up with a list of packages.
-    return (packageName.find(".cts.") != -1);
+    return (packageName.contains(mWhiteListedPackage.string()));
 }
 
 int SensorService::getNumEventsForSensorType(int sensor_event_type) {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 0a7abe8..9a573ae 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -100,6 +100,18 @@
       // State Transitions supported.
       //     RESTRICTED   <---  NORMAL   ---> DATA_INJECTION
       //                  --->           <---
+
+      // Shell commands to switch modes in SensorService.
+      // 1) Put SensorService in RESTRICTED mode with packageName .cts. If it is already in
+      // restricted mode it is treated as a NO_OP (and packageName is NOT changed).
+      // $ adb shell dumpsys sensorservice restrict .cts.
+      //
+      // 2) Put SensorService in DATA_INJECTION mode with packageName .xts. If it is already in
+      // data_injection mode it is treated as a NO_OP (and packageName is NOT changed).
+      // $ adb shell dumpsys sensorservice data_injection .xts.
+      //
+      // 3) Reset sensorservice back to NORMAL mode.
+      // $ adb shell dumpsys sensorservice enable
     };
 
     static const char* WAKE_LOCK_NAME;
@@ -117,7 +129,7 @@
     virtual Vector<Sensor> getSensorList(const String16& opPackageName);
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int requestedMode, const String16& opPackageName);
-    virtual status_t enableDataInjection(int enable);
+    virtual int isDataInjectionEnabled();
     virtual status_t dump(int fd, const Vector<String16>& args);
 
     class SensorEventConnection : public BnSensorEventConnection, public LooperCallback {
@@ -334,7 +346,6 @@
             sensors_event_t const* buffer, const int count);
     static bool canAccessSensor(const Sensor& sensor, const char* operation,
             const String16& opPackageName);
-    static bool hasDataInjectionPermissions();
     // SensorService acquires a partial wakelock for delivering events from wake up sensors. This
     // method checks whether all the events from these wake up sensors have been delivered to the
     // corresponding applications, if yes the wakelock is released.
@@ -394,6 +405,11 @@
     sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
     SensorEventConnection const **mMapFlushEventsToConnections;
     Mode mCurrentOperatingMode;
+    // This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only
+    // applications with this packageName are allowed to activate/deactivate or call flush on
+    // sensors. To run CTS this is can be set to ".cts." and only CTS tests will get access to
+    // sensors.
+    String8 mWhiteListedPackage;
 
     // The size of this vector is constant, only the items are mutable
     KeyedVector<int32_t, CircularBuffer *> mLastEventSeen;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 91f80b6..e2418cc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1102,10 +1102,21 @@
 
 bool Layer::shouldPresentNow(const DispSync& dispSync) const {
     Mutex::Autolock lock(mQueueItemLock);
+    if (mQueueItems.empty()) {
+        return false;
+    }
+    auto timestamp = mQueueItems[0].mTimestamp;
     nsecs_t expectedPresent =
             mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
-    return mQueueItems.empty() ?
-            false : mQueueItems[0].mTimestamp < expectedPresent;
+
+    // Ignore timestamps more than a second in the future
+    bool isPlausible = timestamp < (expectedPresent + s2ns(1));
+    ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible "
+            "relative to expectedPresent %" PRId64, mName.string(), timestamp,
+            expectedPresent);
+
+    bool isDue = timestamp < expectedPresent;
+    return isDue || !isPlausible;
 }
 
 bool Layer::onPreComposition() {