Merge "BufferItemConsumer: Add onBufferFreedListener"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 754ba4c..9006330 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -359,17 +359,20 @@
         }
 
         if (property_get_bool("dalvik.vm.usejitprofiles", false)) {
-            const std::string profile_path = create_data_user_profile_package_path(userId, pkgname);
+            const std::string profile_dir =
+                    create_primary_current_profile_package_dir_path(userId, pkgname);
             // read-write-execute only for the app user.
-            if (fs_prepare_dir_strict(profile_path.c_str(), 0700, uid, uid) != 0) {
-                return error("Failed to prepare " + profile_path);
+            if (fs_prepare_dir_strict(profile_dir.c_str(), 0700, uid, uid) != 0) {
+                return error("Failed to prepare " + profile_dir);
             }
-            std::string profile_file = create_primary_profile(profile_path);
+            const std::string profile_file = create_current_profile_path(userId, pkgname,
+                    /*is_secondary_dex*/false);
             // read-write only for the app user.
             if (fs_prepare_file_strict(profile_file.c_str(), 0600, uid, uid) != 0) {
-                return error("Failed to prepare " + profile_path);
+                return error("Failed to prepare " + profile_file);
             }
-            const std::string ref_profile_path = create_data_ref_profile_package_path(pkgname);
+            const std::string ref_profile_path =
+                    create_primary_reference_profile_package_dir_path(pkgname);
             // dex2oat/profman runs under the shared app gid and it needs to read/write reference
             // profiles.
             int shared_app_gid = multiuser_get_shared_gid(0, appId);
@@ -433,10 +436,10 @@
     std::lock_guard<std::recursive_mutex> lock(mLock);
 
     binder::Status res = ok();
-    if (!clear_reference_profile(packageName)) {
+    if (!clear_primary_reference_profile(packageName)) {
         res = error("Failed to clear reference profile for " + packageName);
     }
-    if (!clear_current_profiles(packageName)) {
+    if (!clear_primary_current_profiles(packageName)) {
         res = error("Failed to clear current profiles for " + packageName);
     }
     return res;
@@ -484,7 +487,7 @@
             }
         }
         if (!only_cache) {
-            if (!clear_current_profile(packageName, userId)) {
+            if (!clear_primary_current_profile(packageName, userId)) {
                 res = error("Failed to clear current profile for " + packageName);
             }
         }
@@ -494,13 +497,13 @@
 
 static int destroy_app_reference_profile(const std::string& pkgname) {
     return delete_dir_contents_and_dir(
-        create_data_ref_profile_package_path(pkgname),
+        create_primary_reference_profile_package_dir_path(pkgname),
         /*ignore_if_missing*/ true);
 }
 
 static int destroy_app_current_profiles(const std::string& pkgname, userid_t userid) {
     return delete_dir_contents_and_dir(
-        create_data_user_profile_package_path(userid, pkgname),
+        create_primary_current_profile_package_dir_path(userid, pkgname),
         /*ignore_if_missing*/ true);
 }
 
@@ -727,7 +730,7 @@
             if (delete_dir_contents_and_dir(path, true) != 0) {
                 res = error("Failed to delete " + path);
             }
-            path = create_data_user_profile_path(userId);
+            path = create_primary_cur_profile_dir_path(userId);
             if (delete_dir_contents_and_dir(path, true) != 0) {
                 res = error("Failed to delete " + path);
             }
@@ -1237,9 +1240,9 @@
             ATRACE_END();
 
             ATRACE_BEGIN("profiles");
-            auto userProfilePath = create_data_user_profile_package_path(userId, pkgname);
+            auto userProfilePath = create_primary_current_profile_package_dir_path(userId, pkgname);
             calculate_tree_size(userProfilePath, &stats.dataSize);
-            auto refProfilePath = create_data_ref_profile_package_path(pkgname);
+            auto refProfilePath = create_primary_reference_profile_package_dir_path(pkgname);
             calculate_tree_size(refProfilePath, &stats.codeSize);
             ATRACE_END();
 
@@ -1257,7 +1260,7 @@
             calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
                     sharedGid, -1);
         }
-        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize,
+        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
                 multiuser_get_uid(userId, appId), -1);
         ATRACE_END();
     }
@@ -1332,9 +1335,9 @@
         ATRACE_END();
 
         ATRACE_BEGIN("profile");
-        auto userProfilePath = create_data_user_profile_path(userId);
+        auto userProfilePath = create_primary_cur_profile_dir_path(userId);
         calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
-        auto refProfilePath = create_data_ref_profile_path();
+        auto refProfilePath = create_primary_ref_profile_dir_path();
         calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
         ATRACE_END();
 
@@ -1356,7 +1359,7 @@
         ATRACE_BEGIN("dalvik");
         calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
                 -1, -1, true);
-        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize,
+        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
                 -1, -1, true);
         ATRACE_END();
 
@@ -1389,9 +1392,9 @@
         ATRACE_END();
 
         ATRACE_BEGIN("profile");
-        auto userProfilePath = create_data_user_profile_path(userId);
+        auto userProfilePath = create_primary_cur_profile_dir_path(userId);
         calculate_tree_size(userProfilePath, &stats.dataSize);
-        auto refProfilePath = create_data_ref_profile_path();
+        auto refProfilePath = create_primary_ref_profile_dir_path();
         calculate_tree_size(refProfilePath, &stats.codeSize);
         ATRACE_END();
 
@@ -1406,7 +1409,7 @@
 
         ATRACE_BEGIN("dalvik");
         calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
-        calculate_tree_size(create_data_user_profile_path(userId), &stats.dataSize);
+        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize);
         ATRACE_END();
     }
 
@@ -1577,8 +1580,7 @@
     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
     std::lock_guard<std::recursive_mutex> lock(mLock);
 
