Merge "Cleanup dvr api headers for exporting"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index ca799c9..301bb67 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -183,6 +183,7 @@
     { "binder_driver", "Binder Kernel driver", 0, {
         { REQ,      "events/binder/binder_transaction/enable" },
         { REQ,      "events/binder/binder_transaction_received/enable" },
+        { OPT,      "events/binder/binder_set_priority/enable" },
     } },
     { "binder_lock", "Binder global lock trace", 0, {
         { OPT,      "events/binder/binder_lock/enable" },
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 7419eb4..22de64e 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1940,8 +1940,11 @@
     // Derive and delete the app image.
     bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
 
+    // Derive and delete the vdex file.
+    bool return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str());
+
     // Report success.
-    return return_value_oat && return_value_art;
+    return return_value_oat && return_value_art && return_value_vdex;
 }
 
 }  // namespace installd
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 38b406c..2eb58ae 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -73,46 +73,92 @@
     }), pids->end());
 }
 
-bool ListCommand::getReferencedPids(
-        pid_t serverPid, std::map<uint64_t, Pids> *objects) const {
-
-    std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid));
+bool scanBinderContext(pid_t pid,
+        const std::string &contextName,
+        std::function<void(const std::string&)> eachLine) {
+    std::ifstream ifs("/d/binder/proc/" + std::to_string(pid));
     if (!ifs.is_open()) {
         return false;
     }
 
-    static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
+    static const std::regex kContextLine("^context (\\w+)$");
 
+    bool isDesiredContext = false;
     std::string line;
     std::smatch match;
     while(getline(ifs, line)) {
-        if (!std::regex_search(line, match, prefix)) {
-            // the line doesn't start with the correct prefix
+        if (std::regex_search(line, match, kContextLine)) {
+            isDesiredContext = match.str(1) == contextName;
             continue;
         }
-        std::string ptrString = "0x" + match.str(2); // use number after c
-        uint64_t ptr;
-        if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) {
-            // Should not reach here, but just be tolerant.
-            mErr << "Could not parse number " << ptrString << std::endl;
+
+        if (!isDesiredContext) {
             continue;
         }
-        const std::string proc = " proc ";
-        auto pos = line.rfind(proc);
-        if (pos != std::string::npos) {
-            for (const std::string &pidStr : split(line.substr(pos + proc.size()), ' ')) {
-                int32_t pid;
-                if (!::android::base::ParseInt(pidStr, &pid)) {
-                    mErr << "Could not parse number " << pidStr << std::endl;
-                    continue;
-                }
-                (*objects)[ptr].push_back(pid);
-            }
-        }
+
+        eachLine(line);
     }
     return true;
 }
 
+bool ListCommand::getPidInfo(
+        pid_t serverPid, PidInfo *pidInfo) const {
+    static const std::regex kReferencePrefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
+    static const std::regex kThreadPrefix("^\\s*thread \\d+:\\s+l\\s+(\\d)(\\d)");
+
+    std::smatch match;
+    return scanBinderContext(serverPid, "hwbinder", [&](const std::string& line) {
+        if (std::regex_search(line, match, kReferencePrefix)) {
+            const std::string &ptrString = "0x" + match.str(2); // use number after c
+            uint64_t ptr;
+            if (!::android::base::ParseUint(ptrString.c_str(), &ptr)) {
+                // Should not reach here, but just be tolerant.
+                mErr << "Could not parse number " << ptrString << std::endl;
+                return;
+            }
+            const std::string proc = " proc ";
+            auto pos = line.rfind(proc);
+            if (pos != std::string::npos) {
+                for (const std::string &pidStr : split(line.substr(pos + proc.size()), ' ')) {
+                    int32_t pid;
+                    if (!::android::base::ParseInt(pidStr, &pid)) {
+                        mErr << "Could not parse number " << pidStr << std::endl;
+                        return;
+                    }
+                    pidInfo->refPids[ptr].push_back(pid);
+                }
+            }
+
+            return;
+        }
+
+        if (std::regex_search(line, match, kThreadPrefix)) {
+            // "1" is waiting in binder driver
+            // "2" is poll. It's impossible to tell if these are in use.
+            //     and HIDL default code doesn't use it.
+            bool isInUse = match.str(1) != "1";
+            // "0" is a thread that has called into binder
+            // "1" is looper thread
+            // "2" is main looper thread
+            bool isHwbinderThread = match.str(2) != "0";
+
+            if (!isHwbinderThread) {
+                return;
+            }
+
+            if (isInUse) {
+                pidInfo->threadUsage++;
+            }
+
+            pidInfo->threadCount++;
+            return;
+        }
+
+        // not reference or thread line
+        return;
+    });
+}
+
 // Must process hwbinder services first, then passthrough services.
 void ListCommand::forEachTable(const std::function<void(Table &)> &f) {
     f(mServicesTable);
@@ -164,9 +210,11 @@
         const std::string &interfaceName,
         const std::string &transport,
         const std::string &arch,
+        const std::string &threadUsage,
         const std::string &server,
         const std::string &serverCmdline,
-        const std::string &address, const std::string &clients,
+        const std::string &address,
+        const std::string &clients,
         const std::string &clientCmdlines) const {
     if (mSelectedColumns & ENABLE_INTERFACE_NAME)
         mOut << std::setw(80) << interfaceName << "\t";
@@ -174,6 +222,9 @@
         mOut << std::setw(10) << transport << "\t";
     if (mSelectedColumns & ENABLE_ARCH)
         mOut << std::setw(5) << arch << "\t";
+    if (mSelectedColumns & ENABLE_THREADS) {
+        mOut << std::setw(8) << threadUsage << "\t";
+    }
     if (mSelectedColumns & ENABLE_SERVER_PID) {
         if (mEnableCmdlines) {
             mOut << std::setw(15) << serverCmdline << "\t";
@@ -349,14 +400,15 @@
         }
         mOut << std::left;
         if (!mNeat) {
-            printLine("Interface", "Transport", "Arch", "Server", "Server CMD",
-                      "PTR", "Clients", "Clients CMD");
+            printLine("Interface", "Transport", "Arch", "Thread Use", "Server",
+                      "Server CMD", "PTR", "Clients", "Clients CMD");
         }
 
         for (const auto &entry : table) {
             printLine(entry.interfaceName,
                     entry.transport,
                     getArchString(entry.arch),
+                    entry.getThreadUsage(),
                     entry.serverPid == NO_PID ? "N/A" : std::to_string(entry.serverPid),
                     entry.serverCmdline,
                     entry.serverObjectAddress == NO_PTR ? "N/A" : toHexString(entry.serverObjectAddress),
@@ -492,7 +544,7 @@
     Status status = OK;
     // server pid, .ptr value of binder object, child pids
     std::map<std::string, DebugInfo> allDebugInfos;
-    std::map<pid_t, std::map<uint64_t, Pids>> allPids;
+    std::map<pid_t, PidInfo> allPids;
     for (const auto &fqInstanceName : fqInstanceNames) {
         const auto pair = splitFirst(fqInstanceName, '/');
         const auto &serviceName = pair.first;
@@ -516,7 +568,7 @@
         auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &debugInfo) {
             allDebugInfos[fqInstanceName] = debugInfo;
             if (debugInfo.pid >= 0) {
-                allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+                allPids[static_cast<pid_t>(debugInfo.pid)] = PidInfo();
             }
         });
         if (!debugRet.isOk()) {
@@ -526,9 +578,10 @@
             status |= DUMP_BINDERIZED_ERROR;
         }
     }
+
     for (auto &pair : allPids) {
         pid_t serverPid = pair.first;
-        if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+        if (!getPidInfo(serverPid, &allPids[serverPid])) {
             mErr << "Warning: no information for PID " << serverPid
                       << ", are you root?" << std::endl;
             status |= DUMP_BINDERIZED_ERROR;
@@ -543,18 +596,23 @@
                 .serverPid = NO_PID,
                 .serverObjectAddress = NO_PTR,
                 .clientPids = {},
+                .threadUsage = 0,
+                .threadCount = 0,
                 .arch = ARCH_UNKNOWN
             });
             continue;
         }
         const DebugInfo &info = it->second;
+        bool writePidInfo = info.pid != NO_PID && info.ptr != NO_PTR;
+
         putEntry(HWSERVICEMANAGER_LIST, {
             .interfaceName = fqInstanceName,
             .transport = mode,
             .serverPid = info.pid,
             .serverObjectAddress = info.ptr,
-            .clientPids = info.pid == NO_PID || info.ptr == NO_PTR
-                    ? Pids{} : allPids[info.pid][info.ptr],
+            .clientPids = writePidInfo ? allPids[info.pid].refPids[info.ptr] : Pids{},
+            .threadUsage = writePidInfo ? allPids[info.pid].threadUsage : 0,
+            .threadCount = writePidInfo ? allPids[info.pid].threadCount : 0,
             .arch = fromBaseArchitecture(info.arch),
         });
     }
@@ -593,6 +651,7 @@
         {"pid",       no_argument,       0, 'p' },
         {"address",   no_argument,       0, 'a' },
         {"clients",   no_argument,       0, 'c' },
+        {"threads",   no_argument,       0, 'e' },
         {"cmdline",   no_argument,       0, 'm' },
         {"debug",     optional_argument, 0, 'd' },
 
@@ -609,7 +668,7 @@
     for (;;) {
         // using getopt_long in case we want to add other options in the future
         c = getopt_long(arg.argc, arg.argv,
-                "hitrpacmd", longOptions, &optionIndex);
+                "hitrpacmde", longOptions, &optionIndex);
         if (c == -1) {
             break;
         }
@@ -661,6 +720,10 @@
             mSelectedColumns |= ENABLE_CLIENT_PIDS;
             break;
         }