-    const char* pkgname = packageName.c_str();
-    *_aidl_return = analyse_profiles(uid, pkgname);
+    *_aidl_return = analyze_primary_profiles(uid, packageName);
     return ok();
 }
 
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 0d5652f..5bb2ce7 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -50,6 +50,18 @@
 namespace android {
 namespace installd {
 
+// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below.
+struct FreeDelete {
+  // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
+  void operator()(const void* ptr) const {
+    free(const_cast<void*>(ptr));
+  }
+};
+
+// Alias for std::unique_ptr<> that uses the C function free() to delete objects.
+template <typename T>
+using UniqueCPtr = std::unique_ptr<T, FreeDelete>;
+
 static unique_fd invalid_unique_fd() {
     return unique_fd(-1);
 }
@@ -106,27 +118,40 @@
     return truncated;
 }
 
-bool clear_reference_profile(const std::string& pkgname) {
-    std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
-    std::string reference_profile = create_primary_profile(reference_profile_dir);
-    return clear_profile(reference_profile);
+// Clear the reference profile for the given location.
+// The location is the package name for primary apks or the dex path for secondary dex files.
+static bool clear_reference_profile(const std::string& location, bool is_secondary_dex) {
+    return clear_profile(create_reference_profile_path(location, is_secondary_dex));
 }
 
-bool clear_current_profile(const std::string& pkgname, userid_t user) {
-    std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
-    std::string profile = create_primary_profile(profile_dir);
-    return clear_profile(profile);
+// Clear the reference profile for the given location.
+// The location is the package name for primary apks or the dex path for secondary dex files.
+static bool clear_current_profile(const std::string& pkgname, userid_t user,
+        bool is_secondary_dex) {
+    return clear_profile(create_current_profile_path(user, pkgname, is_secondary_dex));
 }
 
-bool clear_current_profiles(const std::string& pkgname) {
+// Clear the reference profile for the primary apk of the given package.
+bool clear_primary_reference_profile(const std::string& pkgname) {
+    return clear_reference_profile(pkgname, /*is_secondary_dex*/false);
+}
+
+// Clear all current profile for the primary apk of the given package.
+bool clear_primary_current_profiles(const std::string& pkgname) {
     bool success = true;
+    // For secondary dex files, we don't really need the user but we use it for sanity checks.
     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
     for (auto user : users) {
-        success &= clear_current_profile(pkgname, user);
+        success &= clear_current_profile(pkgname, user, /*is_secondary_dex*/false);
     }
     return success;
 }
 
+// Clear the current profile for the primary apk of the given package and user.
+bool clear_primary_current_profile(const std::string& pkgname, userid_t user) {
+    return clear_current_profile(pkgname, user, /*is_secondary_dex*/false);
+}
+
 static int split_count(const char *str)
 {
   char *ctx;
@@ -472,72 +497,86 @@
     }
 }
 
-static unique_fd open_profile_dir(const std::string& profile_dir) {
-    unique_fd profile_dir_fd(TEMP_FAILURE_RETRY(open(profile_dir.c_str(),
-            O_PATH | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW)));
-    if (profile_dir_fd.get() < 0) {
-        // In a multi-user environment, these directories can be created at
-        // different points and it's possible we'll attempt to open a profile
-        // dir before it exists.
-        if (errno != ENOENT) {
-            PLOG(ERROR) << "Failed to open profile_dir: " << profile_dir;
-        }
-    }
-    return profile_dir_fd;
-}
-
-static unique_fd open_primary_profile_file_from_dir(const std::string& profile_dir,
-        mode_t open_mode) {
-    unique_fd profile_dir_fd  = open_profile_dir(profile_dir);
-    if (profile_dir_fd.get() < 0) {
-        return invalid_unique_fd();
-    }
-
-    std::string profile_file = create_primary_profile(profile_dir);
-    unique_fd profile_fd(TEMP_FAILURE_RETRY(open(profile_file.c_str(),
-            open_mode | O_NOFOLLOW, 0600)));
-    if (profile_fd == -1) {
-        // It's not an error if the profile file does not exist.
-        if (errno != ENOENT) {
-            PLOG(ERROR) << "Failed to open profile : " << profile_file;
-        }
-    }
-    return profile_fd;
-}
-
-static unique_fd open_primary_profile_file(userid_t user, const std::string& pkgname) {
-    std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
-    return open_primary_profile_file_from_dir(profile_dir, O_RDONLY);
-}
-
-static unique_fd open_reference_profile(uid_t uid, const std::string& pkgname, bool read_write) {
-    std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
-    int flags = read_write ? O_RDWR | O_CREAT : O_RDONLY;
-    unique_fd fd = open_primary_profile_file_from_dir(reference_profile_dir, flags);
+static bool create_profile(int uid, const std::string& profile) {
+    unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), O_CREAT | O_NOFOLLOW, 0600)));
     if (fd.get() < 0) {
-        return invalid_unique_fd();
+        if (errno == EEXIST) {
+            return true;
+        } else {
+            PLOG(ERROR) << "Failed to create profile " << profile;
+            return false;
+        }
     }
+    // Profiles should belong to the app; make sure of that by giving ownership to
+    // the app uid. If we cannot do that, there's no point in returning the fd
+    // since dex2oat/profman will fail with SElinux denials.
+    if (fchown(fd.get(), uid, uid) < 0) {
+        PLOG(ERROR) << "Could not chwon profile " << profile;
+        return false;
+    }
+    return true;
+}
+
+static unique_fd open_profile(int uid, const std::string& profile, bool read_write) {
+    // Check if we need to open the profile for a read-write operation. If so, we
+    // might need to create the profile since the file might not be there. Reference
+    // profiles are created on the fly so they might not exist beforehand.
     if (read_write) {
-        // Fix the owner.
-        if (fchown(fd.get(), uid, uid) < 0) {
+        if (!create_profile(uid, profile)) {
             return invalid_unique_fd();
         }
     }
+    int flags = read_write ? O_RDWR : O_RDONLY;
+    // Do not follow symlinks when opening a profile:
+    //   - primary profiles should not contain symlinks in their paths
+    //   - secondary dex paths should have been already resolved and validated
+    flags |= O_NOFOLLOW;
+
+    unique_fd fd(TEMP_FAILURE_RETRY(open(profile.c_str(), flags)));
+    if (fd.get() < 0) {
+        if (errno != ENOENT) {
+            // Profiles might be missing for various reasons. For example, in a
+            // multi-user environment, the profile directory for one user can be created
+            // after we start a merge. In this case the current profile for that user
+            // will not be found.
+            // Also, the secondary dex profiles might be deleted by the app at any time,
+            // so we can't we need to prepare if they are missing.
+            PLOG(ERROR) << "Failed to open profile " << profile;
+        }
+        return invalid_unique_fd();
+    }
+
     return fd;
 }
 
-static void open_profile_files(uid_t uid, const std::string& pkgname,
+static unique_fd open_current_profile(uid_t uid, userid_t user, const std::string& location,
+        bool is_secondary_dex) {
+    std::string profile = create_current_profile_path(user, location, is_secondary_dex);
+    return open_profile(uid, profile, /*read_write*/false);
+}
+
+static unique_fd open_reference_profile(uid_t uid, const std::string& location, bool read_write,
+        bool is_secondary_dex) {
+    std::string profile = create_reference_profile_path(location, is_secondary_dex);
+    return open_profile(uid, profile, read_write);
+}
+
+static void open_profile_files(uid_t uid, const std::string& location, bool is_secondary_dex,
             /*out*/ std::vector<unique_fd>* profiles_fd, /*out*/ unique_fd* reference_profile_fd) {
     // Open the reference profile in read-write mode as profman might need to save the merge.
-    *reference_profile_fd = open_reference_profile(uid, pkgname, /*read_write*/ true);
-    if (reference_profile_fd->get() < 0) {
-        // We can't access the reference profile file.
-        return;
-    }
+    *reference_profile_fd = open_reference_profile(uid, location, /*read_write*/ true,
+            is_secondary_dex);
 
-    std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
+    // For secondary dex files, we don't really need the user but we use it for sanity checks.
+    // Note: the user owning the dex file should be the current user.
+    std::vector<userid_t> users;
+    if (is_secondary_dex){
+        users.push_back(multiuser_get_user_id(uid));
+    } else {
+        users = get_known_users(/*volume_uuid*/ nullptr);
+    }
     for (auto user : users) {
-        unique_fd profile_fd = open_primary_profile_file(user, pkgname);
+        unique_fd profile_fd = open_current_profile(uid, user, location, is_secondary_dex);
         // Add to the lists only if both fds are valid.
         if (profile_fd.get() >= 0) {
             profiles_fd->push_back(std::move(profile_fd));
@@ -603,14 +642,15 @@
 }
 
 // Decides if profile guided compilation is needed or not based on existing profiles.
-// Returns true if there is enough information in the current profiles that worth
-// a re-compilation of the package.
+// The location is the package name for primary apks or the dex path for secondary dex files.
+// Returns true if there is enough information in the current profiles that makes it
+// worth to recompile the given location.
 // If the return value is true all the current profiles would have been merged into
 // the reference profiles accessible with open_reference_profile().
-bool analyse_profiles(uid_t uid, const std::string& pkgname) {
+static bool analyze_profiles(uid_t uid, const std::string& location, bool is_secondary_dex) {
     std::vector<unique_fd> profiles_fd;
     unique_fd reference_profile_fd;
-    open_profile_files(uid, pkgname, &profiles_fd, &reference_profile_fd);
+    open_profile_files(uid, location, is_secondary_dex, &profiles_fd, &reference_profile_fd);
     if (profiles_fd.empty() || (reference_profile_fd.get() < 0)) {
         // Skip profile guided compilation because no profiles were found.
         // Or if the reference profile info couldn't be opened.
@@ -630,7 +670,7 @@
     bool should_clear_current_profiles = false;
     bool should_clear_reference_profile = false;
     if (!WIFEXITED(return_code)) {
-        LOG(WARNING) << "profman failed for package " << pkgname << ": " << return_code;
+        LOG(WARNING) << "profman failed for location " << location << ": " << return_code;
     } else {
         return_code = WEXITSTATUS(return_code);
         switch (return_code) {
@@ -645,7 +685,7 @@
                 should_clear_reference_profile = false;
                 break;
             case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES:
-                LOG(WARNING) << "Bad profiles for package " << pkgname;
+                LOG(WARNING) << "Bad profiles for location " << location;
                 need_to_compile = false;
                 should_clear_current_profiles = true;
                 should_clear_reference_profile = true;
@@ -653,15 +693,15 @@
             case PROFMAN_BIN_RETURN_CODE_ERROR_IO:  // fall-through
             case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING:
                 // Temporary IO problem (e.g. locking). Ignore but log a warning.
-                LOG(WARNING) << "IO error while reading profiles for package " << pkgname;
+                LOG(WARNING) << "IO error while reading profiles for location " << location;
                 need_to_compile = false;
                 should_clear_current_profiles = false;
                 should_clear_reference_profile = false;
                 break;
            default:
                 // Unknown return code or error. Unlink profiles.
-                LOG(WARNING) << "Unknown error code while processing profiles for package " << pkgname
-                        << ": " << return_code;
+                LOG(WARNING) << "Unknown error code while processing profiles for location "
+                        << location << ": " << return_code;
                 need_to_compile = false;
                 should_clear_current_profiles = true;
                 should_clear_reference_profile = true;
@@ -670,14 +710,29 @@
     }
 
     if (should_clear_current_profiles) {
-        clear_current_profiles(pkgname);
+        if (is_secondary_dex) {
+            // For secondary dex files, the owning user is the current user.
+            clear_current_profile(location, multiuser_get_user_id(uid), is_secondary_dex);
+        } else  {
+            clear_primary_current_profiles(location);
+        }
     }
     if (should_clear_reference_profile) {
-        clear_reference_profile(pkgname);
+        clear_reference_profile(location, is_secondary_dex);
     }
     return need_to_compile;
 }
 
+// Decides if profile guided compilation is needed or not based on existing profiles.
+// The analysis is done for the primary apks of the given package.
+// Returns true if there is enough information in the current profiles that makes it
+// worth to recompile the package.
+// If the return value is true all the current profiles would have been merged into
+// the reference profiles accessible with open_reference_profile().
+bool analyze_primary_profiles(uid_t uid, const std::string& pkgname) {
+    return analyze_profiles(uid, pkgname, /*is_secondary_dex*/false);
+}
+
 static void run_profman_dump(const std::vector<unique_fd>& profile_fds,
                              const unique_fd& reference_profile_fd,
                              const std::vector<std::string>& dex_locations,
@@ -729,7 +784,8 @@
     unique_fd reference_profile_fd;
     std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname.c_str());
 
-    open_profile_files(uid, pkgname, &profile_fds, &reference_profile_fd);
+    open_profile_files(uid, pkgname, /*is_secondary_dex*/false,
+            &profile_fds, &reference_profile_fd);
 
     const bool has_reference_profile = (reference_profile_fd.get() != -1);
     const bool has_profiles = !profile_fds.empty();
@@ -739,7 +795,8 @@
         return false;
     }
 
-    unique_fd output_fd(open(out_file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644));
+    unique_fd output_fd(open(out_file_name.c_str(),
+            O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644));
     if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
         ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
         return false;
@@ -1061,23 +1118,22 @@
 
 // Opens the reference profiles if needed.
 // Note that the reference profile might not exist so it's OK if the fd will be -1.
-Dex2oatFileWrapper maybe_open_reference_profile(const char* pkgname, bool profile_guided,
-        bool is_public, int uid, bool is_secondary_dex) {
+Dex2oatFileWrapper maybe_open_reference_profile(const std::string& pkgname,
+        const std::string& dex_path, bool profile_guided, bool is_public, int uid,
+        bool is_secondary_dex) {
     // Public apps should not be compiled with profile information ever. Same goes for the special
     // package '*' used for the system server.
-    // TODO(calin): add support for writing profiles for secondary dex files
-    if (profile_guided && !is_secondary_dex && !is_public && (pkgname[0] != '*')) {
-        // Open reference profile in read only mode as dex2oat does not get write permissions.
-        const std::string pkgname_str(pkgname);
-        unique_fd profile_fd = open_reference_profile(uid, pkgname, /*read_write*/ false);
-        return Dex2oatFileWrapper(
-                profile_fd.release(),
-                [pkgname_str]() {
-                    clear_reference_profile(pkgname_str.c_str());
-                });
-    } else {
+    if (!profile_guided || is_public || (pkgname[0] == '*')) {
         return Dex2oatFileWrapper();
     }
+
+    // Open reference profile in read only mode as dex2oat does not get write permissions.
+    const std::string location = is_secondary_dex ? dex_path : pkgname;
+    unique_fd ufd = open_reference_profile(uid, location, /*read_write*/false, is_secondary_dex);
+    const auto& cleanup = [location, is_secondary_dex]() {
+        clear_reference_profile(location.c_str(), is_secondary_dex);
+    };
+    return Dex2oatFileWrapper(ufd.release(), cleanup);
 }
 
 // Opens the vdex files and assigns the input fd to in_vdex_wrapper_fd and the output fd to
@@ -1197,8 +1253,11 @@
 }
 
 // Runs (execv) dexoptanalyzer on the given arguments.
-static void exec_dexoptanalyzer(const char* dex_file, const char* instruction_set,
-        const char* compiler_filter) {
+// The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter.
+// If this is for a profile guided compilation, profile_was_updated will tell whether or not
+// the profile has changed.
+static void exec_dexoptanalyzer(const std::string& dex_file, const char* instruction_set,
+        const char* compiler_filter, bool profile_was_updated) {
     static const char* DEXOPTANALYZER_BIN = "/system/bin/dexoptanalyzer";
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
@@ -1211,18 +1270,22 @@
     char dex_file_arg[strlen("--dex-file=") + PKG_PATH_MAX];
     char isa_arg[strlen("--isa=") + MAX_INSTRUCTION_SET_LEN];
     char compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
+    const char* assume_profile_changed = "--assume-profile-changed";
 
-    sprintf(dex_file_arg, "--dex-file=%s", dex_file);
+    sprintf(dex_file_arg, "--dex-file=%s", dex_file.c_str());
     sprintf(isa_arg, "--isa=%s", instruction_set);
     sprintf(compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
 
     // program name, dex file, isa, filter, the final NULL
-    const char* argv[5];
+    const char* argv[5 + (profile_was_updated ? 1 : 0)];
     int i = 0;
     argv[i++] = DEXOPTANALYZER_BIN;
     argv[i++] = dex_file_arg;
     argv[i++] = isa_arg;
     argv[i++] = compiler_filter_arg;
+    if (profile_was_updated) {
+        argv[i++] = assume_profile_changed;
+    }
     argv[i] = NULL;
 
     execv(DEXOPTANALYZER_BIN, (char * const *)argv);
@@ -1230,15 +1293,14 @@
 }
 
 // Prepares the oat dir for the secondary dex files.
-static bool prepare_secondary_dex_oat_dir(const char* dex_path, int uid,
-         const char* instruction_set, std::string* oat_dir_out) {
-    std::string apk_path_str(dex_path);
-    unsigned long dirIndex = apk_path_str.rfind('/');
+static bool prepare_secondary_dex_oat_dir(const std::string& dex_path, int uid,
+        const char* instruction_set, std::string* oat_dir_out) {
+    unsigned long dirIndex = dex_path.rfind('/');
     if (dirIndex == std::string::npos) {
         LOG(ERROR ) << "Unexpected dir structure for secondary dex " << dex_path;
         return false;
     }
-    std::string apk_dir = apk_path_str.substr(0, dirIndex);
+    std::string dex_dir = dex_path.substr(0, dirIndex);
 
     // Assign the gid to the cache gid so that the oat file storage
     // is counted towards the app cache.
@@ -1250,13 +1312,13 @@
     }
 
     // Create oat file output directory.
-    if (prepare_app_cache_dir(apk_dir, "oat", 02711, uid, cache_gid) != 0) {
+    if (prepare_app_cache_dir(dex_dir, "oat", 02711, uid, cache_gid) != 0) {
         LOG(ERROR) << "Could not prepare oat dir for secondary dex: " << dex_path;
         return false;
     }
 
     char oat_dir[PKG_PATH_MAX];
-    snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", apk_dir.c_str());
+    snprintf(oat_dir, PKG_PATH_MAX, "%s/oat", dex_dir.c_str());
     oat_dir_out->assign(oat_dir);
 
     // Create oat/isa output directory.
@@ -1273,7 +1335,7 @@
 // Verifies the result of dexoptanalyzer executed for the apk_path.
 // If the result is valid returns true and sets dexopt_needed_out to a valid value.
 // Returns false for errors or unexpected result values.
-static bool process_dexoptanalyzer_result(const char* dex_path, int result,
+static bool process_dexoptanalyzer_result(const std::string& dex_path, int result,
             int* dexopt_needed_out) {
     // The result values are defined in dexoptanalyzer.
     switch (result) {
@@ -1305,10 +1367,11 @@
 // be compiled. Returns false for errors (logged) or true if the secondary dex path was process
 // successfully.
 // When returning true, dexopt_needed_out is assigned a valid OatFileAsssitant::DexOptNeeded
-// code and aot_dir_out is assigned the oat dir path where the oat file should be stored.
-static bool process_secondary_dex_dexopt(const char* dex_path, const char* pkgname,
+// code and oat_dir_out is assigned the oat dir path where the oat file should be stored.
+static bool process_secondary_dex_dexopt(const char* original_dex_path, const char* pkgname,
         int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
-        const char* compiler_filter, int* dexopt_needed_out, std::string* aot_dir_out) {
+        const char* compiler_filter, int* dexopt_needed_out, std::string* oat_dir_out,
+        std::string* dex_path_out) {
     int storage_flag;
 
     if ((dexopt_flags & DEXOPT_STORAGE_CE) != 0) {
@@ -1324,17 +1387,31 @@
         return false;
     }
 
+    {
+        // As opposed to the primary apk, secondary dex files might contain symlinks.
+        // Resolve the path before passing it to the validate method to
+        // make sure the verification is done on the real location.
+        UniqueCPtr<char> dex_real_path_cstr(realpath(original_dex_path, nullptr));
+        if (dex_real_path_cstr == nullptr) {
+            PLOG(ERROR) << "Could not get the real path of the secondary dex file "
+                    << original_dex_path;
+            return false;
+        } else {
+            dex_path_out->assign(dex_real_path_cstr.get());
+        }
+    }
+    const std::string& dex_path = *dex_path_out;
     if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) {
         LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
         return false;
     }
 
     // Check if the path exist. If not, there's nothing to do.
-    if (access(dex_path, F_OK) != 0) {
+    if (access(dex_path.c_str(), F_OK) != 0) {
         if (errno == ENOENT) {
             // Secondary dex files might be deleted any time by the app.
             // Nothing to do if that's the case
-            ALOGV("Secondary dex does not exist %s", dex_path);
+            ALOGV("Secondary dex does not exist %s", dex_path.c_str());
             return NO_DEXOPT_NEEDED;
         } else {
             PLOG(ERROR) << "Could not access secondary dex " << dex_path;
@@ -1342,16 +1419,19 @@
     }
 
     // Prepare the oat directories.
-    if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, aot_dir_out)) {
+    if (!prepare_secondary_dex_oat_dir(dex_path, uid, instruction_set, oat_dir_out)) {
         return false;
     }
 
+    // Analyze profiles.
+    bool profile_was_updated = analyze_profiles(uid, dex_path, /*is_secondary_dex*/true);
+
     pid_t pid = fork();
     if (pid == 0) {
         // child -- drop privileges before continuing.
         drop_capabilities(uid);
         // Run dexoptanalyzer to get dexopt_needed code.
-        exec_dexoptanalyzer(dex_path, instruction_set, compiler_filter);
+        exec_dexoptanalyzer(dex_path, instruction_set, compiler_filter, profile_was_updated);
         exit(DEXOPTANALYZER_BIN_EXEC_ERROR);
     }
 
@@ -1394,10 +1474,12 @@
 
     // Check if we're dealing with a secondary dex file and if we need to compile it.
     std::string oat_dir_str;
+    std::string dex_real_path;
     if (is_secondary_dex) {
         if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
-                instruction_set, compiler_filter, &dexopt_needed, &oat_dir_str)) {
+                instruction_set, compiler_filter, &dexopt_needed, &oat_dir_str, &dex_real_path)) {
             oat_dir = oat_dir_str.c_str();
+            dex_path = dex_real_path.c_str();
             if (dexopt_needed == NO_DEXOPT_NEEDED) {
                 return 0;  // Nothing to do, report success.
             }
@@ -1442,8 +1524,8 @@
             maybe_open_app_image(out_oat_path, profile_guided, is_public, uid, is_secondary_dex);
 
     // Open the reference profile if needed.
-    Dex2oatFileWrapper reference_profile_fd =
-        maybe_open_reference_profile(pkgname, profile_guided, is_public, uid, is_secondary_dex);
+    Dex2oatFileWrapper reference_profile_fd = maybe_open_reference_profile(
+            pkgname, dex_path, profile_guided, is_public, uid, is_secondary_dex);
 
     ALOGV("DexInv: --- BEGIN '%s' ---\n", dex_path);
 
@@ -1541,7 +1623,7 @@
     snprintf(out_oat_isa_dir, PKG_PATH_MAX, "%s/%s", out_oat_dir, isa.c_str());
 
     if (!create_oat_out_path(dex_path.c_str(), isa.c_str(), out_oat_dir,
-            /*is_secondary_dex*/ true, out_oat_path)) {
+            /*is_secondary_dex*/true, out_oat_path)) {
         LOG(ERROR) << "Could not create oat path for secondary dex " << dex_path;
         return false;
     }
@@ -1738,7 +1820,7 @@
     // Delete the oat/odex file.
     char out_path[PKG_PATH_MAX];
     if (!create_oat_out_path(apk_path, instruction_set, oat_dir,
-            /*is_secondary_dex*/ false, out_path)) {
+            /*is_secondary_dex*/false, out_path)) {
         return false;
     }
 
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index df6d176..dbf3fae 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -32,13 +32,23 @@
 static constexpr int DEX2OAT_FOR_RELOCATION      = 4;
 static constexpr int PATCHOAT_FOR_RELOCATION     = 5;
 
-bool clear_reference_profile(const std::string& pkgname);
-bool clear_current_profile(const std::string& pkgname, userid_t user);
-bool clear_current_profiles(const std::string& pkgname);
+// Clear the reference profile for the primary apk of the given package.
+bool clear_primary_reference_profile(const std::string& pkgname);
+// Clear the current profile for the primary apk of the given package and user.
+bool clear_primary_current_profile(const std::string& pkgname, userid_t user);
+// Clear all current profile for the primary apk of the given package.
+bool clear_primary_current_profiles(const std::string& pkgname);
 
 bool move_ab(const char* apk_path, const char* instruction_set, const char* output_path);
 
-bool analyse_profiles(uid_t uid, const std::string& pkgname);
+// Decide if profile guided compilation is needed or not based on existing profiles.
+// The analysis is done for the primary apks (base + splits) of the given package.
+// Returns true if there is enough information in the current profiles that makes it
+// worth to recompile the package.
+// If the return value is true all the current profiles would have been merged into
+// the reference profiles accessible with open_reference_profile().
+bool analyze_primary_profiles(uid_t uid, const std::string& pkgname);
+
 bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths);
 
 bool delete_odex(const char* apk_path, const char* instruction_set, const char* output_path);
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 850d257..49605be 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -525,29 +525,50 @@
 }
 
 TEST_F(UtilsTest, CreateDataUserProfilePath) {
-    EXPECT_EQ("/data/misc/profiles/cur/0", create_data_user_profile_path(0));
-    EXPECT_EQ("/data/misc/profiles/cur/1", create_data_user_profile_path(1));
+    EXPECT_EQ("/data/misc/profiles/cur/0", create_primary_cur_profile_dir_path(0));
+    EXPECT_EQ("/data/misc/profiles/cur/1", create_primary_cur_profile_dir_path(1));
 }
 
 TEST_F(UtilsTest, CreateDataUserProfilePackagePath) {
     EXPECT_EQ("/data/misc/profiles/cur/0/com.example",
-            create_data_user_profile_package_path(0, "com.example"));
+            create_primary_current_profile_package_dir_path(0, "com.example"));
     EXPECT_EQ("/data/misc/profiles/cur/1/com.example",
-            create_data_user_profile_package_path(1, "com.example"));
+            create_primary_current_profile_package_dir_path(1, "com.example"));
 }
 
 TEST_F(UtilsTest, CreateDataRefProfilePath) {
-    EXPECT_EQ("/data/misc/profiles/ref", create_data_ref_profile_path());
+    EXPECT_EQ("/data/misc/profiles/ref", create_primary_ref_profile_dir_path());
 }
 
 TEST_F(UtilsTest, CreateDataRefProfilePackagePath) {
     EXPECT_EQ("/data/misc/profiles/ref/com.example",
-        create_data_ref_profile_package_path("com.example"));
+        create_primary_reference_profile_package_dir_path("com.example"));
 }
 
-TEST_F(UtilsTest, CreatePrimaryProfile) {
-    EXPECT_EQ("/data/misc/profiles/ref/com.example/primary.prof",
-        create_primary_profile("/data/misc/profiles/ref/com.example"));
+TEST_F(UtilsTest, CreatePrimaryCurrentProfile) {
+    std::string expected =
+        create_primary_current_profile_package_dir_path(1, "com.example") + "/primary.prof";
+    EXPECT_EQ(expected,
+            create_current_profile_path(/*user*/0, "com.example", /*is_secondary*/false));
+}
+
+TEST_F(UtilsTest, CreatePrimaryReferenceProfile) {
+    std::string expected =
+        create_primary_reference_profile_package_dir_path("com.example") + "/primary.prof";
+    EXPECT_EQ(expected,
+            create_reference_profile_path("com.example", /*is_secondary*/false));
+}
+
+TEST_F(UtilsTest, CreateSecondaryCurrentProfile) {
+    EXPECT_EQ("/data/user/0/com.example/secondary.dex.prof",
+            create_current_profile_path(/*user*/0,
+                    "/data/user/0/com.example/secondary.dex", /*is_secondary*/true));
+}
+
+TEST_F(UtilsTest, CreateSecondaryReferenceProfile) {
+    EXPECT_EQ("/data/user/0/com.example/oat/secondary.dex.prof",
+            create_reference_profile_path(
+                    "/data/user/0/com.example/secondary.dex", /*is_secondary*/true));
 }
 
 }  // namespace installd
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 5a08c32..97298e5 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -217,20 +217,22 @@
     return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid);
 }
 
-std::string create_data_user_profile_path(userid_t userid) {
+std::string create_primary_cur_profile_dir_path(userid_t userid) {
     return StringPrintf("%s/cur/%u", android_profiles_dir.path, userid);
 }
 
-std::string create_data_user_profile_package_path(userid_t user, const std::string& package_name) {
+std::string create_primary_current_profile_package_dir_path(userid_t user,
+        const std::string& package_name) {
     check_package_name(package_name.c_str());
-    return StringPrintf("%s/%s",create_data_user_profile_path(user).c_str(), package_name.c_str());
+    return StringPrintf("%s/%s",
+            create_primary_cur_profile_dir_path(user).c_str(), package_name.c_str());
 }
 
-std::string create_data_ref_profile_path() {
+std::string create_primary_ref_profile_dir_path() {
     return StringPrintf("%s/ref", android_profiles_dir.path);
 }
 
-std::string create_data_ref_profile_package_path(const std::string& package_name) {
+std::string create_primary_reference_profile_package_dir_path(const std::string& package_name) {
     check_package_name(package_name.c_str());
     return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name.c_str());
 }
@@ -239,11 +241,38 @@
     return "/data/dalvik-cache";
 }
 
-// Keep profile paths in sync with ActivityThread.
-constexpr const char* PRIMARY_PROFILE_NAME = "primary.prof";
+// Keep profile paths in sync with ActivityThread and LoadedApk.
+const std::string PROFILE_EXT = ".prof";
+const std::string PRIMARY_PROFILE_NAME = "primary" + PROFILE_EXT;
 
-std::string create_primary_profile(const std::string& profile_dir) {
-    return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME);
+std::string create_current_profile_path(userid_t user, const std::string& location,
+        bool is_secondary_dex) {
+    if (is_secondary_dex) {
+        // Secondary dex profiles are stored next to the dex files using .prof extension.
+        return StringPrintf("%s%s", location.c_str(), PROFILE_EXT.c_str());
+    } else {
+        // Profiles for primary apks are under /data/misc/profiles/cur.
+        std::string profile_dir = create_primary_current_profile_package_dir_path(user, location);
+        return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME.c_str());
+    }
+}
+
+std::string create_reference_profile_path(const std::string& location, bool is_secondary_dex) {
+    if (is_secondary_dex) {
+        // Secondary dex reference profiles are stored next to the dex files under the oat folder.
+        size_t dirIndex = location.rfind('/');
+        CHECK(dirIndex != std::string::npos)
+                << "Unexpected dir structure for secondary dex " << location;
+
+        std::string dex_dir = location.substr(0, dirIndex);
+        std::string dex_name = location.substr(dirIndex +1);
+        return StringPrintf("%s/oat/%s%s",
+                dex_dir.c_str(), dex_name.c_str(), PROFILE_EXT.c_str());
+    } else {
+        // Reference profiles for primary apks are stored in /data/misc/profile/ref.
+        std::string profile_dir = create_primary_reference_profile_package_dir_path(location);
+        return StringPrintf("%s/%s", profile_dir.c_str(), PRIMARY_PROFILE_NAME.c_str());
+    }
 }
 
 std::vector<userid_t> get_known_users(const char* volume_uuid) {
@@ -1182,13 +1211,15 @@
     return -1;
 }
 
-bool validate_secondary_dex_path(const char* pkgname, const char* path,
+bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
         const char* volume_uuid, int uid, int storage_flag) {
     CHECK(storage_flag == FLAG_STORAGE_CE || storage_flag == FLAG_STORAGE_DE);
 
     std::string app_private_dir = storage_flag == FLAG_STORAGE_CE
-        ? create_data_user_ce_package_path(volume_uuid, multiuser_get_user_id(uid), pkgname)
-        : create_data_user_de_package_path(volume_uuid, multiuser_get_user_id(uid), pkgname);
+        ? create_data_user_ce_package_path(
+                volume_uuid, multiuser_get_user_id(uid), pkgname.c_str())
+        : create_data_user_de_package_path(
+                volume_uuid, multiuser_get_user_id(uid), pkgname.c_str());
     dir_rec_t dir;
     if (get_path_from_string(&dir, app_private_dir.c_str()) != 0) {
         LOG(WARNING) << "Could not get dir rec for " << app_private_dir;
@@ -1198,7 +1229,7 @@
     // Pick at most 10 subdirectories when validating (arbitrary value).
     // If the secondary dex file is >10 directory nested then validation will
     // fail and the file will not be compiled.
-    return validate_path(&dir, path, /*max_subdirs*/ 10) == 0;
+    return validate_path(&dir, dex_path.c_str(), /*max_subdirs*/ 10) == 0;
 }
 
 /**
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index 1c36a54..abe6830 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -96,15 +96,19 @@
 
 std::string create_data_misc_legacy_path(userid_t userid);
 
-std::string create_data_user_profile_path(userid_t userid);
-std::string create_data_user_profile_package_path(userid_t user, const std::string& package_name);
-
-std::string create_data_ref_profile_path();
-std::string create_data_ref_profile_package_path(const std::string& package_name);
-
 std::string create_data_dalvik_cache_path();
 
-std::string create_primary_profile(const std::string& profile_dir);
+std::string create_primary_cur_profile_dir_path(userid_t userid);
+std::string create_primary_current_profile_package_dir_path(
+        userid_t user, const std::string& package_name);
+
+std::string create_primary_ref_profile_dir_path();
+std::string create_primary_reference_profile_package_dir_path(const std::string& package_name);
+
+std::string create_current_profile_path(
+        userid_t user, const std::string& package_name, bool is_secondary_dex);
+std::string create_reference_profile_path(
+        const std::string& package_name, bool is_secondary_dex);
 
 std::vector<userid_t> get_known_users(const char* volume_uuid);
 
@@ -151,7 +155,7 @@
 void finish_cache_collection(cache_t* cache);
 
 int validate_system_app_path(const char* path);
-bool validate_secondary_dex_path(const char* pkgname, const char* path,
+bool validate_secondary_dex_path(const std::string& pkgname, const std::string& dex_path,
         const char* volume_uuid, int uid, int storage_flag);
 
 int get_path_from_env(dir_rec_t* rec, const char* var);
diff --git a/cmds/vr/pose/Android.mk b/cmds/vr/pose/Android.mk
index 1657551..8be3214 100644
--- a/cmds/vr/pose/Android.mk
+++ b/cmds/vr/pose/Android.mk
@@ -19,7 +19,7 @@
 
 staticLibraries := \
   libdvrcommon \
-  libsensor \
+  libvrsensor \
   libpdx_default_transport \
 
 sharedLibraries := \
@@ -33,9 +33,3 @@
 LOCAL_MODULE := pose
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_EXECUTABLE)
-
-ifeq ($(TARGET_BUILD_VARIANT),eng)
-ALL_DEFAULT_INSTALLED_MODULES += pose
-all_modules: pose
-endif
-
diff --git a/cmds/vr/vrscreencap/Android.mk b/cmds/vr/vrscreencap/Android.mk
index 2fa9155..bd0b224 100644
--- a/cmds/vr/vrscreencap/Android.mk
+++ b/cmds/vr/vrscreencap/Android.mk
@@ -21,8 +21,3 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_EXECUTABLE)
-
-ifeq ($(TARGET_BUILD_VARIANT),eng)
-ALL_DEFAULT_INSTALLED_MODULES += vrscreencap
-all_modules: vrscreencap
-endif
diff --git a/data/etc/android.hardware.vr.headtracking-0.mxl b/data/etc/android.hardware.vr.headtracking-0.mxl
new file mode 100644
index 0000000..1b53995
--- /dev/null
+++ b/data/etc/android.hardware.vr.headtracking-0.mxl
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- This is the feature indicating that the device supports VR headtracking
+     level 0 -->
+<permissions>
+    <feature name="android.hardware.vr.headtracking" version="0" />
+</permissions>
diff --git a/data/etc/android.hardware.vr.headtracking-1.mxl b/data/etc/android.hardware.vr.headtracking-1.mxl
new file mode 100644
index 0000000..2ad8ccc
--- /dev/null
+++ b/data/etc/android.hardware.vr.headtracking-1.mxl
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- This is the feature indicating that the device supports VR headtracking
+     level 1 -->
+<permissions>
+    <feature name="android.hardware.vr.headtracking" version="1" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 467e0fd..ed3db5c 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -56,6 +56,9 @@
     <!-- Devices with all optimizations required to be a "VR Ready" device that
          pass all CTS tests for this feature must include feature
          android.hardware.vr.high_performance -->
+    <!-- Devices that support VR headtracking features and pass all CDD
+         requirements may include
+         android.hardware.vr.headtracking -->
 
     <!-- devices with GPS must include android.hardware.location.gps.xml -->
     <!-- devices with an autofocus camera and/or flash must include either
diff --git a/include/gui/FrameTimestamps.h b/include/gui/FrameTimestamps.h
index bda3c5c..cbb4491 100644
--- a/include/gui/FrameTimestamps.h
+++ b/include/gui/FrameTimestamps.h
@@ -105,7 +105,7 @@
 struct CompositorTiming {
     nsecs_t deadline{0};
     nsecs_t interval{16666667};
-    nsecs_t presentLatency{0};
+    nsecs_t presentLatency{16666667};
 };
 
 // A short history of frames that are synchronized between the consumer and
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index da6f13d..58227e6 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -52,6 +52,8 @@
         mComposerClient = new SurfaceComposerClient;
         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
 
+        // TODO(brianderson): The following sometimes fails and is a source of
+        //   test flakiness.
         mSurfaceControl = mComposerClient->createSurface(
                 String8("Test Surface"), 32, 32, PIXEL_FORMAT_RGBA_8888, 0);
 
@@ -526,7 +528,7 @@
 };
 
 
-class GetFrameTimestampsTest : public SurfaceTest {
+class GetFrameTimestampsTest : public ::testing::Test {
 protected:
     struct FenceAndFenceTime {
         explicit FenceAndFenceTime(FenceToFenceTimeMap& fenceMap)
@@ -616,11 +618,9 @@
         RefreshEvents mRefreshes[3];
     };
 
-    GetFrameTimestampsTest() : SurfaceTest() {}
+    GetFrameTimestampsTest() {}
 
     virtual void SetUp() {
-        SurfaceTest::SetUp();
-
         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
         mFakeConsumer = new FakeConsumer;
         mCfeh = &mFakeConsumer->mFrameEventHistory;
diff --git a/libs/hwc2on1adapter/HWC2On1Adapter.cpp b/libs/hwc2on1adapter/HWC2On1Adapter.cpp
index 5ad05c7..03297ca 100644
--- a/libs/hwc2on1adapter/HWC2On1Adapter.cpp
+++ b/libs/hwc2on1adapter/HWC2On1Adapter.cpp
@@ -245,6 +245,11 @@
             return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
                     displayHook<decltype(&Display::validate),
                     &Display::validate, uint32_t*, uint32_t*>);
+        case FunctionDescriptor::GetClientTargetSupport:
+            return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
+                    displayHook<decltype(&Display::getClientTargetSupport),
+                    &Display::getClientTargetSupport, uint32_t, uint32_t,
+                                                      int32_t, int32_t>);
 
         // Layer functions
         case FunctionDescriptor::SetCursorPosition:
@@ -1009,6 +1014,22 @@
     return Error::None;
 }
 
+Error HWC2On1Adapter::Display::getClientTargetSupport(uint32_t width, uint32_t height,
+                                      int32_t format, int32_t dataspace){
+    if (mActiveConfig == nullptr) {
+        return Error::Unsupported;
+    }
+
+    if (width == mActiveConfig->getAttribute(Attribute::Width) &&
+            height == mActiveConfig->getAttribute(Attribute::Height) &&
+            format == HAL_PIXEL_FORMAT_RGBA_8888 &&
+            dataspace == HAL_DATASPACE_UNKNOWN) {
+        return Error::None;
+    }
+
+    return Error::Unsupported;
+}
+
 static constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
     HWC_DISPLAY_VSYNC_PERIOD,
     HWC_DISPLAY_WIDTH,
diff --git a/libs/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h b/libs/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h
index a1d2c88..3badfce 100644
--- a/libs/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h
+++ b/libs/hwc2on1adapter/include/hwc2on1adapter/HWC2On1Adapter.h
@@ -248,6 +248,9 @@
 
             HWC2::Error updateLayerZ(hwc2_layer_t layerId, uint32_t z);
 
+            HWC2::Error getClientTargetSupport(uint32_t width, uint32_t height,
+                     int32_t format, int32_t dataspace);
+
             // Read configs from HWC1 device
             void populateConfigs();
 
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index ef49995..572cb4e 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -97,8 +97,6 @@
     AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE      = 1ULL << 10,
     /* The buffer will be written to by the GPU */
     AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT       = 1ULL << 11,
-    /* The buffer will be used as a cubemap texture */
-    AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP            = 1ULL << 13,
     /* The buffer will be used as a shader storage or uniform buffer object*/
     AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER        = 1ULL << 14,
     /* The buffer must not be used outside of a protected hardware path */
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
new file mode 100644
index 0000000..452bad0
--- /dev/null
+++ b/libs/vr/libbufferhub/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2016 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.
+
+sourceFiles = [
+    "buffer_hub_client.cpp",
+    "buffer_hub_rpc.cpp",
+    "ion_buffer.cpp",
+]
+
+localIncludeFiles = [
+    "include",
+]
+
+staticLibraries = [
+    "libdvrcommon",
+    "libpdx_default_transport",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "libhardware",
+    "liblog",
+    "libui",
+    "libutils",
+]
+
+cc_library {
+    srcs: sourceFiles,
+    cflags: [
+        "-DLOG_TAG=\"libbufferhub\"",
+        "-DTRACE=0"
+    ],
+    export_include_dirs: localIncludeFiles,
+    static_libs: staticLibraries,
+    shared_libs: sharedLibraries,
+    name: "libbufferhub",
+}
+
+cc_test {
+    tags: ["optional"],
+    srcs: ["bufferhub_tests.cpp"],
+    static_libs: ["libbufferhub"] + staticLibraries,
+    shared_libs: sharedLibraries,
+    name: "bufferhub_tests",
+}
+
diff --git a/libs/vr/libbufferhub/Android.mk b/libs/vr/libbufferhub/Android.mk
deleted file mode 100644
index 0877b0b..0000000
--- a/libs/vr/libbufferhub/Android.mk
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	buffer_hub_client.cpp \
-	buffer_hub_rpc.cpp \
-	ion_buffer.cpp
-
-includeFiles := \
-	$(LOCAL_PATH)/include
-
-staticLibraries := \
-	libdvrcommon \
-	libpdx_default_transport \
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	libhardware \
-	liblog \
-	libui \
-	libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"libbufferhub\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := libbufferhub
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := bufferhub_tests.cpp
-LOCAL_STATIC_LIBRARIES := libbufferhub $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := bufferhub_tests
-include $(BUILD_NATIVE_TEST)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
new file mode 100644
index 0000000..10198fd
--- /dev/null
+++ b/libs/vr/libbufferhubqueue/Android.bp
@@ -0,0 +1,51 @@
+// Copyright (C) 2016 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.
+
+sourceFiles = [
+    "buffer_hub_queue_client.cpp",
+    "buffer_hub_queue_core.cpp",
+    "buffer_hub_queue_consumer.cpp",
+    "buffer_hub_queue_producer.cpp",
+]
+
+includeFiles = [
+    "include",
+]
+
+staticLibraries = [
+    "libbufferhub",
+    "libdvrcommon",
+    "libpdx_default_transport",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libbinder",
+    "libcutils",
+    "libhardware",
+    "liblog",
+    "libui",
+    "libutils",
+    "libgui",
+]
+
+cc_library {
+    name: "libbufferhubqueue",
+    cflags = [ "-DLOGTAG=\"libbufferhubqueue\"" ],
+    srcs: sourceFiles,
+    export_include_dirs: includeFiles,
+    static_libs: staticLibraries,
+    shared_libs: sharedLibraries,
+}
+
diff --git a/libs/vr/libbufferhubqueue/Android.mk b/libs/vr/libbufferhubqueue/Android.mk
deleted file mode 100644
index d53f06a..0000000
--- a/libs/vr/libbufferhubqueue/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	buffer_hub_queue_client.cpp \
-	buffer_hub_queue_core.cpp \
-	buffer_hub_queue_consumer.cpp \
-	buffer_hub_queue_producer.cpp \
-
-includeFiles := \
-	$(LOCAL_PATH)/include
-
-staticLibraries := \
-	libbufferhub \
-	libdvrcommon \
-	libpdx_default_transport \
-
-sharedLibraries := \
-	libbase \
-	libbinder \
-	libcutils \
-	libhardware \
-	liblog \
-	libui \
-	libutils \
-        libgui \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"libbufferhubqueue\"
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := libbufferhubqueue
-include $(BUILD_STATIC_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index bad9503..a8077b9 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -13,9 +13,6 @@
 #include <pdx/file_handle.h>
 #include <private/dvr/bufferhub_rpc.h>
 
-using android::pdx::LocalHandle;
-using android::pdx::LocalChannelHandle;
-
 namespace android {
 namespace dvr {
 
@@ -28,6 +25,7 @@
       buffers_(BufferHubQueue::kMaxQueueCapacity),
       epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
       available_buffers_(BufferHubQueue::kMaxQueueCapacity),
+      fences_(BufferHubQueue::kMaxQueueCapacity),
       capacity_(0) {
   Initialize();
 }
@@ -41,6 +39,7 @@
       buffers_(BufferHubQueue::kMaxQueueCapacity),
       epollhup_pending_(BufferHubQueue::kMaxQueueCapacity, false),
       available_buffers_(BufferHubQueue::kMaxQueueCapacity),
+      fences_(BufferHubQueue::kMaxQueueCapacity),
       capacity_(0) {
   Initialize();
 }
@@ -134,7 +133,7 @@
 
   int events = status.get();
   if (events & EPOLLIN) {
-    int ret = OnBufferReady(buffer);
+    int ret = OnBufferReady(buffer, &fences_[slot]);
     if (ret < 0) {
       ALOGE("Failed to set buffer ready: %s", strerror(-ret));
       return;
@@ -254,7 +253,8 @@
 
 std::shared_ptr<BufferHubBuffer> BufferHubQueue::Dequeue(int timeout,
                                                          size_t* slot,
-                                                         void* meta) {
+                                                         void* meta,
+                                                         LocalHandle* fence) {
   ALOGD("Dequeue: count=%zu, timeout=%d", count(), timeout);
 
   if (count() == 0 && !WaitForBuffers(timeout))
@@ -263,6 +263,8 @@
   std::shared_ptr<BufferHubBuffer> buf;
   BufferInfo& buffer_info = available_buffers_.Front();
 
+  *fence = std::move(fences_[buffer_info.slot]);
+
   // Report current pos as the output slot.
   std::swap(buffer_info.slot, *slot);
   // Swap buffer from vector to be returned later.
@@ -373,15 +375,21 @@
   return BufferHubQueue::DetachBuffer(slot);
 }
 
-std::shared_ptr<BufferProducer> ProducerQueue::Dequeue(int timeout,
-                                                       size_t* slot) {
-  auto buf = BufferHubQueue::Dequeue(timeout, slot, nullptr);
+std::shared_ptr<BufferProducer> ProducerQueue::Dequeue(
+    int timeout, size_t* slot, LocalHandle* release_fence) {
+  if (slot == nullptr || release_fence == nullptr) {
+    ALOGE("invalid parameter, slot=%p, release_fence=%p", slot, release_fence);
+    return nullptr;
+  }
+
+  auto buf = BufferHubQueue::Dequeue(timeout, slot, nullptr, release_fence);
   return std::static_pointer_cast<BufferProducer>(buf);
 }
 
-int ProducerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf) {
+int ProducerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
+                                 LocalHandle* release_fence) {
   auto buffer = std::static_pointer_cast<BufferProducer>(buf);
-  return buffer->GainAsync();
+  return buffer->Gain(release_fence);
 }
 
 ConsumerQueue::ConsumerQueue(LocalChannelHandle handle, size_t meta_size)
@@ -431,9 +439,9 @@
   return BufferHubQueue::AddBuffer(buf, slot);
 }
 
-std::shared_ptr<BufferConsumer> ConsumerQueue::Dequeue(int timeout,
-                                                       size_t* slot, void* meta,
-                                                       size_t meta_size) {
+std::shared_ptr<BufferConsumer> ConsumerQueue::Dequeue(
+    int timeout, size_t* slot, void* meta, size_t meta_size,
+    LocalHandle* acquire_fence) {
   if (meta_size != meta_size_) {
     ALOGE(
         "metadata size (%zu) for the dequeuing buffer does not match metadata "
@@ -441,14 +449,21 @@
         meta_size, meta_size_);
     return nullptr;
   }
-  auto buf = BufferHubQueue::Dequeue(timeout, slot, meta);
+
+  if (slot == nullptr || meta == nullptr || acquire_fence == nullptr) {
+    ALOGE("invalid parameter, slot=%p, meta=%p, acquire_fence=%p", slot, meta,
+          acquire_fence);
+    return nullptr;
+  }
+
+  auto buf = BufferHubQueue::Dequeue(timeout, slot, meta, acquire_fence);
   return std::static_pointer_cast<BufferConsumer>(buf);
 }
 
-int ConsumerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf) {
+int ConsumerQueue::OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
+                                 LocalHandle* acquire_fence) {
   auto buffer = std::static_pointer_cast<BufferConsumer>(buf);
-  LocalHandle fence;
-  return buffer->Acquire(&fence, meta_buffer_tmp_.get(), meta_size_);
+  return buffer->Acquire(acquire_fence, meta_buffer_tmp_.get(), meta_size_);
 }
 
 int ConsumerQueue::OnBufferAllocated() {
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 7ddf49b..0deb764 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -83,8 +83,9 @@
   std::shared_ptr<BufferProducer> buffer_producer;
 
   for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
+    LocalHandle fence;
     buffer_producer =
-        core_->producer_->Dequeue(core_->dequeue_timeout_ms_, &slot);
+        core_->producer_->Dequeue(core_->dequeue_timeout_ms_, &slot, &fence);
     if (!buffer_producer)
       return NO_MEMORY;
 
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index 1f2830a..feaf3d7 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -20,6 +20,7 @@
 // automatically re-requeued when released by the remote side.
 class BufferHubQueue : public pdx::Client {
  public:
+  using LocalHandle = pdx::LocalHandle;
   using LocalChannelHandle = pdx::LocalChannelHandle;
   template <typename T>
   using Status = pdx::Status<T>;
@@ -91,14 +92,15 @@
   // while specifying a timeout equal to zero cause |Dequeue()| to return
   // immediately, even if no buffers are available.
   std::shared_ptr<BufferHubBuffer> Dequeue(int timeout, size_t* slot,
-                                           void* meta);
+                                           void* meta, LocalHandle* fence);
 
   // Wait for buffers to be released and re-add them to the queue.
   bool WaitForBuffers(int timeout);
   void HandleBufferEvent(size_t slot, const epoll_event& event);
   void HandleQueueEvent(const epoll_event& event);
 
-  virtual int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf) = 0;
+  virtual int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
+                            LocalHandle* fence) = 0;
 
   // Called when a buffer is allocated remotely.
   virtual int OnBufferAllocated() = 0;
@@ -202,6 +204,10 @@
   // prevent the buffer from being deleted.
   RingBuffer<BufferInfo> available_buffers_;
 
+  // Fences (acquire fence for consumer and release fence for consumer) , one
+  // for each buffer slot.
+  std::vector<LocalHandle> fences_;
+
   // Keep track with how many buffers have been added into the queue.
   size_t capacity_;
 
@@ -274,7 +280,8 @@
   // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
   // and caller should call Post() once it's done writing to release the buffer
   // to the consumer side.
-  std::shared_ptr<BufferProducer> Dequeue(int timeout, size_t* slot);
+  std::shared_ptr<BufferProducer> Dequeue(int timeout, size_t* slot,
+                                          LocalHandle* release_fence);
 
  private:
   friend BASE;
@@ -287,7 +294,8 @@
   ProducerQueue(size_t meta_size, int usage_set_mask, int usage_clear_mask,
                 int usage_deny_set_mask, int usage_deny_clear_mask);
 
-  int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf) override;
+  int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
+                    LocalHandle* release_fence) override;
 
   // Producer buffer is always allocated from the client (i.e. local) side.
   int OnBufferAllocated() override { return 0; }
@@ -316,14 +324,11 @@
   // Dequeue() is done with the corect metadata type and size with those used
   // when the buffer is orignally created.
   template <typename Meta>
-  std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot,
-                                          Meta* meta) {
-    return Dequeue(timeout, slot, meta, sizeof(*meta));
+  std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, Meta* meta,
+                                          LocalHandle* acquire_fence) {
+    return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence);
   }
 
-  std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, void* meta,
-                                          size_t meta_size);
-
  private:
   friend BASE;
 
@@ -335,9 +340,14 @@
   // consumer.
   int AddBuffer(const std::shared_ptr<BufferConsumer>& buf, size_t slot);
 
-  int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf) override;
+  int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
+                    LocalHandle* acquire_fence) override;
 
   int OnBufferAllocated() override;
+
+  std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, void* meta,
+                                          size_t meta_size,
+                                          LocalHandle* acquire_fence);
 };
 
 }  // namespace dvr
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
new file mode 100644
index 0000000..b8a0da3
--- /dev/null
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -0,0 +1,46 @@
+
+
+shared_libraries = [
+    "libbase",
+    "libbinder",
+    "libcutils",
+    "libgui",
+    "liblog",
+    "libhardware",
+    "libui",
+    "libutils",
+]
+
+static_libraries = [
+    "libbufferhubqueue",
+    "libbufferhub",
+    "libchrome",
+    "libdvrcommon",
+    "libpdx_default_transport",
+]
+
+cc_test {
+    srcs: ["buffer_hub_queue-test.cpp"],
+    static_libs: static_libraries,
+    shared_libs: shared_libraries,
+    cflags: [
+        "-DTRACE=0",
+        "-O0",
+        "-g",
+    ],
+    name: "buffer_hub_queue-test",
+    tags: ["optional"],
+}
+
+cc_test {
+    srcs: ["buffer_hub_queue_producer-test.cpp"],
+    static_libs: static_libraries,
+    shared_libs: shared_libraries,
+    cflags: [
+        "-DTRACE=0",
+        "-O0",
+        "-g",
+    ],
+    name: "buffer_hub_queue_producer-test",
+    tags: ["optional"],
+}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.mk b/libs/vr/libbufferhubqueue/tests/Android.mk
deleted file mode 100644
index 59061e6..0000000
--- a/libs/vr/libbufferhubqueue/tests/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-shared_libraries := \
-	libbase \
-	libbinder \
-	libcutils \
-	libgui \
-	liblog \
-	libhardware \
-	libui \
-	libutils \
-
-static_libraries := \
-	libbufferhubqueue \
-	libbufferhub \
-	libchrome \
-	libdvrcommon \
-	libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := buffer_hub_queue-test.cpp
-LOCAL_STATIC_LIBRARIES := $(static_libraries)
-LOCAL_SHARED_LIBRARIES := $(shared_libraries)
-LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
-LOCAL_CFLAGS := -DTRACE=0 -O0 -g
-LOCAL_MODULE := buffer_hub_queue-test
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_NATIVE_TEST)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := buffer_hub_queue_producer-test.cpp
-LOCAL_STATIC_LIBRARIES := $(static_libraries)
-LOCAL_SHARED_LIBRARIES := $(shared_libraries)
-LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
-LOCAL_CFLAGS := -DTRACE=0 -O0 -g
-LOCAL_MODULE := buffer_hub_queue_producer-test
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index 841554e..811543d 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -59,12 +59,13 @@
   // But dequeue multiple times.
   for (size_t i = 0; i < nb_dequeue_times; i++) {
     size_t slot;
-    auto p1 = producer_queue_->Dequeue(0, &slot);
+    LocalHandle fence;
+    auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
     ASSERT_NE(nullptr, p1);
     size_t mi = i;
     ASSERT_EQ(p1->Post(LocalHandle(), &mi, sizeof(mi)), 0);
     size_t mo;
-    auto c1 = consumer_queue_->Dequeue(100, &slot, &mo);
+    auto c1 = consumer_queue_->Dequeue(100, &slot, &mo, &fence);
     ASSERT_NE(nullptr, c1);
     ASSERT_EQ(mi, mo);
     c1->Release(LocalHandle());
@@ -91,19 +92,21 @@
     ASSERT_EQ(consumer_queue_->capacity(), i);
     // Dequeue returns nullptr since no buffer is ready to consumer, but
     // this implicitly triggers buffer import and bump up |capacity|.
-    auto consumer_null = consumer_queue_->Dequeue(0, &slot, &seq);
+    LocalHandle fence;
+    auto consumer_null = consumer_queue_->Dequeue(0, &slot, &seq, &fence);
     ASSERT_EQ(nullptr, consumer_null);
     ASSERT_EQ(consumer_queue_->capacity(), i + 1);
   }
 
   for (size_t i = 0; i < nb_buffer; i++) {
+    LocalHandle fence;
     // First time, there is no buffer available to dequeue.
-    auto buffer_null = consumer_queue_->Dequeue(0, &slot, &seq);
+    auto buffer_null = consumer_queue_->Dequeue(0, &slot, &seq, &fence);
     ASSERT_EQ(nullptr, buffer_null);
 
     // Make sure Producer buffer is Post()'ed so that it's ready to Accquire
     // in the consumer's Dequeue() function.
-    auto producer = producer_queue_->Dequeue(0, &slot);
+    auto producer = producer_queue_->Dequeue(0, &slot, &fence);
     ASSERT_NE(nullptr, producer);
 
     uint64_t seq_in = static_cast<uint64_t>(i);
@@ -111,7 +114,7 @@
 
     // Second time, the just |Post()|'ed buffer should be dequeued.
     uint64_t seq_out = 0;
-    auto consumer = consumer_queue_->Dequeue(0, &slot, &seq_out);
+    auto consumer = consumer_queue_->Dequeue(0, &slot, &seq_out, &fence);
     ASSERT_NE(nullptr, consumer);
     ASSERT_EQ(seq_in, seq_out);
   }
@@ -132,11 +135,12 @@
 
   for (auto mi : ms) {
     size_t slot;
-    auto p1 = producer_queue_->Dequeue(0, &slot);
+    LocalHandle fence;
+    auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
     ASSERT_NE(nullptr, p1);
     ASSERT_EQ(p1->Post(LocalHandle(-1), &mi, sizeof(mi)), 0);
     TestMetadata mo;
-    auto c1 = consumer_queue_->Dequeue(0, &slot, &mo);
+    auto c1 = consumer_queue_->Dequeue(0, &slot, &mo, &fence);
     ASSERT_EQ(mi.a, mo.a);
     ASSERT_EQ(mi.b, mo.b);
     ASSERT_EQ(mi.c, mo.c);
@@ -150,13 +154,14 @@
 
   int64_t mi = 3;
   size_t slot;
-  auto p1 = producer_queue_->Dequeue(0, &slot);
+  LocalHandle fence;
+  auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
   ASSERT_NE(nullptr, p1);
   ASSERT_EQ(p1->Post(LocalHandle(-1), &mi, sizeof(mi)), 0);
 
   int32_t mo;
   // Acquire a buffer with mismatched metadata is not OK.
-  auto c1 = consumer_queue_->Dequeue(0, &slot, &mo);
+  auto c1 = consumer_queue_->Dequeue(0, &slot, &mo, &fence);
   ASSERT_EQ(nullptr, c1);
 }
 