+        case 'e': {
+            mSelectedColumns |= ENABLE_THREADS;
+            break;
+        }
         case 'm': {
             mEnableCmdlines = true;
             break;
@@ -695,7 +758,7 @@
     }
 
     if (mSelectedColumns == 0) {
-        mSelectedColumns = ENABLE_INTERFACE_NAME | ENABLE_SERVER_PID | ENABLE_CLIENT_PIDS;
+        mSelectedColumns = ENABLE_INTERFACE_NAME | ENABLE_SERVER_PID | ENABLE_CLIENT_PIDS | ENABLE_THREADS;
     }
     return OK;
 }
diff --git a/cmds/lshal/ListCommand.h b/cmds/lshal/ListCommand.h
index f367d7f..a75db04 100644
--- a/cmds/lshal/ListCommand.h
+++ b/cmds/lshal/ListCommand.h
@@ -48,18 +48,26 @@
     Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
     Status fetchBinderized(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
     Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
-    bool getReferencedPids(
-        pid_t serverPid, std::map<uint64_t, Pids> *objects) const;
+
+    struct PidInfo {
+        std::map<uint64_t, Pids> refPids; // pids that are referenced
+        uint32_t threadUsage; // number of threads in use
+        uint32_t threadCount; // number of threads total
+    };
+    bool getPidInfo(pid_t serverPid, PidInfo *info) const;
+
     void dumpTable();
     void dumpVintf() const;
     void printLine(
             const std::string &interfaceName,
             const std::string &transport,
             const std::string &arch,
+            const std::string &threadUsage,
             const std::string &server,
             const std::string &serverCmdline,
-            const std::string &address, const std::string &clients,
-            const std::string &clientCmdlines) const ;
+            const std::string &address,
+            const std::string &clients,
+            const std::string &clientCmdlines) const;
     // Return /proc/{pid}/cmdline if it exists, else empty string.
     const std::string &getCmdline(pid_t pid);
     // Call getCmdline on all pid in pids. If it returns empty string, the process might
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 9db42f1..e2d5f6d 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -66,7 +66,7 @@
             "        List all hals with default ordering and columns (`lshal list -ipc`)\n"
             "    lshal list [-h|--help]\n"
             "        -h, --help: Print help message for list (`lshal help list`)\n"