@@ -165,12 +170,13 @@
   AllocateBuffer();
 
   size_t slot;
-  auto p1 = producer_queue_->Dequeue(0, &slot);
+  LocalHandle fence;
+  auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
   ASSERT_NE(nullptr, p1);
 
   int64_t mo;
   producer_queue_->Enqueue(p1, slot);
-  auto c1 = consumer_queue_->Dequeue(0, &slot, &mo);
+  auto c1 = consumer_queue_->Dequeue(0, &slot, &mo, &fence);
   ASSERT_EQ(nullptr, c1);
 }
 
@@ -179,12 +185,13 @@
 
   size_t s1;
   AllocateBuffer();
-  auto p1 = producer_queue_->Dequeue(0, &s1);
+  LocalHandle fence;
+  auto p1 = producer_queue_->Dequeue(0, &s1, &fence);
   ASSERT_NE(nullptr, p1);
 
   // producer queue is exhausted
   size_t s2;
-  auto p2_null = producer_queue_->Dequeue(0, &s2);
+  auto p2_null = producer_queue_->Dequeue(0, &s2, &fence);
   ASSERT_EQ(nullptr, p2_null);
 
   // dynamically add buffer.
@@ -193,7 +200,7 @@
   ASSERT_EQ(producer_queue_->capacity(), 2U);
 
   // now we can dequeue again
-  auto p2 = producer_queue_->Dequeue(0, &s2);
+  auto p2 = producer_queue_->Dequeue(0, &s2, &fence);
   ASSERT_NE(nullptr, p2);
   ASSERT_EQ(producer_queue_->count(), 0U);
   // p1 and p2 should have different slot number
@@ -206,14 +213,14 @@
   int64_t seq = 1;
   ASSERT_EQ(p1->Post(LocalHandle(), seq), 0);
   size_t cs1, cs2;
-  auto c1 = consumer_queue_->Dequeue(0, &cs1, &seq);
+  auto c1 = consumer_queue_->Dequeue(0, &cs1, &seq, &fence);
   ASSERT_NE(nullptr, c1);
   ASSERT_EQ(consumer_queue_->count(), 0U);
   ASSERT_EQ(consumer_queue_->capacity(), 2U);
   ASSERT_EQ(cs1, s1);
 
   ASSERT_EQ(p2->Post(LocalHandle(), seq), 0);
-  auto c2 = consumer_queue_->Dequeue(0, &cs2, &seq);
+  auto c2 = consumer_queue_->Dequeue(0, &cs2, &seq, &fence);
   ASSERT_NE(nullptr, c2);
   ASSERT_EQ(cs2, s2);
 }
@@ -229,7 +236,8 @@
       kBufferSliceCount, &slot);
   ASSERT_EQ(ret, 0);
 
-  auto p1 = producer_queue_->Dequeue(0, &slot);
+  LocalHandle fence;
+  auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
   ASSERT_EQ(p1->usage() & set_mask, set_mask);
 }
 
@@ -244,7 +252,8 @@
       kBufferSliceCount, &slot);
   ASSERT_EQ(ret, 0);
 
-  auto p1 = producer_queue_->Dequeue(0, &slot);
+  LocalHandle fence;
+  auto p1 = producer_queue_->Dequeue(0, &slot, &fence);
   ASSERT_EQ(p1->usage() & clear_mask, 0);
 }
 
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
new file mode 100644
index 0000000..f3c71b5
--- /dev/null
+++ b/libs/vr/libdisplay/Android.bp
@@ -0,0 +1,104 @@
+// Copyright (C) 2015 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.
+
+sourceFiles = [
+    "native_buffer_queue.cpp",
+    "display_client.cpp",
+    "display_manager_client.cpp",
+    "display_manager_client_impl.cpp",
+    "display_rpc.cpp",
+    "dummy_native_window.cpp",
+    "gl_fenced_flush.cpp",
+    "graphics.cpp",
+    "late_latch.cpp",
+    "video_mesh_surface_client.cpp",
+    "vsync_client.cpp",
+    "vsync_client_api.cpp",
+    "screenshot_client.cpp",
+    "frame_history.cpp",
+]
+
+localIncludeFiles = [
+    "include",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "liblog",
+    "libutils",
+    "libEGL",
+    "libGLESv2",
+    "libvulkan",
+    "libui",
+    "libgui",
+    "libhardware",
+    "libsync",
+    "libnativewindow",
+]
+
+staticLibraries = [
+    "libbufferhub",
+    "libbufferhubqueue",
+    "libdvrcommon",
+    "libdvrgraphics",
+    "libvrsensor",
+    "libpdx_default_transport",
+]
+
+headerLibraries = [
+    "vulkan_headers",
+]
+
+cc_library {
+    tags: ["tests"],
+    srcs: sourceFiles,
+    cflags: ["-DLOG_TAG=\"libdisplay\"",
+        "-DTRACE=0",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+    ],  // + [ "-UNDEBUG", "-DDEBUG", "-O0", "-g" ],
+    export_include_dirs: localIncludeFiles,
+    shared_libs: sharedLibraries,
+    static_libs: staticLibraries,
+    header_libs: headerLibraries,
+    export_header_lib_headers: headerLibraries,
+
+    name: "libdisplay",
+}
+
+graphicsAppTestFiles = ["tests/graphics_app_tests.cpp"]
+
+cc_test {
+    name: "graphics_app_tests",
+    tags: ["optional"],
+
+    srcs: graphicsAppTestFiles,
+
+    shared_libs: sharedLibraries,
+
+    static_libs: ["libdisplay"] + staticLibraries,
+}
+
+dummyNativeWindowTestFiles = ["tests/dummy_native_window_tests.cpp"]
+
+cc_test {
+    name: "dummy_native_window_tests",
+    tags: [ "optional" ],
+    srcs: dummyNativeWindowTestFiles,
+    shared_libs: sharedLibraries,
+    static_libs: [ "libdisplay" ] + staticLibraries,
+}
+
diff --git a/libs/vr/libdisplay/Android.mk b/libs/vr/libdisplay/Android.mk
deleted file mode 100644
index 60f73c6..0000000
--- a/libs/vr/libdisplay/Android.mk
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	native_buffer_queue.cpp \
-	display_client.cpp \
-	display_manager_client.cpp \
-	display_manager_client_impl.cpp \
-	display_rpc.cpp \
-	dummy_native_window.cpp \
-	gl_fenced_flush.cpp \
-	graphics.cpp \
-	late_latch.cpp \
-	video_mesh_surface_client.cpp \
-	vsync_client.cpp \
-	vsync_client_api.cpp \
-	screenshot_client.cpp \
-	frame_history.cpp
-
-includeFiles := \
-	$(LOCAL_PATH)/include \
-	frameworks/native/vulkan/include
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	liblog \
-	libutils \
-	libEGL \
-	libGLESv2 \
-	libvulkan \
-	libui \
-	libgui \
-	libhardware \
-	libsync \
-	libnativewindow \
-
-staticLibraries := \
-	libbufferhub \
-	libbufferhubqueue \
-	libdvrcommon \
-	libdvrgraphics \
-	libsensor \
-	libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-#LOCAL_CPPFLAGS := -UNDEBUG -DDEBUG -O0 -g
-LOCAL_CFLAGS += -DLOG_TAG=\"libdisplay\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_GRAPHICS
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_MODULE := libdisplay
-include $(BUILD_STATIC_LIBRARY)
-
-graphicsAppTestFiles := \
-  tests/graphics_app_tests.cpp
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := graphics_app_tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-  $(graphicsAppTestFiles) \
-
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := \
-  $(sharedLibraries) \
-
-LOCAL_STATIC_LIBRARIES := \
-  libdisplay \
-  $(staticLibraries) \
-
-include $(BUILD_NATIVE_TEST)
-
-dummyNativeWindowTestFiles := \
-  tests/dummy_native_window_tests.cpp \
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := dummy_native_window_tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-  $(dummyNativeWindowTestFiles) \
-
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := \
-  $(sharedLibraries) \
-
-LOCAL_STATIC_LIBRARIES := \
-  libdisplay \
-  $(staticLibraries) \
-include $(BUILD_NATIVE_TEST)
-
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
new file mode 100644
index 0000000..81404a4
--- /dev/null
+++ b/libs/vr/libdvrcommon/Android.bp
@@ -0,0 +1,81 @@
+// Copyright (C) 2016 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.
+
+sourceFiles = [
+    "frame_time_history.cpp",
+    "revision.cpp",
+    "revision_path.cpp",
+    "sync_util.cpp",
+]
+
+localIncludeFiles = [
+    "include",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "liblog",
+    "libutils",
+    "libEGL",
+    "libGLESv2",
+    "libui",
+    "libgui",
+    "libhardware",
+]
+
+staticLibraries = ["libpdx_default_transport"]
+
+headerLibraries = [
+    "libeigen",
+]
+
+cc_library {
+    srcs: sourceFiles,
+    local_include_dirs: localIncludeFiles,
+
+    cflags: [
+        "-DLOG_TAG=\"libdvrcommon\"",
+        "-DTRACE=0",
+    ],
+    export_include_dirs: localIncludeFiles,
+
+    shared_libs: sharedLibraries,
+    static_libs: staticLibraries,
+    header_libs: headerLibraries,
+    export_header_lib_headers: headerLibraries,
+
+    name: "libdvrcommon",
+}
+
+testFiles = [
+    "tests/numeric_test.cpp",
+    "tests/pose_test.cpp",
+]
+
+cc_test {
+    name: "libdvrcommon_test",
+    tags: ["optional"],
+
+    srcs: testFiles,
+
+    shared_libs: sharedLibraries,
+
+    static_libs: [
+        "libgmock_main",
+        "libgmock",
+        "libgtest",
+	"libdvrcommon",
+    ] + staticLibraries,
+}
diff --git a/libs/vr/libdvrcommon/Android.mk b/libs/vr/libdvrcommon/Android.mk
deleted file mode 100644
index 80eb3a6..0000000
--- a/libs/vr/libdvrcommon/Android.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	frame_time_history.cpp \
-	revision.cpp \
-	revision_path.cpp \
-	sync_util.cpp \
-
-includeFiles := \
-  $(LOCAL_PATH)/include \
-  external/eigen \
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	liblog \
-	libutils \
-	libEGL \
-	libGLESv2 \
-	libui \
-	libgui \
-	libhardware
-
-staticLibraries := \
-	libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_CFLAGS += -DLOG_TAG=\"libdvrcommon\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_MODULE := libdvrcommon
-include $(BUILD_STATIC_LIBRARY)
-
-testFiles := \
-  tests/numeric_test.cpp \
-  tests/pose_test.cpp \
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libdvrcommon_test
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-  $(testFiles) \
-
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := \
-  $(sharedLibraries) \
-
-LOCAL_STATIC_LIBRARIES := \
-  libgmock_main \
-  libgmock \
-  libgtest \
-  $(staticLibraries) \
-
-include $(BUILD_NATIVE_TEST)
-
diff --git a/libs/vr/libdvrgraphics/Android.bp b/libs/vr/libdvrgraphics/Android.bp
new file mode 100644
index 0000000..73a8bf8
--- /dev/null
+++ b/libs/vr/libdvrgraphics/Android.bp
@@ -0,0 +1,45 @@
+
+
+sourceFiles = [
+    "blur.cpp",
+    "debug_text.cpp",
+    "egl_image.cpp",
+    "gpu_profiler.cpp",
+    "shader_program.cpp",
+    "timer_query.cpp",
+    "vr_gl_extensions.cpp",
+]
+
+localIncludeFiles = [
+    "include",
+]
+
+staticLibraries = [
+    "libbufferhub",
+    "libdvrcommon",
+    "libpdx_default_transport",
+]
+
+sharedLibraries = [
+    "libcutils",
+    "libbase",
+    "libEGL",
+    "libGLESv2",
+    "libpng",
+    "liblog",
+]
+
+cc_library_static {
+    srcs: sourceFiles,
+    cflags: [
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+    ],
+    export_include_dirs: localIncludeFiles,
+    shared_libs: sharedLibraries,
+    static_libs: staticLibraries,
+    // Rather than add this header-file-only library to all users of libdvrgraphics,
+    // include it here.
+    whole_static_libs: ["libarect"],
+    name: "libdvrgraphics",
+}
diff --git a/libs/vr/libdvrgraphics/Android.mk b/libs/vr/libdvrgraphics/Android.mk
deleted file mode 100644
index b9e601c..0000000
--- a/libs/vr/libdvrgraphics/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	blur.cpp \
-	debug_text.cpp \
-	egl_image.cpp \
-	gpu_profiler.cpp \
-	shader_program.cpp \
-	timer_query.cpp \
-	vr_gl_extensions.cpp \
-
-includeFiles := \
-	$(LOCAL_PATH)/include
-
-staticLibraries := \
-	libbufferhub \
-	libdvrcommon \
-	libpdx_default_transport \
-
-sharedLibraries := \
-	libcutils \
-	libbase \
-	libpng
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-# Rather than add this header-file-only library to all users of libdvrgraphics,
-# include it here.
-LOCAL_WHOLE_STATIC_LIBRARIES := libarect
-LOCAL_MODULE := libdvrgraphics
-include $(BUILD_STATIC_LIBRARY)
-
diff --git a/libs/vr/libeds/Android.bp b/libs/vr/libeds/Android.bp
new file mode 100644
index 0000000..a9df847
--- /dev/null
+++ b/libs/vr/libeds/Android.bp
@@ -0,0 +1,85 @@
+// Copyright (C) 2015 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.
+
+sourceFiles = [
+    "eds.cpp",
+    "eds_mesh.cpp",
+    "composite_hmd.cpp",
+    "cpu_thread_pose_updater.cpp",
+    "display_metrics.cpp",
+    "distortion_renderer.cpp",
+    "lucid_metrics.cpp",
+    "lucid_pose_tracker.cpp",
+    "lookup_radial_distortion.cpp",
+    "polynomial_radial_distortion.cpp",
+]
+
+localIncludeFiles = [
+    "include",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "liblog",
+    "libEGL",
+    "libGLESv1_CM",
+    "libGLESv2",
+    "libvulkan",
+]
+
+staticLibraries = [
+    "libdisplay",
+    "libdvrcommon",
+    "libdvrgraphics",
+    "libvrsensor",
+    "libpdx_default_transport",
+]
+
+cc_library_static {
+    srcs: sourceFiles,
+    cflags: [
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+        "-Wno-unused-parameter"],
+    // Enable debug options below to show GL errors and use gdb.
+    // + ["-UNDEBUG", "-DDEBUG", "-O0", "-g", ]
+    export_include_dirs: localIncludeFiles,
+    shared_libs: sharedLibraries,
+    static_libs: staticLibraries,
+    name: "libeds",
+}
+
+testFiles = ["tests/eds_app_tests.cpp"]
+
+cc_test {
+    name: "eds_app_tests",
+    tags: ["optional"],
+
+    srcs: testFiles,
+
+    shared_libs: [
+        "libhardware",
+        "libsync",
+    ] + sharedLibraries,
+
+    static_libs: [
+        "libgmock_main",
+        "libgmock",
+        "libeds",
+    ] + staticLibraries + [
+        "libbufferhub"
+    ],
+
+}
diff --git a/libs/vr/libeds/Android.mk b/libs/vr/libeds/Android.mk
deleted file mode 100644
index d2e6526..0000000
--- a/libs/vr/libeds/Android.mk
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	eds.cpp \
-	eds_mesh.cpp \
-	composite_hmd.cpp \
-	cpu_thread_pose_updater.cpp \
-	display_metrics.cpp \
-	distortion_renderer.cpp \
-	lucid_metrics.cpp \
-	lucid_pose_tracker.cpp \
-	lookup_radial_distortion.cpp \
-	polynomial_radial_distortion.cpp
-
-includeFiles += \
-	$(LOCAL_PATH)/include
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	liblog \
-	libEGL \
-	libGLESv1_CM \
-	libGLESv2 \
-	libvulkan \
-
-staticLibraries := \
-	libdisplay \
-	libdvrcommon \
-	libdvrgraphics \
-	libsensor \
-	libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_CFLAGS += -Wno-unused-parameter
-# Enable debug options below to show GL errors and use gdb.
-# LOCAL_CFLAGS += -UNDEBUG -DDEBUG -O0 -g
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_MODULE := libeds
-include $(BUILD_STATIC_LIBRARY)
-
-
-testFiles := \
-  tests/eds_app_tests.cpp
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := eds_app_tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-  $(testFiles) \
-
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := \
-  libhardware \
-  libsync \
-  $(sharedLibraries) \
-
-LOCAL_STATIC_LIBRARIES := \
-  libgmock_main \
-  libgmock \
-  libdisplay \
-  libeds \
-  libbufferhub \
-  $(staticLibraries) \
-
-include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libimageio/Android.bp b/libs/vr/libimageio/Android.bp
new file mode 100644
index 0000000..7dde075
--- /dev/null
+++ b/libs/vr/libimageio/Android.bp
@@ -0,0 +1,26 @@
+
+
+sourceFiles = [
+    "image_io.cpp",
+    "image_io_png.cpp",
+    "image_io_ppm.cpp",
+]
+
+includeFiles = ["include"]
+
+sharedLibraries = [
+    "libcutils",
+    "libpng",
+]
+
+cc_library_static {
+    srcs: sourceFiles,
+    export_include_dirs: includeFiles,
+    shared_libs: sharedLibraries,
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    name: "libimageio",
+    tags: ["optional"],
+}
diff --git a/libs/vr/libimageio/Android.mk b/libs/vr/libimageio/Android.mk
deleted file mode 100644
index b3b88ac..0000000
--- a/libs/vr/libimageio/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	image_io.cpp \
-	image_io_png.cpp \
-	image_io_ppm.cpp
-
-includeFiles := \
-  $(LOCAL_PATH)/include
-
-sharedLibraries := \
-	libcutils \
-	libpng
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES += $(includeFiles)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_CFLAGS := -Wall -Wextra
-LOCAL_MODULE := libimageio
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method.h b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
index 49bee40..679503c 100644
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method.h
+++ b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
@@ -25,10 +25,9 @@
 // Evaluates to true if the method type is <any>(Void), false otherwise.
 template <typename RemoteMethodType>
 using IsVoidMethod = typename std::integral_constant<
-    bool,
-    RemoteMethodType::Traits::Arity == 1 &&
-        std::is_same<typename RemoteMethodType::Traits::template Arg<0>,
-                     Void>::value>;
+    bool, RemoteMethodType::Traits::Arity == 1 &&
+              std::is_same<typename RemoteMethodType::Traits::template Arg<0>,
+                           Void>::value>;
 
 // Utility to determine if a method is of type <any>(Void).
 template <typename RemoteMethodType>