-            "    lshal [list] [--interface|-i] [--transport|-t] [-r|--arch]\n"
+            "    lshal [list] [--interface|-i] [--transport|-t] [-r|--arch] [-e|--threads]\n"
             "            [--pid|-p] [--address|-a] [--clients|-c] [--cmdline|-m]\n"
             "            [--sort={interface|i|pid|p}] [--init-vintf[=<output file>]]\n"
             "            [--debug|-d[=<output file>]]\n"
@@ -74,6 +74,8 @@
             "        -n, --instance: print the instance name column\n"
             "        -t, --transport: print the transport mode column\n"
             "        -r, --arch: print if the HAL is in 64-bit or 32-bit\n"
+            "        -e, --threads: print currently used/available threads\n"
+            "                       (note, available threads created lazily)\n"
             "        -p, --pid: print the server PID, or server cmdline if -m is set\n"
             "        -a, --address: print the server object address column\n"
             "        -c, --clients: print the client PIDs, or client cmdlines if -m is set\n"
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 9ae8f78..e04c3ca 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -47,6 +47,8 @@
     std::string interfaceName;
     std::string transport;
     int32_t serverPid;
+    uint32_t threadUsage;
+    uint32_t threadCount;
     std::string serverCmdline;
     uint64_t serverObjectAddress;
     Pids clientPids;