@@ -274,7 +273,9 @@
 void DispatchRemoteMethod(
     Class& instance, ChannelHandle<Mode> (Class::*method)(Message&, Args...),
     Message& message, std::size_t max_capacity = InitialBufferCapacity) {
-  using Signature = typename RemoteMethodType::template RewriteArgs<Args...>;
+  using Signature =
+      typename RemoteMethodType::template RewriteSignature<ChannelHandle<Mode>,
+                                                           Args...>;
   rpc::ServicePayload<ReceiveBuffer> payload(message);
   payload.Resize(max_capacity);
 
diff --git a/libs/vr/libperformance/Android.bp b/libs/vr/libperformance/Android.bp
new file mode 100644
index 0000000..364873d
--- /dev/null
+++ b/libs/vr/libperformance/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 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.
+
+sourceFiles = [
+    "performance_client.cpp",
+    "performance_rpc.cpp",
+]
+
+includeFiles = [ "include" ]
+
+staticLibraries = ["libpdx_default_transport"]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "liblog",
+    "libutils",
+]
+
+cc_library {
+    srcs: sourceFiles,
+    cflags: [
+        "-DLOG_TAG=\"libperformance\"",
+	"-DTRACE=0"
+    ],
+    export_include_dirs: includeFiles,
+    static_libs: staticLibraries,
+    shared_libs: sharedLibraries,
+    name: "libperformance",
+}
diff --git a/libs/vr/libperformance/Android.mk b/libs/vr/libperformance/Android.mk
deleted file mode 100644
index aaacb1a..0000000
--- a/libs/vr/libperformance/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	performance_client.cpp \
-	performance_rpc.cpp
-
-includeFiles := \
-	$(LOCAL_PATH)/include
-
-staticLibraries := \
-	libpdx_default_transport \
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	liblog \
-	libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"libperformance\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := libperformance
-include $(BUILD_STATIC_LIBRARY)
-
diff --git a/libs/vr/libposepredictor/Android.bp b/libs/vr/libposepredictor/Android.bp
new file mode 100644
index 0000000..2f1d2f5
--- /dev/null
+++ b/libs/vr/libposepredictor/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2008 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.
+
+sourceFiles = [
+    "predictor.cpp",
+    "buffered_predictor.cpp",
+    "linear_predictor.cpp",
+    "polynomial_predictor.cpp",
+    "dvr_pose_predictor.cpp",
+]
+
+includeFiles = [
+    "include",
+]
+
+staticLibraries = ["libvrsensor"]
+
+sharedLibraries = []
+
+headerLibraries = [ "libeigen" ]
+
+cc_library {
+    srcs: sourceFiles,
+    cflags: [
+      "-DLOG_TAG=\"libposepredictor\"",
+      "-DTRACE=0",
+    ],
+    export_include_dirs: includeFiles,
+    static_libs: staticLibraries,
+    shared_libs: sharedLibraries,
+    header_libs: headerLibraries,
+    export_header_lib_headers: headerLibraries,
+    name: "libposepredictor",
+}
+
+cc_test {
+    tags: ["optional"],
+    srcs: [
+        "predictor_tests.cpp",
+        "linear_predictor_tests.cpp",
+        "polynomial_predictor_tests.cpp",
+    ],
+
+    static_libs: ["libposepredictor"] + staticLibraries,
+    shared_libs: sharedLibraries,
+    name: "pose_predictor_tests",
+}
diff --git a/libs/vr/libposepredictor/Android.mk b/libs/vr/libposepredictor/Android.mk
deleted file mode 100755
index 2217819..0000000
--- a/libs/vr/libposepredictor/Android.mk
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2008 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-        predictor.cpp \
-        buffered_predictor.cpp \
-        linear_predictor.cpp \
-        polynomial_predictor.cpp \
-        dvr_pose_predictor.cpp \
-
-includeFiles := \
-        $(LOCAL_PATH)/include \
-        external/eigen \
-
-staticLibraries := \
-        libsensor \
-
-sharedLibraries := \
-
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"libposepredictor\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := libposepredictor
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-        predictor_tests.cpp \
-        linear_predictor_tests.cpp \
-        polynomial_predictor_tests.cpp \
-
-LOCAL_STATIC_LIBRARIES := libposepredictor $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := pose_predictor_tests
-include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libsensor/Android.mk b/libs/vr/libsensor/Android.mk
deleted file mode 100644
index 8c7ad43..0000000
--- a/libs/vr/libsensor/Android.mk
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2015 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	pose_client.cpp \
-	sensor_client.cpp
-
-includeFiles := \
-	$(LOCAL_PATH)/include
-
-staticLibraries := \
-	libbufferhub \
-	libdvrcommon \
-	libpdx_default_transport \
-
-sharedLibraries := \
-	libbase \
-	libcutils \
-	libhardware \
-	liblog \
-	libutils \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := libsensor
-include $(BUILD_STATIC_LIBRARY)
-
-
-testFiles := \
-  tests/sensor_app_tests.cpp
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := sensor_app_tests
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := \
-  $(testFiles) \
-
-LOCAL_C_INCLUDES := \
-  $(includeFiles) \
-
-LOCAL_SHARED_LIBRARIES := \
-  libEGL \
-  libGLESv1_CM \
-  libGLESv2 \
-  libvulkan \
-  libsync \
-  $(sharedLibraries) \
-
-LOCAL_STATIC_LIBRARIES := \
-  libgmock_main \
-  libgmock \
-  libdisplay \
-  libeds \
-  libsensor \
-  libdvrgraphics \
-  $(staticLibraries) \
-
-include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libvr_manager/Android.bp b/libs/vr/libvr_manager/Android.bp
new file mode 100644
index 0000000..8784877
--- /dev/null
+++ b/libs/vr/libvr_manager/Android.bp
@@ -0,0 +1,36 @@
+// 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.
+
+exported_include_dirs = [ "include" ]
+
+include_dirs = ["frameworks/native/include/vr/vr_manager"]
+
+src_files = [
+    "vr_manager.cpp",
+    "trusted_uids.cpp",
+]
+
+static_libs = [
+    "libutils",
+    "libbinder",
+]
+
+cc_library_static {
+    srcs: src_files,
+    include_dirs: include_dirs,
+    export_include_dirs: exported_include_dirs,
+    cflags: ["-Wall", "-Werror", "-Wunused", "-Wunreachable-code"],
+    static_libs: static_libs,
+    name: "libvr_manager",
+}
diff --git a/libs/vr/libvr_manager/Android.mk b/libs/vr/libvr_manager/Android.mk
deleted file mode 100644
index e9987f7..0000000
--- a/libs/vr/libvr_manager/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-
-exported_include_dirs := \
-  $(LOCAL_PATH)/include
-
-include_dirs := \
-  frameworks/native/include/vr/vr_manager \
-  $(exported_include_dirs)
-
-src_files := \
-  vr_manager.cpp \
-  trusted_uids.cpp
-
-static_libs := \
-  libutils \
-  libbinder \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(src_files)
-LOCAL_C_INCLUDES := $(include_dirs)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(exported_include_dirs)
-LOCAL_CFLAGS += -Wall
-LOCAL_CFLAGS += -Werror
-LOCAL_CFLAGS += -Wunused
-LOCAL_CFLAGS += -Wunreachable-code
-LOCAL_STATIC_LIBRARIES := $(static_libs)
-LOCAL_MODULE := libvr_manager
-include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
new file mode 100644
index 0000000..4ad7c23
--- /dev/null
+++ b/libs/vr/libvrflinger/Android.bp
@@ -0,0 +1,87 @@
+// Copyright (C) 2008 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.
+
+sourceFiles = [
+    "acquired_buffer.cpp",
+    "compositor.cpp",
+    "debug_hud_data.cpp",
+    "debug_hud_view.cpp",
+    "display_manager_service.cpp",
+    "display_service.cpp",
+    "display_surface.cpp",
+    "epoll_event_dispatcher.cpp",
+    "hardware_composer.cpp",
+    "screenshot_service.cpp",
+    "surface_channel.cpp",
+    "video_compositor.cpp",
+    "video_mesh_surface.cpp",
+    "vr_flinger.cpp",
+    "vsync_service.cpp",
+]
+
+includeFiles = [ "include" ]
+
+staticLibraries = [
+    "libsurfaceflingerincludes",
+    "libhwcomposer-command-buffer",
+    "libbufferhub",
+    "libbufferhubqueue",
+    "libeds",
+    "libdisplay",
+    "libdvrcommon",
+    "libdvrgraphics",
+    "libperformance",
+    "libvrsensor",
+    "libpdx_default_transport",
+    "libvr_manager",
+]
+
+sharedLibraries = [
+    "android.dvr.composer@1.0",
+    "android.hardware.graphics.allocator@2.0",
+    "android.hardware.graphics.composer@2.1",
+    "libbinder",
+    "libbase",
+    "libcutils",
+    "liblog",
+    "libhardware",
+    "libnativewindow",
+    "libutils",
+    "libEGL",
+    "libGLESv1_CM",
+    "libGLESv2",
+    "libvulkan",
+    "libui",
+    "libgui",
+    "libsync",
+    "libhidlbase",
+    "libhidltransport",
+    "libfmq",
+]
+
+cc_library_static {
+    srcs: sourceFiles,
+    export_include_dirs: includeFiles,
+
+    cflags: [
+        "-DLOG_TAG=\"vr_flinger\"",
+        "-DTRACE=0",
+	"-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+        "-DGL_GLEXT_PROTOTYPES",
+        "-DEGL_EGLEXT_PROTOTYPES",
+    ],
+    shared_libs: sharedLibraries,
+    whole_static_libs: staticLibraries,
+    name: "libvrflinger",
+}
diff --git a/libs/vr/libvrflinger/Android.mk b/libs/vr/libvrflinger/Android.mk
deleted file mode 100644
index 3450788..0000000
--- a/libs/vr/libvrflinger/Android.mk
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2008 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
-	acquired_buffer.cpp \
-	compositor.cpp \
-	debug_hud_data.cpp \
-	debug_hud_view.cpp \
-	display_manager_service.cpp \
-	display_service.cpp \
-	display_surface.cpp \
-	epoll_event_dispatcher.cpp \
-	hardware_composer.cpp \
-	screenshot_service.cpp \
-	surface_channel.cpp \
-	video_compositor.cpp \
-	video_mesh_surface.cpp \
-	vr_flinger.cpp \
-	vsync_service.cpp
-
-includeFiles := $(LOCAL_PATH)/include
-
-staticLibraries := \
-	libsurfaceflingerincludes \
-	libhwcomposer-command-buffer \
-	libbufferhub \
-	libbufferhubqueue \
-	libeds \
-	libdisplay \
-	libdvrcommon \
-	libdvrgraphics \
-	libperformance \
-	libsensor \
-	libpdx_default_transport \
-	libvr_manager \
-
-sharedLibraries := \
-	android.dvr.composer@1.0 \
-	android.hardware.graphics.allocator@2.0 \
-	android.hardware.graphics.composer@2.1 \
-	libbinder \
-	libbase \
-	libcutils \
-	liblog \
-	libhardware \
-	libnativewindow \
-	libutils \
-	libEGL \
-	libGLESv1_CM \
-	libGLESv2 \
-	libvulkan \
-	libui \
-	libgui \
-	libsync \
-	libhidlbase \
-	libhidltransport \
-	libfmq \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_C_INCLUDES := $(includeFiles)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(includeFiles)
-
-LOCAL_CFLAGS += -DLOG_TAG=\"vr_flinger\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_GRAPHICS
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_WHOLE_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_MODULE := libvrflinger
-include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvrflinger/video_compositor.cpp b/libs/vr/libvrflinger/video_compositor.cpp
index 6b39a3c..411e3a3 100644
--- a/libs/vr/libvrflinger/video_compositor.cpp
+++ b/libs/vr/libvrflinger/video_compositor.cpp
@@ -79,7 +79,9 @@
     // queued in order from the producer side.
     // TODO(jwcai) Use |metadata.timestamp_ns| to schedule video frames
     // accurately.
-    auto buffer_consumer = consumer_queue_->Dequeue(0, &slot, &metadata);
+    LocalHandle acquire_fence;
+    auto buffer_consumer =
+        consumer_queue_->Dequeue(0, &slot, &metadata, &acquire_fence);
 
     if (buffer_consumer) {
       // Create a new texture if it hasn't been created yet, or the same slot
diff --git a/libs/vr/libvrsensor/Android.bp b/libs/vr/libvrsensor/Android.bp
new file mode 100644
index 0000000..376630e
--- /dev/null
+++ b/libs/vr/libvrsensor/Android.bp
@@ -0,0 +1,71 @@
+// Copyright (C) 2015 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.
+
+sourceFiles = [
+    "pose_client.cpp",
+    "sensor_client.cpp",
+]
+
+includeFiles = [
+    "include",
+]
+
+staticLibraries = [
+    "libbufferhub",
+    "libdvrcommon",
+    "libpdx_default_transport",
+]
+
+sharedLibraries = [
+    "libbase",
+    "libcutils",
+    "libhardware",
+    "liblog",
+    "libutils",
+]
+
+cc_library {
+    srcs: sourceFiles,
+    export_include_dirs: includeFiles,
+    static_libs: staticLibraries,
+    shared_libs: sharedLibraries,
+    name: "libvrsensor",
+}
+
+testFiles = ["tests/sensor_app_tests.cpp"]
+
+cc_test {
+    name: "sensor_app_tests",
+    tags: ["optional"],
+
+    srcs: testFiles,
+
+    shared_libs: [
+        "libEGL",
+        "libGLESv1_CM",
+        "libGLESv2",
+        "libvulkan",
+        "libsync",
+    ] + sharedLibraries,
+
+    static_libs: [
+        "libgmock_main",
+        "libgmock",
+        "libdisplay",
+        "libeds",
+        "libvrsensor",
+        "libdvrgraphics",
+    ] + staticLibraries,
+
+}
diff --git a/libs/vr/libsensor/include/CPPLINT.cfg b/libs/vr/libvrsensor/include/CPPLINT.cfg
similarity index 100%
rename from libs/vr/libsensor/include/CPPLINT.cfg
rename to libs/vr/libvrsensor/include/CPPLINT.cfg
diff --git a/libs/vr/libsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h
similarity index 100%
rename from libs/vr/libsensor/include/dvr/pose_client.h
rename to libs/vr/libvrsensor/include/dvr/pose_client.h
diff --git a/libs/vr/libsensor/include/private/dvr/pose-ipc.h b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
similarity index 100%
rename from libs/vr/libsensor/include/private/dvr/pose-ipc.h
rename to libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
diff --git a/libs/vr/libsensor/include/private/dvr/pose_client_internal.h b/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
similarity index 100%
rename from libs/vr/libsensor/include/private/dvr/pose_client_internal.h
rename to libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
diff --git a/libs/vr/libsensor/include/private/dvr/sensor-ipc.h b/libs/vr/libvrsensor/include/private/dvr/sensor-ipc.h
similarity index 100%
rename from libs/vr/libsensor/include/private/dvr/sensor-ipc.h
rename to libs/vr/libvrsensor/include/private/dvr/sensor-ipc.h
diff --git a/libs/vr/libsensor/include/private/dvr/sensor_client.h b/libs/vr/libvrsensor/include/private/dvr/sensor_client.h
similarity index 100%
rename from libs/vr/libsensor/include/private/dvr/sensor_client.h
rename to libs/vr/libvrsensor/include/private/dvr/sensor_client.h
diff --git a/libs/vr/libsensor/include/private/dvr/sensor_constants.h b/libs/vr/libvrsensor/include/private/dvr/sensor_constants.h
similarity index 100%
rename from libs/vr/libsensor/include/private/dvr/sensor_constants.h
rename to libs/vr/libvrsensor/include/private/dvr/sensor_constants.h
diff --git a/libs/vr/libsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp
similarity index 100%
rename from libs/vr/libsensor/pose_client.cpp
rename to libs/vr/libvrsensor/pose_client.cpp
diff --git a/libs/vr/libsensor/sensor_client.cpp b/libs/vr/libvrsensor/sensor_client.cpp
similarity index 100%
rename from libs/vr/libsensor/sensor_client.cpp
rename to libs/vr/libvrsensor/sensor_client.cpp
diff --git a/libs/vr/libsensor/tests/sensor_app_tests.cpp b/libs/vr/libvrsensor/tests/sensor_app_tests.cpp
similarity index 100%
rename from libs/vr/libsensor/tests/sensor_app_tests.cpp
rename to libs/vr/libvrsensor/tests/sensor_app_tests.cpp
diff --git a/services/Android.bp b/services/Android.bp
new file mode 100644
index 0000000..7a8ee5d
--- /dev/null
+++ b/services/Android.bp
@@ -0,0 +1 @@
+subdirs = [ "*" ]
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
new file mode 100644
index 0000000..8c2300e
--- /dev/null
+++ b/services/sensorservice/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+    "hidl"
+]
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 7bd495f..2a17a7f 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -51,7 +51,7 @@
     }
 }
 
-SensorDevice::SensorDevice() {
+SensorDevice::SensorDevice() : mHidlTransportErrors(20) {
     // SensorDevice may wait upto 100ms * 10 = 1s for hidl service.
     constexpr auto RETRY_DELAY = std::chrono::milliseconds(100);
     size_t retry = 10;
@@ -118,7 +118,15 @@
     if (mSensors == NULL) return "HAL not initialized\n";
 
     String8 result;
-    checkReturn(mSensors->getSensorsList([&](const auto &list) {
+
+    result.appendFormat("Saw %d hidlTransport Errors\n", mTotalHidlTransportErrors);
+    for (auto it = mHidlTransportErrors.begin() ; it != mHidlTransportErrors.end(); it++ ) {
+        result += "\t";
+        result += it->toString();
+        result += "\n";
+    }
+
+    checkReturn(mSensors->getSensorsList([&](const auto &list){
             const size_t count = list.size();
 
             result.appendFormat(
@@ -182,19 +190,44 @@
     if (mSensors == NULL) return NO_INIT;
 
     ssize_t err;
+    int numHidlTransportErrors = 0;
+    bool hidlTransportError = false;
 
-    checkReturn(mSensors->poll(
-            count,
-            [&](auto result,
-                const auto &events,
-                const auto &dynamicSensorsAdded) {
-                if (result == Result::OK) {
-                    convertToSensorEvents(events, dynamicSensorsAdded, buffer);
-                    err = (ssize_t)events.size();
-                } else {
-                    err = StatusFromResult(result);
-                }
-            }));
+    do {
+        auto ret = mSensors->poll(
+                count,
+                [&](auto result,
+                    const auto &events,
+                    const auto &dynamicSensorsAdded) {
+                    if (result == Result::OK) {
+                        convertToSensorEvents(events, dynamicSensorsAdded, buffer);
+                        err = (ssize_t)events.size();
+                    } else {
+                        err = StatusFromResult(result);
+                    }
+                });
+
+        if (ret.isOk())  {
+            hidlTransportError = false;
+        } else {
+            hidlTransportError = true;
+            numHidlTransportErrors++;
+            if (numHidlTransportErrors > 50) {
+                // Log error and bail
+                ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors);
+                handleHidlDeath(ret.description());
+            } else {
+                std::this_thread::sleep_for(std::chrono::milliseconds(10));
+            }
+        }
+    } while (hidlTransportError);
+
+    if(numHidlTransportErrors > 0) {
+        ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors);
+        HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors);
+        mHidlTransportErrors.add(errLog);
+        mTotalHidlTransportErrors++;
+    }
 
     return err;
 }
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 03552f6..410531b 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -31,6 +31,8 @@
 
 #include "android/hardware/sensors/1.0/ISensors.h"
 
+#include "RingBuffer.h"
+
 // ---------------------------------------------------------------------------
 
 namespace android {
@@ -41,6 +43,33 @@
 
 class SensorDevice : public Singleton<SensorDevice>, public Dumpable {
 public:
+
+    class HidlTransportErrorLog {
+     public:
+
+        HidlTransportErrorLog() {
+            mTs = 0;
+            mCount = 0;
+        }
+
+        HidlTransportErrorLog(time_t ts, int count) {
+            mTs = ts;
+            mCount = count;
+        }
+
+        String8 toString() const {
+            String8 result;
+            struct tm *timeInfo = localtime(&mTs);
+            result.appendFormat("%02d:%02d:%02d :: %d", timeInfo->tm_hour, timeInfo->tm_min,
+                                timeInfo->tm_sec, mCount);
+            return result;
+        }
+
+    private:
+        time_t mTs; // timestamp of the error
+        int mCount;   // number of transport errors observed
+    };
+
     ssize_t getSensorList(sensor_t const** list);
 
     void handleDynamicSensorConnection(int handle, bool connected);
@@ -125,6 +154,10 @@
     };
     DefaultKeyedVector<int, Info> mActivationCount;
 
+    // Keep track of any hidl transport failures
+    SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors;
+    int mTotalHidlTransportErrors;
+
     // Use this vector to determine which client is activated or deactivated.
     SortedVector<void *> mDisabledClients;
     SensorDevice();
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
new file mode 100644
index 0000000..f00c297
--- /dev/null
+++ b/services/sensorservice/hidl/Android.bp
@@ -0,0 +1,28 @@
+cc_library_shared {
+    name: "libsensorservicehidl",
+    srcs: [
+        "DirectReportChannel.cpp",
+        "SensorManager.cpp",
+        "utils.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libutils",
+        "libsensor",
+        "android.frameworks.sensorservice@1.0",
+        "android.hardware.sensors@1.0",
+        "android.hidl.base@1.0",
+    ],
+    export_include_dirs: [
+        "include/"
+    ],
+    local_include_dirs: [
+        "include/sensorservicehidl/"
+    ]
+}
diff --git a/services/sensorservice/hidl/DirectReportChannel.cpp b/services/sensorservice/hidl/DirectReportChannel.cpp
new file mode 100644
index 0000000..9caba47
--- /dev/null
+++ b/services/sensorservice/hidl/DirectReportChannel.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#include "DirectReportChannel.h"
+#include "utils.h"
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+DirectReportChannel::DirectReportChannel(::android::SensorManager& manager, int channelId)
+        : mManager(manager), mId(channelId) {}
+
+DirectReportChannel::~DirectReportChannel() {
+    mManager.destroyDirectChannel(mId);
+}
+
+// Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
+Return<Result> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate) {
+    return convertResult(mManager.configureDirectChannel(mId,
+            static_cast<int>(sensorHandle), static_cast<int>(rate)));
+}
+
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
diff --git a/services/sensorservice/hidl/DirectReportChannel.h b/services/sensorservice/hidl/DirectReportChannel.h
new file mode 100644
index 0000000..f4cd4e7
--- /dev/null
+++ b/services/sensorservice/hidl/DirectReportChannel.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_DIRECTREPORTCHANNEL_H
+#define ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_DIRECTREPORTCHANNEL_H
+
+#include <android/frameworks/sensorservice/1.0/IDirectReportChannel.h>
+#include <android/frameworks/sensorservice/1.0/types.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::frameworks::sensorservice::V1_0::IDirectReportChannel;
+using ::android::hardware::sensors::V1_0::RateLevel;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct DirectReportChannel : public IDirectReportChannel {
+
+    DirectReportChannel(::android::SensorManager& manager, int channelId);
+    ~DirectReportChannel();
+
+    // Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
+    Return<Result> configure(int32_t sensorHandle, RateLevel rate) override;
+
+private:
+    ::android::SensorManager& mManager;
+    const int mId;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
+
+#endif  // ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_DIRECTREPORTCHANNEL_H
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
new file mode 100644
index 0000000..b55efb0
--- /dev/null
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+// LOG_TAG defined via build flag.
+#ifndef LOG_TAG
+#define LOG_TAG "HidlSensorManager"
+#endif
+#include <android-base/logging.h>
+
+#include "DirectReportChannel.h"
+#include "SensorManager.h"
+#include "utils.h"
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::frameworks::sensorservice::V1_0::IDirectReportChannel;
+using ::android::hardware::sensors::V1_0::SensorInfo;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Void;
+using ::android::sp;
+
+SensorManager::SensorManager()
+        : mManager{::android::SensorManager::getInstanceForPackage(
+            String16(ISensorManager::descriptor))} {
+}
+
+// Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
+Return<void> SensorManager::getSensorList(getSensorList_cb _hidl_cb) {
+    ::android::Sensor const* const* list;
+    ssize_t count = mManager.getSensorList(&list);
+    if (count < 0 || !list) {
+        LOG(ERROR) << "::android::SensorManager::getSensorList encounters " << count;
+        _hidl_cb({}, Result::UNKNOWN_ERROR);
+        return Void();
+    }
+    hidl_vec<SensorInfo> ret;
+    ret.resize(static_cast<size_t>(count));
+    for (ssize_t i = 0; i < count; ++i) {
+        ret[i] = convertSensor(*list[i]);
+    }
+    _hidl_cb(ret, Result::OK);
+    return Void();
+}
+
+Return<void> SensorManager::getDefaultSensor(SensorType type, getDefaultSensor_cb _hidl_cb) {
+    ::android::Sensor const* sensor = mManager.getDefaultSensor(static_cast<int>(type));
+    if (!sensor) {
+        _hidl_cb({}, Result::NOT_EXIST);
+        return Void();
+    }
+    _hidl_cb(convertSensor(*sensor), Result::OK);
+    return Void();
+}
+
+template<typename Callback>
+void createDirectChannel(::android::SensorManager& manager, size_t size, int type,
+        const native_handle_t* handle, const Callback& _hidl_cb) {
+
+    int channelId = manager.createDirectChannel(
+        size, type, handle);
+    if (channelId < 0) {
+        _hidl_cb(nullptr, convertResult(channelId));
+        return;
+    }
+    if (channelId == 0) {
+        _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+        return;
+    }
+
+    _hidl_cb(sp<IDirectReportChannel>(new DirectReportChannel(manager, channelId)),
+            Result::OK);
+}
+
+Return<void> SensorManager::createAshmemDirectChannel(
+        const hidl_memory& mem, uint64_t size,
+        createAshmemDirectChannel_cb _hidl_cb) {
+    if (size > mem.size()) {
+        _hidl_cb(nullptr, Result::BAD_VALUE);
+        return Void();
+    }
+
+    createDirectChannel(mManager, size, SENSOR_DIRECT_MEM_TYPE_ASHMEM,
+            mem.handle(), _hidl_cb);
+
+    return Void();
+}
+
+Return<void> SensorManager::createGrallocDirectChannel(
+        const hidl_handle& buffer, uint64_t size,
+        createGrallocDirectChannel_cb _hidl_cb) {
+
+    createDirectChannel(mManager, size, SENSOR_DIRECT_MEM_TYPE_GRALLOC,
+            buffer.getNativeHandle(), _hidl_cb);
+
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
new file mode 100644
index 0000000..484e624
--- /dev/null
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_SENSORMANAGER_H
+#define ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_SENSORMANAGER_H
+
+#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
+#include <android/frameworks/sensorservice/1.0/types.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::sensors::V1_0::SensorType;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::Return;
+
+struct SensorManager : public ISensorManager {
+
+    SensorManager();
+
+    // Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
+    Return<void> getSensorList(getSensorList_cb _hidl_cb) override;
+    Return<void> getDefaultSensor(SensorType type, getDefaultSensor_cb _hidl_cb) override;
+    Return<void> createAshmemDirectChannel(const hidl_memory& mem, uint64_t size, createAshmemDirectChannel_cb _hidl_cb) override;
+    Return<void> createGrallocDirectChannel(const hidl_handle& buffer, uint64_t size, createGrallocDirectChannel_cb _hidl_cb) override;
+
+private:
+    ::android::SensorManager& mManager;
+
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
+
+#endif  // ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_SENSORMANAGER_H
diff --git a/services/sensorservice/hidl/utils.cpp b/services/sensorservice/hidl/utils.cpp
new file mode 100644
index 0000000..4e02741
--- /dev/null
+++ b/services/sensorservice/hidl/utils.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#include "utils.h"
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::Sensor;
+using ::android::hardware::hidl_string;
+using ::android::hardware::sensors::V1_0::SensorInfo;
+
+SensorInfo convertSensor(const Sensor &src) {
+    SensorInfo dst;
+    const String8& name = src.getName();
+    const String8& vendor = src.getVendor();
+    dst.name = hidl_string{name.string(), name.size()};
+    dst.vendor = hidl_string{vendor.string(), vendor.size()};
+    dst.version = src.getVersion();
+    dst.sensorHandle = src.getHandle();
+    dst.type = static_cast<::android::hardware::sensors::V1_0::SensorType>(
+            src.getType());
+    // FIXME maxRange uses maxValue because ::android::Sensor wraps the
+    // internal sensor_t in this way.
+    dst.maxRange = src.getMaxValue();
+    dst.resolution = src.getResolution();
+    dst.power = src.getPowerUsage();
+    dst.minDelay = src.getMinDelay();
+    dst.fifoReservedEventCount = src.getFifoReservedEventCount();
+    dst.fifoMaxEventCount = src.getFifoMaxEventCount();
+    dst.typeAsString = src.getStringType();
+    dst.requiredPermission = src.getRequiredPermission();
+    dst.maxDelay = src.getMaxDelay();
+    dst.flags = src.getFlags();
+    return dst;
+}
+
+Result convertResult(status_t status) {
+    switch (status) {
+        case OK:
+            return Result::OK;
+        case NAME_NOT_FOUND:
+            return Result::NOT_EXIST;
+        case NO_MEMORY:
+            return Result::NO_MEMORY;
+        case NO_INIT:
+            return Result::NO_INIT;
+        case BAD_VALUE:
+            return Result::BAD_VALUE;
+        case INVALID_OPERATION:
+            return Result::INVALID_OPERATION;
+        default:
+            return Result::UNKNOWN_ERROR;
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
diff --git a/services/sensorservice/hidl/utils.h b/services/sensorservice/hidl/utils.h
new file mode 100644
index 0000000..0606e69
--- /dev/null
+++ b/services/sensorservice/hidl/utils.h
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_UTILS_H
+#define ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_UTILS_H
+
+#include <android/frameworks/sensorservice/1.0/types.h>
+#include <android/hardware/sensors/1.0/types.h>
+#include <hidl/HidlSupport.h>
+#include <sensor/Sensor.h>
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace V1_0 {
+namespace implementation {
+
+::android::hardware::sensors::V1_0::SensorInfo convertSensor(const ::android::Sensor &src);
+Result convertResult(status_t status);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace sensorservice
+}  // namespace frameworks
+}  // namespace android
+
+#endif  // ANDROID_FRAMEWORKS_SENSORSERVICE_V1_0_UTILS_H
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index ad5955a..a6ea750 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -65,30 +65,10 @@
         DisplayHardware/HWComposer_hwc1.cpp
 endif
 
-ifeq ($(TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS),true)
-    LOCAL_CFLAGS += -DFORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS
-endif
-
 ifneq ($(NUM_FRAMEBUFFER_SURFACE_BUFFERS),)
     LOCAL_CFLAGS += -DNUM_FRAMEBUFFER_SURFACE_BUFFERS=$(NUM_FRAMEBUFFER_SURFACE_BUFFERS)
 endif
 
-ifeq ($(TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK),true)
-    LOCAL_CFLAGS += -DRUNNING_WITHOUT_SYNC_FRAMEWORK
-endif
-
-ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
-    LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=$(PRESENT_TIME_OFFSET_FROM_VSYNC_NS)
-else
-    LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=0
-endif
-
-ifneq ($(MAX_VIRTUAL_DISPLAY_DIMENSION),)
-    LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=$(MAX_VIRTUAL_DISPLAY_DIMENSION)
-else
-    LOCAL_CFLAGS += -DMAX_VIRTUAL_DISPLAY_DIMENSION=0
-endif
-
 LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
 
 LOCAL_HEADER_LIBRARIES := \
@@ -205,3 +185,5 @@
 
 include $(BUILD_SHARED_LIBRARY)
 endif # libnativehelper
+
+include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index 86cf17d..bd9b8aa 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -33,6 +33,7 @@
 #include <ui/Fence.h>
 
 #include "DispSync.h"
+#include "SurfaceFlinger.h"
 #include "EventLog/EventLog.h"
 
 using std::max;
@@ -54,10 +55,6 @@
 // present time and the nearest software-predicted vsync.
 static const nsecs_t kErrorThreshold = 160000000000;    // 400 usec squared
 
-// This is the offset from the present fence timestamps to the corresponding
-// vsync event.
-static const int64_t kPresentTimeOffset = PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
-
 #undef LOG_TAG
 #define LOG_TAG "DispSyncThread"
 class DispSyncThread: public Thread {
@@ -219,7 +216,8 @@
         return BAD_VALUE;
     }
 
-    // This method is only here to handle the kIgnorePresentFences case.
+    // This method is only here to handle the !SurfaceFlinger::hasSyncFramework
+    // case.
     bool hasAnyEventListeners() {
         if (kTraceDetailedInfo) ATRACE_CALL();
         Mutex::Autolock lock(mMutex);
@@ -379,8 +377,10 @@
 DispSync::DispSync(const char* name) :
         mName(name),
         mRefreshSkipCount(0),
-        mThread(new DispSyncThread(name)) {
+        mThread(new DispSyncThread(name)),
+        mIgnorePresentFences(!SurfaceFlinger::hasSyncFramework){
 
+    mPresentTimeOffset = SurfaceFlinger::dispSyncPresentTimeOffset;
     mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
     // set DispSync to SCHED_FIFO to minimize jitter
     struct sched_param param = {0};
@@ -399,7 +399,7 @@
         // Even if we're just ignoring the fences, the zero-phase tracing is
         // not needed because any time there is an event registered we will
         // turn on the HW vsync events.
-        if (!kIgnorePresentFences && kEnableZeroPhaseTracer) {
+        if (!mIgnorePresentFences && kEnableZeroPhaseTracer) {
             addEventListener("ZeroPhaseTracer", 0, new ZeroPhaseTracer());
         }
     }
@@ -433,7 +433,7 @@
             nsecs_t t = f->getSignalTime();
             if (t < INT64_MAX) {
                 mPresentFences[i].clear();
-                mPresentTimes[i] = t + kPresentTimeOffset;
+                mPresentTimes[i] = t + mPresentTimeOffset;
             }
         }
     }
@@ -478,7 +478,7 @@
         resetErrorLocked();
     }
 
-    if (kIgnorePresentFences) {
+    if (mIgnorePresentFences) {
         // If we don't have the sync framework we will never have
         // addPresentFence called.  This means we have no way to know whether
         // or not we're synchronized with the HW vsyncs, so we just request
@@ -643,7 +643,7 @@
 void DispSync::dump(String8& result) const {
     Mutex::Autolock lock(mMutex);
     result.appendFormat("present fences are %s\n",
-            kIgnorePresentFences ? "ignored" : "used");
+            mIgnorePresentFences ? "ignored" : "used");
     result.appendFormat("mPeriod: %" PRId64 " ns (%.3f fps; skipCount=%d)\n",
             mPeriod, 1000000000.0 / mPeriod, mRefreshSkipCount);
     result.appendFormat("mPhase: %" PRId64 " ns\n", mPhase);
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index 2763e59..82ae795 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -25,15 +25,6 @@
 
 namespace android {
 
-// Ignore present (retire) fences if the device doesn't have support for the
-// sync framework
-#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK)
-static const bool kIgnorePresentFences = true;
-#else
-static const bool kIgnorePresentFences = false;
-#endif
-
-
 class String8;
 class Fence;
 class DispSyncThread;
@@ -182,6 +173,14 @@
 
     // mMutex is used to protect access to all member variables.
     mutable Mutex mMutex;
+
+    // This is the offset from the present fence timestamps to the corresponding
+    // vsync event.
+    int64_t mPresentTimeOffset;
+
+    // Ignore present (retire) fences if the device doesn't have support for the
+    // sync framework
+    bool mIgnorePresentFences;
 };
 
 }
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 9af4402..11df4e2 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -118,6 +118,9 @@
     mNativeWindow = surface = new Surface(producer, false);
     ANativeWindow* const window = mNativeWindow.get();
 
+#ifdef USE_HWC2
+    mActiveColorMode = static_cast<android_color_mode_t>(-1);
+#endif
     /*
      * Create our display's surface
      */
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6644bd9..23b7a45 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -267,12 +267,12 @@
         return NO_MEMORY;
     }
 
-    if (MAX_VIRTUAL_DISPLAY_DIMENSION != 0 &&
-        (width > MAX_VIRTUAL_DISPLAY_DIMENSION ||
-         height > MAX_VIRTUAL_DISPLAY_DIMENSION)) {
+    if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
+        (width > SurfaceFlinger::maxVirtualDisplaySize ||
+         height > SurfaceFlinger::maxVirtualDisplaySize)) {
         ALOGE("createVirtualDisplay: Can't create a virtual display with"
-                      " a dimension > %u (tried %u x %u)",
-              MAX_VIRTUAL_DISPLAY_DIMENSION, width, height);
+                      " a dimension > %" PRIu64 " (tried %u x %u)",
+              SurfaceFlinger::maxVirtualDisplaySize, width, height);
         return INVALID_OPERATION;
     }
 
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 6f253ab..8217540 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -17,6 +17,7 @@
 // #define LOG_NDEBUG 0
 #include "VirtualDisplaySurface.h"
 #include "HWComposer.h"
+#include "SurfaceFlinger.h"
 
 #include <gui/BufferItem.h>
 #include <gui/BufferQueue.h>
@@ -26,12 +27,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-#if defined(FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS)
-static const bool sForceHwcCopy = true;
-#else
-static const bool sForceHwcCopy = false;
-#endif
-
 #define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \
         mDisplayName.string(), ##__VA_ARGS__)
 #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \
@@ -74,7 +69,8 @@
     mOutputProducerSlot(BufferQueue::INVALID_BUFFER_SLOT),
     mDbgState(DBG_STATE_IDLE),
     mDbgLastCompositionType(COMPOSITION_UNKNOWN),
-    mMustRecompose(false)
+    mMustRecompose(false),
+    mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv)
 {
     mSource[SOURCE_SINK] = sink;
     mSource[SOURCE_SCRATCH] = bqProducer;
@@ -137,7 +133,7 @@
     mDbgState = DBG_STATE_PREPARED;
 
     mCompositionType = compositionType;
-    if (sForceHwcCopy && mCompositionType == COMPOSITION_GLES) {
+    if (mForceHwcCopy && mCompositionType == COMPOSITION_GLES) {
         // Some hardware can do RGB->YUV conversion more efficiently in hardware
         // controlled by HWC than in hardware controlled by the video encoder.
         // Forcing GLES-composed frames to go through an extra copy by the HWC
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index ee2772a..5c0e084 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -255,6 +255,9 @@
 #ifdef USE_HWC2
     HWComposerBufferCache mHwcBufferCache;
 #endif
+
+
+    bool mForceHwcCopy;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 295b229..861a7d9 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -760,9 +760,7 @@
 
     mHwcLayers[hwcId].forceClientComposition = true;
 }
-#endif
 
-#ifdef USE_HWC2
 void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
     // Apply this display's projection's viewport to the visible region
     // before giving it to the HWC HAL.
@@ -865,6 +863,10 @@
                 static_cast<int32_t>(error));
     }
 }
+
+android_dataspace Layer::getDataSpace() const {
+    return mCurrentState.dataSpace;
+}
 #else
 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6b228b0..afe6074 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -261,6 +261,8 @@
     void forceClientComposition(int32_t hwcId);
     void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
 
+    android_dataspace getDataSpace() const;
+
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
     void setCompositionType(int32_t hwcId, HWC2::Composition type,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b93de7e..06dd903 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -99,6 +99,7 @@
 
 namespace android {
 
+
 using namespace android::hardware::configstore;
 using namespace android::hardware::configstore::V1_0;
 
@@ -113,6 +114,10 @@
 int64_t SurfaceFlinger::vsyncPhaseOffsetNs;
 int64_t SurfaceFlinger::sfVsyncPhaseOffsetNs;
 bool SurfaceFlinger::useContextPriority;
+int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
+bool SurfaceFlinger::useHwcForRgbToYuv;
+uint64_t SurfaceFlinger::maxVirtualDisplaySize;
+bool SurfaceFlinger::hasSyncFramework;
 
 SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(),
@@ -156,6 +161,7 @@
         ,mEnterVrMode(false)
 #endif
 {
+    ALOGI("SurfaceFlinger is starting");
 
     vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
@@ -163,11 +169,21 @@
     sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
 
-    ALOGI("SurfaceFlinger is starting");
+    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
 
     useContextPriority = getBool< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::useContextPriority>(false);
 
+    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
+
+    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
+
+    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
+
     // debugging stuff...
     char value[PROPERTY_VALUE_MAX];
 
@@ -1113,7 +1129,7 @@
 }
 
 void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
-    std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
     *compositorTiming = mCompositorTiming;
 }
 
@@ -1410,34 +1426,39 @@
         mCompositePresentTimes.pop();
     }
 
+    setCompositorTimingSnapped(
+            vsyncPhase, vsyncInterval, compositeToPresentLatency);
+}
+
+void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
+        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
     // Integer division and modulo round toward 0 not -inf, so we need to
     // treat negative and positive offsets differently.
-    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ?
+    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
             (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
             ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
 
+    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
+    if (idealLatency <= 0) {
+        idealLatency = vsyncInterval;
+    }
+
     // Snap the latency to a value that removes scheduling jitter from the
     // composition and present times, which often have >1ms of jitter.
     // Reducing jitter is important if an app attempts to extrapolate
     // something (such as user input) to an accurate diasplay time.
     // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
     // with (presentLatency % interval).
-    nsecs_t snappedCompositeToPresentLatency = -1;
-    if (compositeToPresentLatency >= 0) {
-        nsecs_t bias = vsyncInterval / 2;
-        int64_t extraVsyncs =
-                (compositeToPresentLatency - idealLatency + bias) /
-                vsyncInterval;
-        nsecs_t extraLatency = extraVsyncs * vsyncInterval;
-        snappedCompositeToPresentLatency = idealLatency + extraLatency;
-    }
+    nsecs_t bias = vsyncInterval / 2;
+    int64_t extraVsyncs =
+            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
+    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
+            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
 
-    std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
     mCompositorTiming.deadline = vsyncPhase - idealLatency;
     mCompositorTiming.interval = vsyncInterval;
-    if (snappedCompositeToPresentLatency >= 0) {
-        mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
-    }
+    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
 void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
@@ -1484,10 +1505,15 @@
     // since updateCompositorTiming has snapping logic.
     updateCompositorTiming(
         vsyncPhase, vsyncInterval, refreshStartTime, displayFenceTime);
+    CompositorTiming compositorTiming;
+    {
+        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
+        compositorTiming = mCompositorTiming;
+    }
 
     mDrawingState.traverseInZOrder([&](Layer* layer) {
         bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
-                *presentFenceTime, *retireFenceTime, mCompositorTiming);
+                *presentFenceTime, *retireFenceTime, compositorTiming);
         if (frameLatched) {
             recordBufferingStats(layer->getName().string(),
                     layer->getOccupancyHistory(false));
@@ -1502,7 +1528,7 @@
         }
     }
 
-    if (kIgnorePresentFences) {
+    if (!hasSyncFramework) {
         if (hw->isDisplayOn()) {
             enableHardwareVsync();
         }
@@ -2966,10 +2992,9 @@
     const nsecs_t period = activeConfig->getVsyncPeriod();
     mAnimFrameTracker.setDisplayRefreshPeriod(period);
 
-    {
-        std::lock_guard<std::mutex> lock(mCompositeTimingLock);
-        mCompositorTiming.interval = period;
-    }
+    // Use phase of 0 since phase is not known.
+    // Use latency of 0, which will snap to the ideal latency.
+    setCompositorTimingSnapped(0, period, 0);
 }
 
 void SurfaceFlinger::initializeDisplays() {
@@ -3232,6 +3257,11 @@
 
     if (isLayerTripleBufferingDisabled())
         result.append(" DISABLE_TRIPLE_BUFFERING");
+
+    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64 , dispSyncPresentTimeOffset);
+    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
+    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
+    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
     result.append("]");
 }
 
@@ -3358,9 +3388,9 @@
     result.append("DispSync configuration: ");
     colorizer.reset(result);
     result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
-            "present offset %d ns (refresh %" PRId64 " ns)",
+            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
         vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
-        PRESENT_TIME_OFFSET_FROM_VSYNC_NS, activeConfig->getVsyncPeriod());
+        dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
     result.append("\n");
 
     // Dump static screen stats
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index bfe0c9c..921ecf6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -105,7 +105,6 @@
 {
 public:
 
-
     // This is the phase offset in nanoseconds of the software vsync event
     // relative to the vsync event reported by HWComposer.  The software vsync
     // event is when SurfaceFlinger and Choreographer-based applications run each
@@ -129,9 +128,26 @@
     static int64_t vsyncPhaseOffsetNs;
     static int64_t sfVsyncPhaseOffsetNs;
 
+    // If fences from sync Framework are supported.
+    static bool hasSyncFramework;
+
     // Instruct the Render Engine to use EGL_IMG_context_priority is available.
     static bool useContextPriority;
 
+    // The offset in nanoseconds to use when DispSync timestamps present fence
+    // signaling time.
+    static int64_t dispSyncPresentTimeOffset;
+
+    // Some hardware can do RGB->YUV conversion more efficiently in hardware
+    // controlled by HWC than in hardware controlled by the video encoder.
+    // This instruct VirtualDisplaySurface to use HWC for such conversion on
+    // GL composition.
+    static bool useHwcForRgbToYuv;
+
+    // Maximum dimension supported by HWC for virtual display.
+    // Equal to min(max_height, max_width).
+    static uint64_t maxVirtualDisplaySize;
+
     static char const* getServiceName() ANDROID_API {
         return "SurfaceFlinger";
     }
@@ -450,6 +466,9 @@
     void updateCompositorTiming(
             nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime,
             std::shared_ptr<FenceTime>& presentFenceTime);
+    void setCompositorTimingSnapped(
+            nsecs_t vsyncPhase, nsecs_t vsyncInterval,
+            nsecs_t compositeToPresentLatency);
     void rebuildLayerStacks();
     void setUpHWComposer();
     void doComposition();
@@ -620,7 +639,7 @@
     bool mHWVsyncAvailable;
 
     // protected by mCompositorTimingLock;
-    mutable std::mutex mCompositeTimingLock;
+    mutable std::mutex mCompositorTimingLock;
     CompositorTiming mCompositorTiming;
 
     // Only accessed from the main thread.
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index 01226e0..1d2b485 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -179,7 +179,7 @@
     const nsecs_t nextRefresh = dispSync.computeNextRefresh(hwcLatency);
 
     // The DispSync time is already adjusted for the difference between
-    // vsync and reported-vsync (PRESENT_TIME_OFFSET_FROM_VSYNC_NS), so
+    // vsync and reported-vsync (SurfaceFlinger::dispSyncPresentTimeOffset), so
     // we don't need to factor that in here.  Pad a little to avoid
     // weird effects if apps might be requesting times right on the edge.
     nsecs_t extraPadding = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index c567e61..e8147cf 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -112,6 +112,10 @@
 int64_t SurfaceFlinger::vsyncPhaseOffsetNs;
 int64_t SurfaceFlinger::sfVsyncPhaseOffsetNs;
 bool SurfaceFlinger::useContextPriority;
+int64_t SurfaceFlinger::dispSyncPresentTimeOffset;
+bool SurfaceFlinger::useHwcForRgbToYuv;
+uint64_t SurfaceFlinger::maxVirtualDisplaySize;
+bool SurfaceFlinger::hasSyncFramework;
 
 SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(),
@@ -148,17 +152,29 @@
         mLastSwapTime(0),
         mNumLayers(0)
 {
+    ALOGI("SurfaceFlinger is starting");
+
     vsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::vsyncEventPhaseOffsetNs>(1000000);
 
     sfVsyncPhaseOffsetNs = getInt64< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::vsyncSfEventPhaseOffsetNs>(1000000);
 
-    ALOGI("SurfaceFlinger is starting");
+    maxVirtualDisplaySize = getUInt64<ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::maxVirtualDisplaySize>(0);
+
+    hasSyncFramework = getBool< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::hasSyncFramework>(true);
 
     useContextPriority = getBool< ISurfaceFlingerConfigs,
             &ISurfaceFlingerConfigs::useContextPriority>(false);
 
+    dispSyncPresentTimeOffset = getInt64< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::presentTimeOffsetFromVSyncNs>(0);
+
+    useHwcForRgbToYuv = getBool< ISurfaceFlingerConfigs,
+            &ISurfaceFlingerConfigs::useHwcForRGBtoYUV>(false);
+
     char value[PROPERTY_VALUE_MAX];
 
     property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
@@ -1032,7 +1048,7 @@
 }
 
 void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
-    std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
     *compositorTiming = mCompositorTiming;
 }
 
@@ -1195,34 +1211,39 @@
         mCompositePresentTimes.pop();
     }
 
+    setCompositorTimingSnapped(
+            vsyncPhase, vsyncInterval, compositeToPresentLatency);
+}
+
+void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase,
+        nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) {
     // Integer division and modulo round toward 0 not -inf, so we need to
     // treat negative and positive offsets differently.
-    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ?
+    nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ?
             (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) :
             ((-sfVsyncPhaseOffsetNs) % vsyncInterval);
 
+    // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval.
+    if (idealLatency <= 0) {
+        idealLatency = vsyncInterval;
+    }
+
     // Snap the latency to a value that removes scheduling jitter from the
     // composition and present times, which often have >1ms of jitter.
     // Reducing jitter is important if an app attempts to extrapolate
     // something (such as user input) to an accurate diasplay time.
     // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs
     // with (presentLatency % interval).
-    nsecs_t snappedCompositeToPresentLatency = -1;
-    if (compositeToPresentLatency >= 0) {
-        nsecs_t bias = vsyncInterval / 2;
-        int64_t extraVsyncs =
-                (compositeToPresentLatency - idealLatency + bias) /
-                vsyncInterval;
-        nsecs_t extraLatency = extraVsyncs * vsyncInterval;
-        snappedCompositeToPresentLatency = idealLatency + extraLatency;
-    }
+    nsecs_t bias = vsyncInterval / 2;
+    int64_t extraVsyncs =
+            (compositeToPresentLatency - idealLatency + bias) / vsyncInterval;
+    nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ?
+            idealLatency + (extraVsyncs * vsyncInterval) : idealLatency;
 
-    std::lock_guard<std::mutex> lock(mCompositeTimingLock);
+    std::lock_guard<std::mutex> lock(mCompositorTimingLock);
     mCompositorTiming.deadline = vsyncPhase - idealLatency;
     mCompositorTiming.interval = vsyncInterval;
-    if (snappedCompositeToPresentLatency >= 0) {
-        mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
-    }
+    mCompositorTiming.presentLatency = snappedCompositeToPresentLatency;
 }
 
 void SurfaceFlinger::postComposition(nsecs_t refreshStartTime)
@@ -1254,10 +1275,15 @@
     // since updateCompositorTiming has snapping logic.
     updateCompositorTiming(
         vsyncPhase, vsyncInterval, refreshStartTime, retireFenceTime);
+    CompositorTiming compositorTiming;
+    {
+        std::lock_guard<std::mutex> lock(mCompositorTimingLock);
+        compositorTiming = mCompositorTiming;
+    }
 
     mDrawingState.traverseInZOrder([&](Layer* layer) {
         bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime,
-                presentFenceTime, retireFenceTime, mCompositorTiming);
+                presentFenceTime, retireFenceTime, compositorTiming);
         if (frameLatched) {
             recordBufferingStats(layer->getName().string(),
                     layer->getOccupancyHistory(false));
@@ -1272,7 +1298,7 @@
         }
     }
 
-    if (kIgnorePresentFences) {
+    if (!hasSyncFramework) {
         if (hw->isDisplayOn()) {
             enableHardwareVsync();
         }
@@ -1693,9 +1719,9 @@
                             ALOGE_IF(status != NO_ERROR,
                                     "Unable to query height (%d)", status);
                             if (mUseHwcVirtualDisplays &&
-                                    (MAX_VIRTUAL_DISPLAY_DIMENSION == 0 ||
-                                    (width <= MAX_VIRTUAL_DISPLAY_DIMENSION &&
-                                     height <= MAX_VIRTUAL_DISPLAY_DIMENSION))) {
+                                    (SurfaceFlinger::maxVirtualDisplaySize == 0 ||
+                                    (width <= static_cast<int>(SurfaceFlinger::maxVirtualDisplaySize) &&
+                                     height <= static_cast<int>(SurfaceFlinger::maxVirtualDisplaySize)))) {
                                 hwcDisplayId = allocateHwcDisplayId(state.type);
                             }
 
@@ -2742,6 +2768,10 @@
     const nsecs_t period =
             getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
     mAnimFrameTracker.setDisplayRefreshPeriod(period);
+
+    // Use phase of 0 since phase is not known.
+    // Use latency of 0, which will snap to the ideal latency.
+    setCompositorTimingSnapped(0, period, 0);
 }
 
 void SurfaceFlinger::initializeDisplays() {
@@ -3004,6 +3034,11 @@
 
     if (isLayerTripleBufferingDisabled())
         result.append(" DISABLE_TRIPLE_BUFFERING");
+
+    result.appendFormat(" PRESENT_TIME_OFFSET=%" PRId64, dispSyncPresentTimeOffset);
+    result.appendFormat(" FORCE_HWC_FOR_RBG_TO_YUV=%d", useHwcForRgbToYuv);
+    result.appendFormat(" MAX_VIRT_DISPLAY_DIM=%" PRIu64, maxVirtualDisplaySize);
+    result.appendFormat(" RUNNING_WITHOUT_SYNC_FRAMEWORK=%d", !hasSyncFramework);
     result.append("]");
 }
 
@@ -3127,8 +3162,8 @@
     result.append("DispSync configuration: ");
     colorizer.reset(result);
     result.appendFormat("app phase %" PRId64 " ns, sf phase %" PRId64 " ns, "
-            "present offset %d ns (refresh %" PRId64 " ns)",
-        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, PRESENT_TIME_OFFSET_FROM_VSYNC_NS,
+            "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
+        vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, dispSyncPresentTimeOffset,
         mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY));
     result.append("\n");
 
diff --git a/services/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk
index f93d918..f46ce8a 100644
--- a/services/surfaceflinger/tests/Android.mk
+++ b/services/surfaceflinger/tests/Android.mk
@@ -8,8 +8,9 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_SRC_FILES := \
-    Transaction_test.cpp \
-    SurfaceInterceptor_test.cpp
+   Transaction_test.cpp \
+   Stress_test.cpp \
+   SurfaceInterceptor_test.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libEGL \
@@ -20,6 +21,7 @@
     libprotobuf-cpp-full \
     libui \
     libutils \
+    libandroid \
     liblog
 
 LOCAL_STATIC_LIBRARIES := libtrace_proto
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
new file mode 100644
index 0000000..33dd2f5
--- /dev/null
+++ b/services/surfaceflinger/tests/Stress_test.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <gui/SurfaceComposerClient.h>
+
+#include <utils/String8.h>
+
+#include <thread>
+#include <functional>
+
+
+namespace android {
+
+TEST(SurfaceFlingerStress, create_and_destroy) {
+    auto do_stress = []() {
+        sp<SurfaceComposerClient> client = new SurfaceComposerClient;
+        ASSERT_EQ(NO_ERROR, client->initCheck());
+        for (int j = 0; j < 1000; j++) {
+            auto surf = client->createSurface(String8("t"), 100, 100,
+                    PIXEL_FORMAT_RGBA_8888, 0);
+            ASSERT_TRUE(surf != nullptr);
+            client->destroySurface(surf->getHandle());
+        }
+    };
+
+    std::vector<std::thread> threads;
+    for (int i = 0; i < 10; i++) {
+        threads.push_back(std::thread(do_stress));
+    }
+    for (auto& thread : threads) {
+        thread.join();
+    }
+}
+
+}
diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
index 1a3f89f..0cc763c 100644
--- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
+++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <frameworks/native/cmds/surfacereplayer/proto/src/trace.pb.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
 
 #include <gtest/gtest.h>
 
@@ -68,11 +69,18 @@
 }
 
 static status_t readProtoFile(Trace* trace) {
-    std::ifstream input(DEFAULT_FILENAME, std::ios::in | std::ios::binary);
-    if (input && !trace->ParseFromIstream(&input)) {
-        return PERMISSION_DENIED;
+    status_t err = NO_ERROR;
+
+    int fd = open(DEFAULT_FILENAME, O_RDONLY);
+    {
+        google::protobuf::io::FileInputStream f(fd);
+        if (fd && !trace->ParseFromZeroCopyStream(&f)) {
+            err = PERMISSION_DENIED;
+        }
     }
-    return NO_ERROR;
+    close(fd);
+
+    return err;
 }
 
 static void enableInterceptor() {
diff --git a/services/vr/Android.bp b/services/vr/Android.bp
index af8212a..80df479 100644
--- a/services/vr/Android.bp
+++ b/services/vr/Android.bp
@@ -1,3 +1,3 @@
 subdirs = [
-  "*/*",
+  "*",
 ]
diff --git a/services/vr/sensord/Android.mk b/services/vr/sensord/Android.mk
index f86664e..f9a1cec 100644
--- a/services/vr/sensord/Android.mk
+++ b/services/vr/sensord/Android.mk
@@ -30,7 +30,7 @@
 
 staticLibraries := \
 	libdvrcommon \
-	libsensor \
+	libvrsensor \
 	libperformance \
 	libbufferhub \
 	libpdx_default_transport \
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
new file mode 100644
index 0000000..ad999b7
--- /dev/null
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -0,0 +1,116 @@
+
+
+// Touchpad implementation.
+
+src = [
+    "EvdevInjector.cpp",
+    "VirtualTouchpadEvdev.cpp",
+]
+
+shared_libs = [
+    "libbase",
+    "liblog",
+    "libutils",
+]
+
+cc_library {
+    srcs: src,
+    export_include_dirs: ["include"],
+    shared_libs: shared_libs,
+    cppflags: ["-std=c++11"],
+    cflags: ["-DLOG_TAG=\"VrVirtualTouchpad\""],
+    name: "libvirtualtouchpad",
+    tags: ["optional"],
+}
+
+// Touchpad unit tests.
+
+test_static_libs = [
+    "libcutils",
+    "libvirtualtouchpad",
+]
+
+test_shared_libs = [
+    "libbase",
+    "liblog",
+    "libutils",
+]
+
+test_src_files = ["tests/VirtualTouchpad_test.cpp"]
+
+cc_test {
+    srcs: test_src_files,
+    static_libs: test_static_libs,
+    shared_libs: test_shared_libs,
+    cppflags = [
+        "-std=c++11",
+    ],
+    host_ldlibs = [
+        "-llog",
+    ],
+    name: "VirtualTouchpad_test",
+    stl: "libc++_static",
+    tags: [ "optional" ],
+}
+
+// Service.
+
+service_src = [
+    "main.cpp",
+    "VirtualTouchpadService.cpp",
+    "aidl/android/dvr/VirtualTouchpadService.aidl",
+]
+
+service_static_libs = [
+    "libcutils",
+    "libvirtualtouchpad",
+]
+
+service_shared_libs = [
+    "libbase",
+    "libbinder",
+    "liblog",
+    "libutils",
+]
+
+cc_binary {
+    srcs: service_src,
+    static_libs: service_static_libs,
+    shared_libs: service_shared_libs,
+    cppflags: ["-std=c++11"],
+    cflags: [
+        "-DLOG_TAG=\"VrVirtualTouchpad\"",
+        "-DSELINUX_ACCESS_CONTROL",
+    ],
+    host_ldlibs: ["-llog"],
+    name: "virtual_touchpad",
+    tags: ["optional"],
+    init_rc: ["virtual_touchpad.rc"],
+    compile_multilib: "64",
+    stl: "libc++_static",
+}
+
+// Touchpad client library.
+
+client_src = [
+    "VirtualTouchpadClient.cpp",
+    "aidl/android/dvr/VirtualTouchpadService.aidl",
+]
+
+client_shared_libs = [
+    "libbase",
+    "libbinder",
+    "liblog",
+    "libutils",
+]
+
+cc_library {
+    srcs: client_src,
+    shared_libs: client_shared_libs,
+    cppflags: ["-std=c++11"],
+    cflags: ["-DLOG_TAG=\"VirtualTouchpadClient\""],
+    host_ldlibs: ["-llog"],
+    name: "libvirtualtouchpadclient",
+    tags: ["optional"],
+    export_include_dirs: ["include"],
+}
diff --git a/services/vr/virtual_touchpad/Android.mk b/services/vr/virtual_touchpad/Android.mk
deleted file mode 100644
index 88b2dd9..0000000
--- a/services/vr/virtual_touchpad/Android.mk
+++ /dev/null
@@ -1,107 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-
-# Touchpad implementation.
-
-src := \
-  EvdevInjector.cpp \
-  VirtualTouchpadEvdev.cpp
-
-shared_libs := \
-  libbase \
-  libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(src)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CPPFLAGS += -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"VrVirtualTouchpad\"
-LOCAL_MODULE := libvirtualtouchpad
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_STATIC_LIBRARY)
-
-
-# Touchpad unit tests.
-
-test_static_libs := \
-  libbase \
-  libcutils \
-  libvirtualtouchpad
-
-test_shared_libs := \
-  libutils
-
-test_src_files := \
-  tests/VirtualTouchpad_test.cpp
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_C_INCLUDES := $(LOCAL_PATH)/include) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(test_static_libs)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(test_shared_libs)) \
-    $(eval LOCAL_CPPFLAGS += -std=c++11) \
-    $(eval LOCAL_LDLIBS := -llog) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval LOCAL_MODULE_TAGS := optional) \
-    $(eval LOCAL_CXX_STL := libc++_static) \
-    $(eval include $(BUILD_NATIVE_TEST)) \
-)
-
-
-# Service.
-
-src := \
-  main.cpp \
-  VirtualTouchpadService.cpp \
-  aidl/android/dvr/VirtualTouchpadService.aidl
-
-static_libs := \
-  libcutils \
-  libvirtualtouchpad
-
-shared_libs := \
-  libbase \
-  libbinder \
-  libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(src)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_STATIC_LIBRARIES := $(static_libs)
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CPPFLAGS += -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"VrVirtualTouchpad\" -DSELINUX_ACCESS_CONTROL
-LOCAL_LDLIBS := -llog
-LOCAL_MODULE := virtual_touchpad
-LOCAL_MODULE_TAGS := optional
-LOCAL_INIT_RC := virtual_touchpad.rc
-LOCAL_MULTILIB := 64
-LOCAL_CXX_STL := libc++_static
-include $(BUILD_EXECUTABLE)
-
-
-# Touchpad client library.
-
-src := \
-  VirtualTouchpadClient.cpp \
-  aidl/android/dvr/VirtualTouchpadService.aidl
-
-shared_libs := \
-  libbase \
-  libbinder \
-  libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(src)
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CPPFLAGS += -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"VirtualTouchpadClient\"
-LOCAL_LDLIBS := -llog
-LOCAL_MODULE := libvirtualtouchpadclient
-LOCAL_MODULE_TAGS := optional
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-include $(BUILD_STATIC_LIBRARY)
diff --git a/services/vr/vr_window_manager/Android.bp b/services/vr/vr_window_manager/Android.bp
new file mode 100644
index 0000000..a7a341c
--- /dev/null
+++ b/services/vr/vr_window_manager/Android.bp
@@ -0,0 +1,103 @@
+// Copyright (C) 2016 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.
+
+subdirs = [ "composer", ]
+
+native_src = [
+    "application.cpp",
+    "controller_mesh.cpp",
+    "elbow_model.cpp",
+    "hwc_callback.cpp",
+    "reticle.cpp",
+    "shell_view.cpp",
+    "surface_flinger_view.cpp",
+    "texture.cpp",
+    "vr_window_manager.cpp",
+    "vr_window_manager_binder.cpp",
+    "aidl/android/service/vr/IVrWindowManager.aidl",
+    "display_view.cpp",
+]
+
+static_libs = [
+    "libdisplay",
+    "libbufferhub",
+    "libbufferhubqueue",
+    "libeds",
+    "libdvrgraphics",
+    "libdvrcommon",
+    "libhwcomposer-client",
+    "libvrsensor",
+    "libperformance",
+    "libpdx_default_transport",
+    "libcutils",
+    "libvr_manager",
+    "libvirtualtouchpadclient",
+]
+
+shared_libs = [
+    "android.dvr.composer@1.0",
+    "android.hardware.graphics.composer@2.1",
+    "libvrhwc",
+    "libbase",
+    "libbinder",
+    "libinput",
+    "libhardware",
+    "libhwbinder",
+    "libsync",
+    "libutils",
+    "libgui",
+    "libEGL",
+    "libGLESv2",
+    "libvulkan",
+    "libsync",
+    "libui",
+    "libhidlbase",
+    "libhidltransport",
+    "liblog",
+]
+
+cc_binary {
+    srcs: native_src,
+    static_libs: static_libs,
+    shared_libs: shared_libs,
+    cflags: ["-DGL_GLEXT_PROTOTYPES", "-DEGL_EGLEXT_PROTOTYPES", "-DLOG_TAG=\"VrWindowManager\""],
+    host_ldlibs: ["-llog"],
+    name: "vr_wm",
+    tags: ["optional"],
+    init_rc: ["vr_wm.rc"],
+}
+
+cmd_src = [
+    "vr_wm_ctl.cpp",
+    "aidl/android/service/vr/IVrWindowManager.aidl",
+]
+
+staticLibs = ["libcutils"]
+
+sharedLibs = [
+    "libbase",
+    "libbinder",
+    "libutils",
+]
+
+cc_binary {
+    srcs: cmd_src,
+    static_libs: staticLibs,
+    shared_libs: sharedLibs,
+    cppflags: ["-std=c++11"],
+    cflags: ["-DLOG_TAG=\"vrwmctl\""],
+    host_ldlibs: ["-llog"],
+    name: "vr_wm_ctl",
+    tags: ["optional"],
+}
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
deleted file mode 100644
index 59ef63c..0000000
--- a/services/vr/vr_window_manager/Android.mk
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-native_src := \
-  application.cpp \
-  controller_mesh.cpp \
-  display_view.cpp \
-  elbow_model.cpp \
-  hwc_callback.cpp \
-  reticle.cpp \
-  shell_view.cpp \
-  surface_flinger_view.cpp \
-  texture.cpp \
-  vr_window_manager.cpp \
-  vr_window_manager_binder.cpp \
-  aidl/android/service/vr/IVrWindowManager.aidl
-
-static_libs := \
-  libdisplay \
-  libbufferhub \
-  libbufferhubqueue \
-  libeds \
-  libdvrgraphics \
-  libdvrcommon \
-  libhwcomposer-client \
-  libsensor \
-  libperformance \
-  libpdx_default_transport \
-  libcutils \
-  libvr_manager \
-  libvirtualtouchpadclient
-
-shared_libs := \
-  android.dvr.composer@1.0 \
-  android.hardware.graphics.composer@2.1 \
-  libvrhwc \
-  libbase \
-  libbinder \
-  libinput \
-  libhardware \
-  libhwbinder \
-  libsync \
-  libutils \
-  libgui \
-  libEGL \
-  libGLESv2 \
-  libvulkan \
-  libsync \
-  libui \
-  libhidlbase \
-  libhidltransport
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(native_src)
-LOCAL_STATIC_LIBRARIES := $(static_libs)
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
-LOCAL_CFLAGS += -DEGL_EGLEXT_PROTOTYPES
-LOCAL_CFLAGS += -DLOG_TAG=\"VrWindowManager\"
-LOCAL_LDLIBS := -llog
-LOCAL_MODULE := vr_wm
-LOCAL_MODULE_TAGS := optional
-LOCAL_INIT_RC := vr_wm.rc
-include $(BUILD_EXECUTABLE)
-
-cmd_src := \
-  vr_wm_ctl.cpp \
-  aidl/android/service/vr/IVrWindowManager.aidl
-
-static_libs := \
-  libcutils
-
-shared_libs := \
-  libbase \
-  libbinder \
-  libutils
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(cmd_src)
-LOCAL_STATIC_LIBRARIES := $(static_libs)
-LOCAL_SHARED_LIBRARIES := $(shared_libs)
-LOCAL_CPPFLAGS += -std=c++11
-LOCAL_CFLAGS += -DLOG_TAG=\"vrwmctl\"
-LOCAL_LDLIBS := -llog
-LOCAL_MODULE := vr_wm_ctl
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
diff --git a/services/vr/vr_window_manager/composer/Android.bp b/services/vr/vr_window_manager/composer/Android.bp
index 7c8bb86..4349269 100644
--- a/services/vr/vr_window_manager/composer/Android.bp
+++ b/services/vr/vr_window_manager/composer/Android.bp
@@ -13,6 +13,10 @@
 
   static_libs: [
     "libhwcomposer-client",
+    "libdisplay",
+    "libpdx_default_transport",
+    "libbufferhub",
+    "libbufferhubqueue",
   ],
 
   shared_libs: [
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index 8b50c01..60ca818 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -21,6 +21,8 @@
 
 #include <mutex>
 
+#include <private/dvr/display_client.h>
+
 #include "vr_composer_client.h"
 
 using namespace android::hardware::graphics::common::V1_0;
diff --git a/services/vr/vr_window_manager/hwc_callback.cpp b/services/vr/vr_window_manager/hwc_callback.cpp
index b755c60..2d2a85c 100644
--- a/services/vr/vr_window_manager/hwc_callback.cpp
+++ b/services/vr/vr_window_manager/hwc_callback.cpp
@@ -41,6 +41,7 @@
 base::unique_fd HwcCallback::OnNewFrame(const ComposerView::Frame& display_frame) {
   auto& frame = display_frame.layers;
   std::vector<HwcLayer> hwc_frame(frame.size());
+
   for (size_t i = 0; i < frame.size(); ++i) {
     hwc_frame[i] = HwcLayer{
       .fence = frame[i].fence,
diff --git a/services/vr/vr_window_manager/surface_flinger_view.cpp b/services/vr/vr_window_manager/surface_flinger_view.cpp
index 2011967..8411806 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.cpp
+++ b/services/vr/vr_window_manager/surface_flinger_view.cpp
@@ -1,6 +1,7 @@
 #include "surface_flinger_view.h"
 
 #include <impl/vr_composer_view.h>
+#include <private/dvr/display_client.h>
 #include <private/dvr/native_buffer.h>
 
 #include "hwc_callback.h"
@@ -38,7 +39,7 @@
   vr_composer_view_->Initialize(GetComposerViewFromIComposer(
       vr_hwcomposer_.get()));
 
-  // TODO(dnicoara): Query this from the composer service.
+  // TODO(alexst): Refactor ShellView to account for orientation and change this back.
   width_ = 1920;
   height_ = 1080;
   return true;
diff --git a/vulkan/Android.bp b/vulkan/Android.bp
index 3f077a2..3fd8c51 100644
--- a/vulkan/Android.bp
+++ b/vulkan/Android.bp
@@ -23,7 +23,7 @@
     license: "include/vulkan/NOTICE",
 }
 
-cc_library_static {
+cc_library_headers {
     name: "vulkan_headers",
     export_include_dirs: ["include"],
 }
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index b4708b0..86dd001 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -320,6 +320,10 @@
 @extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
 @extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
 
+// 119
+@extension("VK_KHR_get_surface_capabilities2") define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
+@extension("VK_KHR_get_surface_capabilities2") define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
+
 // 123
 @extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_SPEC_VERSION 1
 @extension("VK_MVK_ios_surface") define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface"
@@ -1082,6 +1086,14 @@
     //@extension("VK_EXT_hdr_metadata") // 106
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT                          = 1000105000,
 
+    //@extension("VK_KHR_shared_presentable_image") // 111
+    VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR   = 1000111000,
+
+    //@extension("VK_KHR_get_surface_capabilities2") // 119
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR        = 1000119000,
+    VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR                = 1000119001,
+    VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR                      = 1000119002,
+
     //@extension("VK_MVK_ios_surface") // 123
     VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK               = 1000122000,
 
@@ -4245,6 +4257,34 @@
     f32                                             maxFrameAverageLightLevel
 }
 
+@extension("VK_KHR_shared_presentable_image") // 111
+class VkSharedPresentSurfaceCapabilitiesKHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkImageUsageFlags                               sharedPresentSupportedUsageFlags
+}
+
+@extension("VK_KHR_get_surface_capabilities2") // 119
+class VkPhysicalDeviceSurfaceInfo2KHR {
+    VkStructureType                                 sType
+    const void*                                     pNext
+    VkSurfaceKHR                                    surface
+}
+
+@extension("VK_KHR_get_surface_capabilities2") // 119
+class VkSurfaceCapabilities2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkSurfaceCapabilitiesKHR                        surfaceCapabilities
+}
+
+@extension("VK_KHR_get_surface_capabilities2") // 119
+class VkSurfaceFormat2KHR {
+    VkStructureType                                 sType
+    void*                                           pNext
+    VkSurfaceFormatKHR                              surfaceFormat
+}
+
 @extension("VK_MVK_ios_surface") // 123
 class VkIOSSurfaceCreateInfoMVK {
     VkStructureType                                 sType
@@ -7418,6 +7458,23 @@
     return ?
 }
 
+@extension("VK_KHR_get_surface_capabilities2") // 119
+cmd VkResult vkGetPhysicalDeviceSurfaceCapabilities2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+        VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities) {
+    return ?
+}
+
+@extension("VK_KHR_get_surface_capabilities2") // 119
+cmd VkResult vkGetPhysicalDeviceSurfaceFormats2KHR(
+        VkPhysicalDevice                            physicalDevice,
+        const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+        u32*                                        pSurfaceFormatCount,
+        VkSurfaceFormat2KHR*                        pSurfaceFormats) {
+    return ?
+}
+
 @extension("VK_MVK_ios_surface") // 123
 cmd VkResult vkCreateIOSSurfaceMVK(
         VkInstance                                  instance,
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index 8bb5448..4b3b8bf 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -301,6 +301,10 @@
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
     VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
     VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
+    VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
+    VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
+    VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
     VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
     VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
     VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
@@ -3302,14 +3306,14 @@
     VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
     VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001,
     VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002,
-    VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104003,
-    VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104004,
-    VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104005,
-    VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104006,
-    VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104007,
-    VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104008,
-    VK_COLOR_SPACE_BT2020_170M_EXT = 1000104009,
-    VK_COLOR_SPACE_BT2020_ST2084_EXT = 1000104010,
+    VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104003,
+    VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004,
+    VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005,
+    VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006,
+    VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007,
+    VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008,
+    VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009,
+    VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010,
     VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
     VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
     VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013,
@@ -5766,6 +5770,13 @@
 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
 #define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
 
+typedef struct VkSharedPresentSurfaceCapabilitiesKHR {
+    VkStructureType      sType;
+    void*                pNext;
+    VkImageUsageFlags    sharedPresentSupportedUsageFlags;
+} VkSharedPresentSurfaceCapabilitiesKHR;
+
+
 typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain);
 
 #ifndef VK_NO_PROTOTYPES