@@ -59,6 +61,14 @@
     static bool sortByServerPid(const TableEntry &a, const TableEntry &b) {
         return a.serverPid < b.serverPid;
     };
+
+    std::string getThreadUsage() const {
+        if (threadCount == 0) {
+            return "N/A";
+        }
+
+        return std::to_string(threadUsage) + "/" + std::to_string(threadCount);
+    }
 };
 
 struct Table {
@@ -80,7 +90,8 @@
     ENABLE_SERVER_PID     = 1 << 2,
     ENABLE_SERVER_ADDR    = 1 << 3,
     ENABLE_CLIENT_PIDS    = 1 << 4,
-    ENABLE_ARCH           = 1 << 5
+    ENABLE_ARCH           = 1 << 5,
+    ENABLE_THREADS        = 1 << 6,
 };
 
 using TableEntrySelect = unsigned int;
diff --git a/include/audiomanager/AudioManager.h b/include/audiomanager/AudioManager.h
index 834dcbd..009dc52 100644
--- a/include/audiomanager/AudioManager.h
+++ b/include/audiomanager/AudioManager.h
@@ -26,6 +26,9 @@
 typedef enum {
     PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE = 11,
     PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD = 12,
+    PLAYER_TYPE_AAUDIO = 13,
+    PLAYER_TYPE_HW_SOURCE = 14,
+    PLAYER_TYPE_EXTERNAL_PROXY = 15,
 } player_type_t;
 
 typedef enum {
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index bff80cd..4e275db 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -111,6 +111,7 @@
         "EGL/Loader.cpp",
         "EGL/BlobCache.cpp",
     ],
+    shared_libs: ["libvndksupport"],
     static_libs: ["libEGL_getProcAddress"],
     ldflags: ["-Wl,--exclude-libs=ALL"],
     export_include_dirs: ["EGL/include"],
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 1116400..6e5c510 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -29,6 +29,7 @@
 #include <log/log.h>
 
 #include <graphicsenv/GraphicsEnv.h>
+#include <vndksupport/linker.h>
 
 #include "egl_trace.h"
 #include "egldefs.h"
@@ -115,6 +116,11 @@
     return android_dlopen_ext(path, mode, info);
 }
 
+static void* do_android_load_sphal_library(const char* path, int mode) {
+    ATRACE_CALL();
+    return android_load_sphal_library(path, mode);
+}
+
 // ----------------------------------------------------------------------------
 
 Loader::driver_t::driver_t(void* gles)
@@ -424,27 +430,11 @@
     const char* const driver_absolute_path = absolutePath.c_str();
 
     // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
-    // the original routine when the namespace does not exist or the load from
-    // the namespace fails.
+    // the original routine when the namespace does not exist.
     // See /system/core/rootdir/etc/ld.config.txt for the configuration of the
     // sphal namespace.
-    android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
-    if (sphal_namespace != NULL) {
-        const android_dlextinfo dlextinfo = {
-            .flags = ANDROID_DLEXT_USE_NAMESPACE,
-            .library_namespace = sphal_namespace,
-        };
-        void* dso = do_android_dlopen_ext(driver_absolute_path, RTLD_LOCAL | RTLD_NOW, &dlextinfo);
-        if (dso) {
-            ALOGD("loaded %s from sphal namespace", driver_absolute_path);
-            return dso;
-        }
-        else {
-            ALOGW("failed to load %s from sphal namespace: %s", driver_absolute_path, dlerror());
-        }
-    }
-
-    void* dso = do_dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
+    void* dso = do_android_load_sphal_library(driver_absolute_path,
+                                              RTLD_NOW | RTLD_LOCAL);
     if (dso == 0) {
         const char* err = dlerror();
         ALOGE("load_driver(%s): %s", driver_absolute_path, err ? err : "unknown");
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 18b2e1b..a1ee294 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -40,9 +40,7 @@
 #include "Mesh.h"
 #include "Texture.h"
 
-#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
-#include <configstore/Utils.h>
-
+#include <sstream>
 #include <fstream>
 
 // ---------------------------------------------------------------------------
@@ -111,8 +109,10 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-GLES20RenderEngine::GLES20RenderEngine() :
-        mVpWidth(0), mVpHeight(0) {
+GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags) :
+         mVpWidth(0),
+         mVpHeight(0),
+         mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
 
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
@@ -133,12 +133,6 @@
     //mColorBlindnessCorrection = M;
 
 #ifdef USE_HWC2
-    // retrieve wide-color and hdr settings from configstore
-    using namespace android::hardware::configstore;
-    using namespace android::hardware::configstore::V1_0;
-
-    mPlatformHasWideColor =
-            getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
     if (mPlatformHasWideColor) {
         // Compute sRGB to DisplayP3 color transform
         // NOTE: For now, we are limiting wide-color support to
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 19cbb60..eaf94af 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -59,7 +59,7 @@
     virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
 
 public:
-    GLES20RenderEngine();
+    GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
 
 protected:
     virtual ~GLES20RenderEngine();
@@ -86,7 +86,6 @@
     android_dataspace mDataSpace = HAL_DATASPACE_V0_SRGB;
 
     // Indicate if wide-color mode is needed or not
-    bool mPlatformHasWideColor = false;
     bool mDisplayHasWideColor = false;
     bool mUseWideColor = false;
     uint64_t mWideColorFrameCount = 0;
@@ -98,6 +97,8 @@
             int alpha);
     virtual void setupDimLayerBlending(int alpha);
 #endif
+    bool mPlatformHasWideColor = false;
+
     virtual void setupLayerTexturing(const Texture& texture);
     virtual void setupLayerBlackedOut();
     virtual void setupFillWithColor(float r, float g, float b, float a);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index f8785db..ac2d8b2 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -47,7 +47,7 @@
     return false;
 }
 
-RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat) {
+RenderEngine* RenderEngine::create(EGLDisplay display, int hwcFormat, uint32_t featureFlags) {
     // EGL_ANDROIDX_no_config_context is an experimental extension with no
     // written specification. It will be replaced by something more formal.
     // SurfaceFlinger is using it to allow a single EGLContext to render to
@@ -135,7 +135,7 @@
         break;
     case GLES_VERSION_2_0:
     case GLES_VERSION_3_0:
-        engine = new GLES20RenderEngine();
+        engine = new GLES20RenderEngine(featureFlags);
         break;
     }
     engine->setEGLHandles(config, ctxt);
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 8b031bc..56f5827 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -59,7 +59,10 @@
     virtual ~RenderEngine() = 0;
 
 public:
-    static RenderEngine* create(EGLDisplay display, int hwcFormat);
+    enum FeatureFlag {
+        WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
+    };
+    static RenderEngine* create(EGLDisplay display, int hwcFormat, uint32_t featureFlags);
 
     static EGLConfig chooseEglConfig(EGLDisplay display, int format);
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 12afdf7..7392006 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -560,7 +560,8 @@
 
         // Get a RenderEngine for the given display / config (can't fail)
         mRenderEngine = RenderEngine::create(mEGLDisplay,
-                HAL_PIXEL_FORMAT_RGBA_8888);
+                HAL_PIXEL_FORMAT_RGBA_8888,
+                hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);
     }
 
     // Drop the state lock while we initialize the hardware composer. We drop
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index f6ee660..0b3a0d0 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -536,7 +536,8 @@
             *static_cast<HWComposer::EventHandler *>(this));
 
     // get a RenderEngine for the given display / config (can't fail)
-    mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
+    mRenderEngine = RenderEngine::create(mEGLDisplay,
+            mHwc->getVisualID(), 0);
 
     // retrieve the EGL context that was selected/created
     mEGLContext = mRenderEngine->getEGLContext();
diff --git a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
new file mode 100644
index 0000000..3728ef0
--- /dev/null
+++ b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
@@ -0,0 +1,24 @@
+# Copyright (C) 2017 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.
+
+#
+# Virtual touchpad for the VR virtual display
+device.internal = 1
+
+touch.deviceType = touchScreen
+
+# This displayID matches the unique ID of the virtual display created for VR.
+# This will indicate to input flinger than it should link this input device
+# with the virtual display.
+touch.displayId = virtual:android:277f1a09-b88d-4d1e-8716-796f114d080b