@@ -5774,6 +5785,46 @@
     VkSwapchainKHR                              swapchain);
 #endif
 
+#define VK_KHR_get_surface_capabilities2 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
+
+typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
+    VkStructureType    sType;
+    const void*        pNext;
+    VkSurfaceKHR       surface;
+} VkPhysicalDeviceSurfaceInfo2KHR;
+
+typedef struct VkSurfaceCapabilities2KHR {
+    VkStructureType             sType;
+    void*                       pNext;
+    VkSurfaceCapabilitiesKHR    surfaceCapabilities;
+} VkSurfaceCapabilities2KHR;
+
+typedef struct VkSurfaceFormat2KHR {
+    VkStructureType       sType;
+    void*                 pNext;
+    VkSurfaceFormatKHR    surfaceFormat;
+} VkSurfaceFormat2KHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+    VkSurfaceCapabilities2KHR*                  pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR(
+    VkPhysicalDevice                            physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR*      pSurfaceInfo,
+    uint32_t*                                   pSurfaceFormatCount,
+    VkSurfaceFormat2KHR*                        pSurfaceFormats);
+#endif
+
+
 
 #ifdef VK_USE_PLATFORM_IOS_MVK
 #define VK_MVK_ios_surface 1
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 524de75..2fe880a 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -64,8 +64,8 @@
         "vulkan_loader_data.cpp",
     ],
 
-    export_static_lib_headers: ["vulkan_headers"],
-    static_libs: [
+    export_header_lib_headers: ["vulkan_headers"],
+    header_libs: [
         "vulkan_headers",
     ],
     shared_libs: [
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index 69e38de..54c77f1 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -110,7 +110,7 @@
 
 // clang-format on
 
-}  // anonymous
+}  // namespace
 
 bool InitDispatchTable(
     VkInstance instance,
@@ -473,7 +473,9 @@
         "vkGetPhysicalDeviceQueueFamilyProperties2KHR",
         "vkGetPhysicalDeviceSparseImageFormatProperties",
         "vkGetPhysicalDeviceSparseImageFormatProperties2KHR",
+        "vkGetPhysicalDeviceSurfaceCapabilities2KHR",
         "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
+        "vkGetPhysicalDeviceSurfaceFormats2KHR",
         "vkGetPhysicalDeviceSurfaceFormatsKHR",
         "vkGetPhysicalDeviceSurfacePresentModesKHR",
         "vkGetPhysicalDeviceSurfaceSupportKHR",
diff --git a/vulkan/libvulkan/api_gen.h b/vulkan/libvulkan/api_gen.h
index 7f8d274..3e50fda 100644
--- a/vulkan/libvulkan/api_gen.h
+++ b/vulkan/libvulkan/api_gen.h
@@ -19,8 +19,8 @@
 #ifndef LIBVULKAN_API_GEN_H
 #define LIBVULKAN_API_GEN_H
 
-#include <bitset>
 #include <vulkan/vulkan.h>
+#include <bitset>
 #include "driver_gen.h"
 
 namespace vulkan {
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 185121c..5bbe116 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -690,6 +690,7 @@
 VK_KHR_shared_presentable_image
 VK_KHR_surface
 VK_KHR_swapchain
+VK_KHR_get_surface_capabilities2
 {{end}}
 
 
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index b62eec6..dbb217d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -448,6 +448,7 @@
             case ProcHook::KHR_android_surface:
             case ProcHook::KHR_surface:
             case ProcHook::EXT_swapchain_colorspace:
+            case ProcHook::KHR_get_surface_capabilities2:
                 hook_extensions_.set(ext_bit);
                 // return now as these extensions do not require HAL support
                 return;
@@ -674,13 +675,15 @@
     const char* pLayerName,
     uint32_t* pPropertyCount,
     VkExtensionProperties* pProperties) {
-    static const std::array<VkExtensionProperties, 3> loader_extensions = {{
+    static const std::array<VkExtensionProperties, 4> loader_extensions = {{
         // WSI extensions
         {VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION},
         {VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
          VK_KHR_ANDROID_SURFACE_SPEC_VERSION},
         {VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
          VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION},
+        {VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
+         VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION},
     }};
     static const VkExtensionProperties loader_debug_report_extension = {
         VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index fc3f87a..82b464e 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -262,6 +262,13 @@
         reinterpret_cast<PFN_vkVoidFunction>(checkedGetPastPresentationTimingGOOGLE),
     },
     {
+        "vkGetPhysicalDeviceSurfaceCapabilities2KHR",
+        ProcHook::INSTANCE,
+        ProcHook::KHR_get_surface_capabilities2,
+        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilities2KHR),
+        nullptr,
+    },
+    {
         "vkGetPhysicalDeviceSurfaceCapabilitiesKHR",
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
@@ -269,6 +276,13 @@
         nullptr,
     },
     {
+        "vkGetPhysicalDeviceSurfaceFormats2KHR",
+        ProcHook::INSTANCE,
+        ProcHook::KHR_get_surface_capabilities2,
+        reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormats2KHR),
+        nullptr,
+    },
+    {
         "vkGetPhysicalDeviceSurfaceFormatsKHR",
         ProcHook::INSTANCE,
         ProcHook::KHR_surface,
@@ -348,7 +362,7 @@
     // clang-format on
 };
 
-}  // anonymous
+}  // namespace
 
 const ProcHook* GetProcHook(const char* name) {
     const auto& begin = g_proc_hooks;
@@ -372,6 +386,7 @@
     if (strcmp(name, "VK_KHR_shared_presentable_image") == 0) return ProcHook::KHR_shared_presentable_image;
     if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface;
     if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain;
+    if (strcmp(name, "VK_KHR_get_surface_capabilities2") == 0) return ProcHook::KHR_get_surface_capabilities2;
     if (strcmp(name, "VK_KHR_get_physical_device_properties2") == 0) return ProcHook::KHR_get_physical_device_properties2;
     // clang-format on
     return ProcHook::EXTENSION_UNKNOWN;
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 738da5b..3b26a80 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -19,9 +19,9 @@
 #ifndef LIBVULKAN_DRIVER_GEN_H
 #define LIBVULKAN_DRIVER_GEN_H
 
-#include <bitset>
-#include <vulkan/vulkan.h>
 #include <vulkan/vk_android_native_buffer.h>
+#include <vulkan/vulkan.h>
+#include <bitset>
 
 namespace vulkan {
 namespace driver {
@@ -43,6 +43,7 @@
         KHR_shared_presentable_image,
         KHR_surface,
         KHR_swapchain,
+        KHR_get_surface_capabilities2,
         KHR_get_physical_device_properties2,
 
         EXTENSION_CORE,  // valid bit
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 7e96b4c..f7695ea 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -411,8 +411,6 @@
             return HAL_DATASPACE_DISPLAY_P3;
         case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
             return HAL_DATASPACE_V0_SCRGB_LINEAR;
-        case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
-            return HAL_DATASPACE_V0_SCRGB;
         case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
             return HAL_DATASPACE_DCI_P3_LINEAR;
         case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
@@ -421,14 +419,20 @@
             return HAL_DATASPACE_V0_SRGB_LINEAR;
         case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
             return HAL_DATASPACE_V0_SRGB;
-        case VK_COLOR_SPACE_BT2020_170M_EXT:
-            return static_cast<android_dataspace>(
-                HAL_DATASPACE_STANDARD_BT2020 |
-                HAL_DATASPACE_TRANSFER_SMPTE_170M | HAL_DATASPACE_RANGE_FULL);
-        case VK_COLOR_SPACE_BT2020_ST2084_EXT:
+        case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
+            return HAL_DATASPACE_BT2020_LINEAR;
+        case VK_COLOR_SPACE_HDR10_ST2084_EXT:
             return static_cast<android_dataspace>(
                 HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
                 HAL_DATASPACE_RANGE_FULL);
+        case VK_COLOR_SPACE_DOLBYVISION_EXT:
+            return static_cast<android_dataspace>(
+                HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
+                HAL_DATASPACE_RANGE_FULL);
+        case VK_COLOR_SPACE_HDR10_HLG_EXT:
+            return static_cast<android_dataspace>(
+                HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
+                HAL_DATASPACE_RANGE_FULL);
         case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
             return static_cast<android_dataspace>(
                 HAL_DATASPACE_STANDARD_ADOBE_RGB |
@@ -649,6 +653,72 @@
 }
 
 VKAPI_ATTR
+VkResult GetPhysicalDeviceSurfaceCapabilities2KHR(
+    VkPhysicalDevice physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+    VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
+    VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR(
+        physicalDevice, pSurfaceInfo->surface,
+        &pSurfaceCapabilities->surfaceCapabilities);
+
+    VkSurfaceCapabilities2KHR* caps = pSurfaceCapabilities;
+    while (caps->pNext) {
+        caps = reinterpret_cast<VkSurfaceCapabilities2KHR*>(caps->pNext);
+
+        switch (caps->sType) {
+            case VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR: {
+                VkSharedPresentSurfaceCapabilitiesKHR* shared_caps =
+                    reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>(
+                        caps);
+                // Claim same set of usage flags are supported for
+                // shared present modes as for other modes.
+                shared_caps->sharedPresentSupportedUsageFlags =
+                    pSurfaceCapabilities->surfaceCapabilities
+                        .supportedUsageFlags;
+            } break;
+
+            default:
+                // Ignore all other extension structs
+                break;
+        }
+    }
+
+    return result;
+}
+
+VKAPI_ATTR
+VkResult GetPhysicalDeviceSurfaceFormats2KHR(
+    VkPhysicalDevice physicalDevice,
+    const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+    uint32_t* pSurfaceFormatCount,
+    VkSurfaceFormat2KHR* pSurfaceFormats) {
+    if (!pSurfaceFormats) {
+        return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
+                                                  pSurfaceInfo->surface,
+                                                  pSurfaceFormatCount, nullptr);
+    } else {
+        // temp vector for forwarding; we'll marshal it into the pSurfaceFormats
+        // after the call.
+        android::Vector<VkSurfaceFormatKHR> surface_formats;
+        surface_formats.resize(*pSurfaceFormatCount);
+        VkResult result = GetPhysicalDeviceSurfaceFormatsKHR(
+            physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount,
+            &surface_formats.editItemAt(0));
+
+        if (result == VK_SUCCESS || result == VK_INCOMPLETE) {
+            // marshal results individually due to stride difference.
+            // completely ignore any chained extension structs.
+            uint32_t formats_to_marshal = *pSurfaceFormatCount;
+            for (uint32_t i = 0u; i < formats_to_marshal; i++) {
+                pSurfaceFormats[i].surfaceFormat = surface_formats[i];
+            }
+        }
+
+        return result;
+    }
+}
+
+VKAPI_ATTR
 VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev,
                                                  VkSurfaceKHR /*surface*/,
                                                  uint32_t* count,
diff --git a/vulkan/libvulkan/swapchain.h b/vulkan/libvulkan/swapchain.h
index 976c995..e3cf624 100644
--- a/vulkan/libvulkan/swapchain.h
+++ b/vulkan/libvulkan/swapchain.h
@@ -38,6 +38,8 @@
 VKAPI_ATTR VkResult GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings);
 VKAPI_ATTR VkResult GetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain);
 VKAPI_ATTR void SetHdrMetadataEXT(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pHdrMetadataEXTs);
+VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
 // clang-format on
 
 }  // namespace driver
diff --git a/vulkan/nulldrv/Android.bp b/vulkan/nulldrv/Android.bp
index ea3b781..3329609 100644
--- a/vulkan/nulldrv/Android.bp
+++ b/vulkan/nulldrv/Android.bp
@@ -42,6 +42,6 @@
         "null_driver_gen.cpp",
     ],
 
-    static_libs: ["vulkan_headers"],
+    header_libs: ["vulkan_headers"],
     shared_libs: ["liblog"],
 }
diff --git a/vulkan/nulldrv/null_driver_gen.cpp b/vulkan/nulldrv/null_driver_gen.cpp
index 7cbbdb1..25ee65a 100644
--- a/vulkan/nulldrv/null_driver_gen.cpp
+++ b/vulkan/nulldrv/null_driver_gen.cpp
@@ -16,8 +16,8 @@
 
 // WARNING: This file is generated. See ../README.md for instructions.
 
-#include "null_driver_gen.h"
 #include <algorithm>
+#include "null_driver_gen.h"
 
 using namespace null_driver;