Merge "Move AHardwareBuffer_getNativeHandle to VNDK" into oc-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 3e0f6f0..989fcda 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -395,7 +395,9 @@
         }
 
         // Consider restorecon over contents if label changed
-        if (restorecon_app_data_lazy(path, seInfo, uid, existing)) {
+        if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
+                restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
+                restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
             return error("Failed to restorecon " + path);
         }
 
@@ -617,11 +619,9 @@
         ATRACE_BEGIN("fixup user");
         FTS* fts;
         FTSENT* p;
-        char *argv[] = {
-                (char*) create_data_user_ce_path(uuid_, user).c_str(),
-                (char*) create_data_user_de_path(uuid_, user).c_str(),
-                nullptr
-        };
+        auto ce_path = create_data_user_ce_path(uuid_, user);
+        auto de_path = create_data_user_de_path(uuid_, user);
+        char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(), nullptr };
         if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
             return error("Failed to fts_open");
         }
@@ -950,11 +950,9 @@
         for (auto user : get_known_users(uuid_)) {
             FTS *fts;
             FTSENT *p;
-            char *argv[] = {
-                    (char*) create_data_user_ce_path(uuid_, user).c_str(),
-                    (char*) create_data_user_de_path(uuid_, user).c_str(),
-                    nullptr
-            };
+            auto ce_path = create_data_user_ce_path(uuid_, user);
+            auto de_path = create_data_user_de_path(uuid_, user);
+            char *argv[] = { (char*) ce_path.c_str(), (char*) de_path.c_str(), nullptr };
             if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) {
                 return error("Failed to fts_open");
             }
@@ -1395,12 +1393,16 @@
             collectManualStats(dePath, &stats);
             ATRACE_END();
 
-            ATRACE_BEGIN("profiles");
-            auto userProfilePath = create_primary_current_profile_package_dir_path(userId, pkgname);
-            calculate_tree_size(userProfilePath, &stats.dataSize);
-            auto refProfilePath = create_primary_reference_profile_package_dir_path(pkgname);
-            calculate_tree_size(refProfilePath, &stats.codeSize);
-            ATRACE_END();
+            if (!uuid) {
+                ATRACE_BEGIN("profiles");
+                calculate_tree_size(
+                        create_primary_current_profile_package_dir_path(userId, pkgname),
+                        &stats.dataSize);
+                calculate_tree_size(
+                        create_primary_reference_profile_package_dir_path(pkgname),
+                        &stats.codeSize);
+                ATRACE_END();
+            }
 
             ATRACE_BEGIN("external");
             auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
@@ -1410,15 +1412,15 @@
             ATRACE_END();
         }
 
-        ATRACE_BEGIN("dalvik");
-        int32_t sharedGid = multiuser_get_shared_gid(userId, appId);
-        if (sharedGid != -1) {
-            calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
-                    sharedGid, -1);
+        if (!uuid) {
+            ATRACE_BEGIN("dalvik");
+            int32_t sharedGid = multiuser_get_shared_gid(userId, appId);
+            if (sharedGid != -1) {
+                calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
+                        sharedGid, -1);
+            }
+            ATRACE_END();
         }
-        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
-                multiuser_get_uid(userId, appId), -1);
-        ATRACE_END();
     }
 
     std::vector<int64_t> ret;
@@ -1496,12 +1498,14 @@
         collectManualStatsForUser(dePath, &stats, true);
         ATRACE_END();
 
-        ATRACE_BEGIN("profile");
-        auto userProfilePath = create_primary_cur_profile_dir_path(userId);
-        calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
-        auto refProfilePath = create_primary_ref_profile_dir_path();
-        calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
-        ATRACE_END();
+        if (!uuid) {
+            ATRACE_BEGIN("profile");
+            auto userProfilePath = create_primary_cur_profile_dir_path(userId);
+            calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true);
+            auto refProfilePath = create_primary_ref_profile_dir_path();
+            calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
+            ATRACE_END();
+        }
 
         ATRACE_BEGIN("external");
         uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
@@ -1518,12 +1522,14 @@
         }
         ATRACE_END();
 
-        ATRACE_BEGIN("dalvik");
-        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
-                -1, -1, true);
-        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
-                -1, -1, true);
-        ATRACE_END();
+        if (!uuid) {
+            ATRACE_BEGIN("dalvik");
+            calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
+                    -1, -1, true);
+            calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize,
+                    -1, -1, true);
+            ATRACE_END();
+        }
 
         ATRACE_BEGIN("quota");
         for (auto appId : appIds) {
@@ -1554,12 +1560,14 @@
         collectManualStatsForUser(dePath, &stats);
         ATRACE_END();
 
-        ATRACE_BEGIN("profile");
-        auto userProfilePath = create_primary_cur_profile_dir_path(userId);
-        calculate_tree_size(userProfilePath, &stats.dataSize);
-        auto refProfilePath = create_primary_ref_profile_dir_path();
-        calculate_tree_size(refProfilePath, &stats.codeSize);
-        ATRACE_END();
+        if (!uuid) {
+            ATRACE_BEGIN("profile");
+            auto userProfilePath = create_primary_cur_profile_dir_path(userId);
+            calculate_tree_size(userProfilePath, &stats.dataSize);
+            auto refProfilePath = create_primary_ref_profile_dir_path();
+            calculate_tree_size(refProfilePath, &stats.codeSize);
+            ATRACE_END();
+        }
 
         ATRACE_BEGIN("external");
         auto dataMediaPath = create_data_media_path(uuid_, userId);
@@ -1570,10 +1578,12 @@
 #endif
         ATRACE_END();
 
-        ATRACE_BEGIN("dalvik");
-        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
-        calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize);
-        ATRACE_END();
+        if (!uuid) {
+            ATRACE_BEGIN("dalvik");
+            calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
+            calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize);
+            ATRACE_END();
+        }
     }
 
     std::vector<int64_t> ret;
diff --git a/data/etc/android.software.preview_sdk.xml b/data/etc/android.software.preview_sdk.xml
new file mode 100644
index 0000000..928b4b3
--- /dev/null
+++ b/data/etc/android.software.preview_sdk.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+
+<permissions>
+    <!-- The device is running a preview (i.e. unofficial) API version. -->
+    <feature name="android.software.preview_sdk" />
+</permissions>
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index b91de8f..5dc4a1b 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -109,6 +109,11 @@
     dvr_api->hwc_frame_get_display_width = dvrHwcFrameGetDisplayWidth;
     dvr_api->hwc_frame_get_display_height = dvrHwcFrameGetDisplayHeight;
     dvr_api->hwc_frame_get_display_removed = dvrHwcFrameGetDisplayRemoved;
+    dvr_api->hwc_frame_get_active_config = dvrHwcFrameGetActiveConfig;
+    dvr_api->hwc_frame_get_color_mode = dvrHwcFrameGetColorMode;
+    dvr_api->hwc_frame_get_color_transform = dvrHwcFrameGetColorTransform;
+    dvr_api->hwc_frame_get_power_mode = dvrHwcFrameGetPowerMode;
+    dvr_api->hwc_frame_get_vsync_enabled = dvrHwcFrameGetVsyncEnabled;
     dvr_api->hwc_frame_get_layer_count = dvrHwcFrameGetLayerCount;
     dvr_api->hwc_frame_get_layer_id = dvrHwcFrameGetLayerId;
     dvr_api->hwc_frame_get_layer_buffer = dvrHwcFrameGetLayerBuffer;
@@ -121,6 +126,19 @@
     dvr_api->hwc_frame_get_layer_type = dvrHwcFrameGetLayerType;
     dvr_api->hwc_frame_get_layer_application_id =
         dvrHwcFrameGetLayerApplicationId;
+    dvr_api->hwc_frame_get_layer_z_order = dvrHwcFrameGetLayerZOrder;
+    dvr_api->hwc_frame_get_layer_cursor = dvrHwcFrameGetLayerCursor;
+    dvr_api->hwc_frame_get_layer_transform = dvrHwcFrameGetLayerTransform;
+    dvr_api->hwc_frame_get_layer_dataspace = dvrHwcFrameGetLayerDataspace;
+    dvr_api->hwc_frame_get_layer_color = dvrHwcFrameGetLayerColor;
+    dvr_api->hwc_frame_get_layer_num_visible_regions =
+        dvrHwcFrameGetLayerNumVisibleRegions;
+    dvr_api->hwc_frame_get_layer_visible_region =
+        dvrHwcFrameGetLayerVisibleRegion;
+    dvr_api->hwc_frame_get_layer_num_damaged_regions =
+        dvrHwcFrameGetLayerNumDamagedRegions;
+    dvr_api->hwc_frame_get_layer_damaged_region =
+        dvrHwcFrameGetLayerDamagedRegion;
 
     return 0;
   }
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
index 39c2a90..d3ae299 100644
--- a/libs/vr/libdvr/dvr_hardware_composer_client.cpp
+++ b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
@@ -104,6 +104,29 @@
   return frame->frame.layers.size();
 }
 
+uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
+  return static_cast<uint32_t>(frame->frame.active_config);
+}
+
+uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
+  return static_cast<uint32_t>(frame->frame.color_mode);
+}
+
+void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
+                                  int32_t* out_hint) {
+  *out_hint = frame->frame.color_transform_hint;
+  memcpy(out_matrix, frame->frame.color_transform,
+         sizeof(frame->frame.color_transform));
+}
+
+uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
+  return static_cast<uint32_t>(frame->frame.power_mode);
+}
+
+uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
+  return static_cast<uint32_t>(frame->frame.vsync_enabled);
+}
+
 DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
   return frame->frame.layers[layer_index].id;
 }
@@ -157,3 +180,58 @@
                                           size_t layer_index) {
   return frame->frame.layers[layer_index].app_id;
 }
+
+uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].z_order;
+}
+
+void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
+                               int32_t* out_x, int32_t* out_y) {
+  *out_x = frame->frame.layers[layer_index].cursor_x;
+  *out_y = frame->frame.layers[layer_index].cursor_y;
+}
+
+uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].transform;
+}
+
+uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
+  return frame->frame.layers[layer_index].dataspace;
+}
+
+uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
+  const auto& color = frame->frame.layers[layer_index].color;
+  return color.r | (static_cast<uint32_t>(color.g) << 8) |
+         (static_cast<uint32_t>(color.b) << 16) |
+         (static_cast<uint32_t>(color.a) << 24);
+}
+
+uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
+                                              size_t layer_index) {
+  return frame->frame.layers[layer_index].visible_regions.size();
+}
+
+DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
+                                             size_t layer_index, size_t index) {
+  return DvrHwcRecti{
+      frame->frame.layers[layer_index].visible_regions[index].left,
+      frame->frame.layers[layer_index].visible_regions[index].top,
+      frame->frame.layers[layer_index].visible_regions[index].right,
+      frame->frame.layers[layer_index].visible_regions[index].bottom,
+  };
+}
+
+uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
+                                              size_t layer_index) {
+  return frame->frame.layers[layer_index].damaged_regions.size();
+}
+
+DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
+                                             size_t layer_index, size_t index) {
+  return DvrHwcRecti{
+      frame->frame.layers[layer_index].damaged_regions[index].left,
+      frame->frame.layers[layer_index].damaged_regions[index].top,
+      frame->frame.layers[layer_index].damaged_regions[index].right,
+      frame->frame.layers[layer_index].damaged_regions[index].bottom,
+  };
+}
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index 7dc6a30..a69433d 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -159,6 +159,13 @@
 typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
 typedef DvrHwcLayer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame,
                                                 size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetActiveConfigPtr)(DvrHwcFrame* frame);
+typedef uint32_t (*DvrHwcFrameGetColorModePtr)(DvrHwcFrame* frame);
+typedef void (*DvrHwcFrameGetColorTransformPtr)(DvrHwcFrame* frame,
+                                                float* out_matrix,
+                                                int32_t* out_hint);
+typedef uint32_t (*DvrHwcFrameGetPowerModePtr)(DvrHwcFrame* frame);
+typedef uint32_t (*DvrHwcFrameGetVsyncEnabledPtr)(DvrHwcFrame* frame);
 typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
                                                          size_t layer_index);
 typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
@@ -175,6 +182,33 @@
                                                size_t layer_index);
 typedef uint32_t (*DvrHwcFrameGetLayerApplicationIdPtr)(DvrHwcFrame* frame,
                                                         size_t layer_index);
+typedef uint32_t (*DvrHwcFrameGetLayerZOrderPtr)(DvrHwcFrame* frame,
+                                                 size_t layer_index);
+
+typedef void (*DvrHwcFrameGetLayerCursorPtr)(DvrHwcFrame* frame,
+                                             size_t layer_index, int32_t* out_x,
+                                             int32_t* out_y);
+
+typedef uint32_t (*DvrHwcFrameGetLayerTransformPtr)(DvrHwcFrame* frame,
+                                                    size_t layer_index);
+
+typedef uint32_t (*DvrHwcFrameGetLayerDataspacePtr)(DvrHwcFrame* frame,
+                                                    size_t layer_index);
+
+typedef uint32_t (*DvrHwcFrameGetLayerColorPtr)(DvrHwcFrame* frame,
+                                                size_t layer_index);
+
+typedef uint32_t (*DvrHwcFrameGetLayerNumVisibleRegionsPtr)(DvrHwcFrame* frame,
+                                                            size_t layer_index);
+typedef DvrHwcRecti (*DvrHwcFrameGetLayerVisibleRegionPtr)(DvrHwcFrame* frame,
+                                                           size_t layer_index,
+                                                           size_t index);
+
+typedef uint32_t (*DvrHwcFrameGetLayerNumDamagedRegionsPtr)(DvrHwcFrame* frame,
+                                                            size_t layer_index);
+typedef DvrHwcRecti (*DvrHwcFrameGetLayerDamagedRegionPtr)(DvrHwcFrame* frame,
+                                                           size_t layer_index,
+                                                           size_t index);
 
 struct DvrApi_v1 {
   // Display manager client
@@ -261,6 +295,11 @@
   DvrHwcFrameGetDisplayWidthPtr hwc_frame_get_display_width;
   DvrHwcFrameGetDisplayHeightPtr hwc_frame_get_display_height;
   DvrHwcFrameGetDisplayRemovedPtr hwc_frame_get_display_removed;
+  DvrHwcFrameGetActiveConfigPtr hwc_frame_get_active_config;
+  DvrHwcFrameGetColorModePtr hwc_frame_get_color_mode;
+  DvrHwcFrameGetColorTransformPtr hwc_frame_get_color_transform;
+  DvrHwcFrameGetPowerModePtr hwc_frame_get_power_mode;
+  DvrHwcFrameGetVsyncEnabledPtr hwc_frame_get_vsync_enabled;
   DvrHwcFrameGetLayerCountPtr hwc_frame_get_layer_count;
   DvrHwcFrameGetLayerIdPtr hwc_frame_get_layer_id;
   DvrHwcFrameGetLayerBufferPtr hwc_frame_get_layer_buffer;
@@ -271,6 +310,17 @@
   DvrHwcFrameGetLayerAlphaPtr hwc_frame_get_layer_alpha;
   DvrHwcFrameGetLayerTypePtr hwc_frame_get_layer_type;
   DvrHwcFrameGetLayerApplicationIdPtr hwc_frame_get_layer_application_id;
+  DvrHwcFrameGetLayerZOrderPtr hwc_frame_get_layer_z_order;
+  DvrHwcFrameGetLayerCursorPtr hwc_frame_get_layer_cursor;
+  DvrHwcFrameGetLayerTransformPtr hwc_frame_get_layer_transform;
+  DvrHwcFrameGetLayerDataspacePtr hwc_frame_get_layer_dataspace;
+  DvrHwcFrameGetLayerColorPtr hwc_frame_get_layer_color;
+  DvrHwcFrameGetLayerNumVisibleRegionsPtr
+      hwc_frame_get_layer_num_visible_regions;
+  DvrHwcFrameGetLayerVisibleRegionPtr hwc_frame_get_layer_visible_region;
+  DvrHwcFrameGetLayerNumDamagedRegionsPtr
+      hwc_frame_get_layer_num_damaged_regions;
+  DvrHwcFrameGetLayerDamagedRegionPtr hwc_frame_get_layer_damaged_region;
 };
 
 int dvrGetApi(void* api, size_t struct_size, int version);
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
index 2d28aa3..7ee7f9e 100644
--- a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
+++ b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
@@ -43,6 +43,13 @@
 // @return Number of layers in the frame.
 size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame);
 
+uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame);
+uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame);
+void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
+                                  int32_t* out_hint);
+uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame);
+uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame);
+
 DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index);
 
 // Return the graphic buffer associated with the layer at |layer_index| in
@@ -73,6 +80,26 @@
 uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
                                           size_t layer_index);
 
+uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index);
+
+void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
+                               int32_t* out_x, int32_t* out_y);
+
+uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index);
+
+uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
+                                              size_t layer_index);
+DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
+                                             size_t layer_index, size_t index);
+
+uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
+                                              size_t layer_index);
+DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
+                                             size_t layer_index, size_t index);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index b096e1c..91923b3 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -185,17 +185,18 @@
                 struct stat s1, s2;
                 int fd1, fd2;
                 fd1 = mMem.handle->data[0];
-                fd2 = mem->handle->data[1];
+                fd2 = mem->handle->data[0];
                 if (fstat(fd1, &s1) < 0 || fstat(fd2, &s2) < 0 || s1.st_ino == s2.st_ino) {
                     ret = true;
                 }
                 break;
             }
             case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
-                LOG_FATAL("%s: Implement GRALLOC or remove", __FUNCTION__);
-                ret = true;
+                // there is no known method to test if two gralloc handle are equivalent
+                ret = false;
                 break;
             default:
+                // should never happen
                 ALOGE("Unexpected mem type %d", mMem.type);
                 ret = true;
                 break;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 4d76272..26f9143 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -978,6 +978,7 @@
     for (auto &i : mDirectConnections) {
         sp<SensorDirectConnection> connection(i.promote());
         if (connection != nullptr && connection->isEquivalent(&mem)) {
+            ALOGE("Duplicate create channel request for the same share memory");
             return nullptr;
         }
     }
@@ -988,14 +989,15 @@
             int fd = resource->data[0];
             int size2 = ashmem_get_size_region(fd);
             // check size consistency
-            if (size2 != static_cast<int>(size)) {
-                ALOGE("Ashmem direct channel size mismatch, %" PRIu32 " vs %d", size, size2);
+            if (size2 < static_cast<int>(size)) {
+                ALOGE("Ashmem direct channel size %" PRIu32 " greater than shared memory size %d",
+                      size, size2);
                 return nullptr;
             }
             break;
         }
         case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
-            LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__);
+            // no specific checks for gralloc
             break;
         default:
             ALOGE("Unknown direct connection memory type %d", type);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 7314127..40979c9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -206,7 +206,7 @@
         }
         disp = DisplayDevice::DISPLAY_EXTERNAL;
     }
-    mEventHandler->onHotplugReceived(disp,
+    mEventHandler->onHotplugReceived(this, disp,
             connected == HWC2::Connection::Connected);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 81f1619..78d0307 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -70,7 +70,7 @@
         friend class HWComposer;
         virtual void onVSyncReceived(
             HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
-        virtual void onHotplugReceived(int32_t disp, bool connected) = 0;
+        virtual void onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) = 0;
         virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index 5b5f1cf..dcb2913 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -315,7 +315,7 @@
     queryDisplayProperties(disp);
     // Do not teardown or recreate the primary display
     if (disp != HWC_DISPLAY_PRIMARY) {
-        mEventHandler.onHotplugReceived(disp, bool(connected));
+        mEventHandler.onHotplugReceived(this, disp, bool(connected));
     }
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index f64d69a..4bc63bb 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -62,7 +62,7 @@
         friend class HWComposer;
         virtual void onVSyncReceived(
             HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
-        virtual void onHotplugReceived(int disp, bool connected) = 0;
+        virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected) = 0;
         virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 09a4124..746d3d9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -599,7 +599,7 @@
 
     // make the GLContext current so that we can create textures when creating
     // Layers (which may happens before we render something)
-    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
 
     mEventControlThread = new EventControlThread(this);
     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -792,10 +792,12 @@
         ALOGE("%s : display is NULL", __func__);
         return BAD_VALUE;
     }
-    sp<DisplayDevice> device(getDisplayDevice(display));
+
+    sp<const DisplayDevice> device(getDisplayDevice(display));
     if (device != NULL) {
         return device->getActiveConfig();
     }
+
     return BAD_VALUE;
 }
 
@@ -883,7 +885,7 @@
 }
 
 android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
-    sp<DisplayDevice> device(getDisplayDevice(display));
+    sp<const DisplayDevice> device(getDisplayDevice(display));
     if (device != nullptr) {
         return device->getActiveColorMode();
     }
@@ -965,7 +967,7 @@
         HdrCapabilities* outCapabilities) const {
     Mutex::Autolock _l(mStateLock);
 
-    sp<const DisplayDevice> displayDevice(getDisplayDevice(display));
+    sp<const DisplayDevice> displayDevice(getDisplayDeviceLocked(display));
     if (displayDevice == nullptr) {
         ALOGE("getHdrCapabilities: Invalid display %p", displayDevice.get());
         return BAD_VALUE;
@@ -1144,54 +1146,59 @@
     *compositorTiming = mCompositorTiming;
 }
 
-void SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
+void SurfaceFlinger::createDefaultDisplayDevice() {
+    const int32_t type = DisplayDevice::DISPLAY_PRIMARY;
+    wp<IBinder> token = mBuiltinDisplays[type];
+
+    // All non-virtual displays are currently considered secure.
+    const bool isSecure = true;
+
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
+
+    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
+
+    bool hasWideColorModes = false;
+    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
+    for (android_color_mode_t colorMode : modes) {
+        switch (colorMode) {
+            case HAL_COLOR_MODE_DISPLAY_P3:
+            case HAL_COLOR_MODE_ADOBE_RGB:
+            case HAL_COLOR_MODE_DCI_P3:
+                hasWideColorModes = true;
+                break;
+            default:
+                break;
+        }
+    }
+    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
+                                             token, fbs, producer, mRenderEngine->getEGLConfig(),
+                                             hasWideColorModes && hasWideColorDisplay);
+    mDisplays.add(token, hw);
+    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
+    if (hasWideColorModes && hasWideColorDisplay) {
+        defaultColorMode = HAL_COLOR_MODE_SRGB;
+    }
+    setActiveColorModeInternal(hw, defaultColorMode);
+}
+
+void SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) {
     ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
+
+    if (composer->isUsingVrComposer()) {
+        // We handle initializing the primary display device for the VR
+        // window manager hwc explicitly at the time of transition.
+        if (disp != DisplayDevice::DISPLAY_PRIMARY) {
+            ALOGE("External displays are not supported by the vr hardware composer.");
+        }
+        return;
+    }
+
     if (disp == DisplayDevice::DISPLAY_PRIMARY) {
         Mutex::Autolock lock(mStateLock);
-
-        // All non-virtual displays are currently considered secure.
-        bool isSecure = true;
-
-        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
-
-        // When we're using the vr composer, the assumption is that we've
-        // already created the IBinder object for the primary display.
-        if (!mHwc->isUsingVrComposer()) {
-            createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
-        }
-
-        wp<IBinder> token = mBuiltinDisplays[type];
-
-        sp<IGraphicBufferProducer> producer;
-        sp<IGraphicBufferConsumer> consumer;
-        BufferQueue::createBufferQueue(&producer, &consumer);
-
-        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
-                DisplayDevice::DISPLAY_PRIMARY, consumer);
-
-        bool hasWideColorModes = false;
-        std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
-        for (android_color_mode_t colorMode : modes) {
-            switch (colorMode) {
-                case HAL_COLOR_MODE_DISPLAY_P3:
-                case HAL_COLOR_MODE_ADOBE_RGB:
-                case HAL_COLOR_MODE_DCI_P3:
-                    hasWideColorModes = true;
-                    break;
-                default:
-                    break;
-            }
-        }
-        sp<DisplayDevice> hw =
-                new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
-                                  producer, mRenderEngine->getEGLConfig(),
-                                  hasWideColorModes && hasWideColorDisplay);
-        mDisplays.add(token, hw);
-        android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
-        if (hasWideColorModes && hasWideColorDisplay) {
-            defaultColorMode = HAL_COLOR_MODE_SRGB;
-        }
-        setActiveColorModeInternal(hw, defaultColorMode);
+        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+        createDefaultDisplayDevice();
     } else {
         auto type = DisplayDevice::DISPLAY_EXTERNAL;
         Mutex::Autolock _l(mStateLock);
@@ -1233,7 +1240,8 @@
     }
 }
 
-void SurfaceFlinger::resetHwc() {
+// Note: it is assumed the caller holds |mStateLock| when this is called
+void SurfaceFlinger::resetHwcLocked() {
     disableHardwareVsync(true);
     clearHwcLayers(mDrawingState.layersSortedByZ);
     clearHwcLayers(mCurrentState.layersSortedByZ);
@@ -1242,6 +1250,13 @@
     // mCurrentState and mDrawingState and re-apply all changes when we make the
     // transition.
     mDrawingState.displays.clear();
+    // Release virtual display hwcId during vr mode transition.
+    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
+        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
+        if (displayDevice->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL) {
+            displayDevice->disconnect(getHwComposer());
+        }
+    }
     mDisplays.clear();
     initializeDisplays();
 }
@@ -1253,36 +1268,45 @@
     if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
         return;
     }
+
     if (vrFlingerRequestsDisplay && !mVrHwc) {
         // Construct new HWComposer without holding any locks.
         mVrHwc = new HWComposer(true);
+
+        // Set up the event handlers. This step is neccessary to initialize the internal state of
+        // the hardware composer object properly. Our callbacks are designed such that if they are
+        // triggered between now and the point where the display is properly re-initialized, they
+        // will not have any effect, so this is safe to do here, before the lock is aquired.
+        mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
         ALOGV("Vr HWC created");
     }
-    {
-        Mutex::Autolock _l(mStateLock);
 
-        if (vrFlingerRequestsDisplay) {
-            resetHwc();
+    Mutex::Autolock _l(mStateLock);
 
-            mHwc = mVrHwc;
-            mVrFlinger->GrantDisplayOwnership();
-        } else {
-            mVrFlinger->SeizeDisplayOwnership();
+    if (vrFlingerRequestsDisplay) {
+        resetHwcLocked();
 
-            resetHwc();
+        mHwc = mVrHwc;
+        mVrFlinger->GrantDisplayOwnership();
 
-            mHwc = mRealHwc;
-            enableHardwareVsync();
-        }
+    } else {
+        mVrFlinger->SeizeDisplayOwnership();
 
-        mVisibleRegionsDirty = true;
-        invalidateHwcGeometry();
-        android_atomic_or(1, &mRepaintEverything);
-        setTransactionFlags(eDisplayTransactionNeeded);
+        resetHwcLocked();
+
+        mHwc = mRealHwc;
+        enableHardwareVsync();
     }
-    if (mVrHwc) {
-        mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
-    }
+
+    mVisibleRegionsDirty = true;
+    invalidateHwcGeometry();
+
+    // Explicitly re-initialize the primary display. This is because some other
+    // parts of this class rely on the primary display always being available.
+    createDefaultDisplayDevice();
+
+    android_atomic_or(1, &mRepaintEverything);
+    setTransactionFlags(eDisplayTransactionNeeded);
 }
 
 void SurfaceFlinger::onMessageReceived(int32_t what) {
@@ -1492,7 +1516,8 @@
         layer->releasePendingBuffer(dequeueReadyTime);
     }
 
-    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    // |mStateLock| not needed as we are on the main thread
+    const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
     if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
@@ -1840,7 +1865,8 @@
     mLastSwapBufferTime = systemTime() - now;
     mDebugInSwapBuffers = 0;
 
-    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
+    // |mStateLock| not needed as we are on the main thread
+    uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
     if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
         logFrameStats();
     }
@@ -1925,9 +1951,9 @@
                         // Call makeCurrent() on the primary display so we can
                         // be sure that nothing associated with this display
                         // is current.
-                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
+                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
                         defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
-                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
+                        sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
                         if (hw != NULL)
                             hw->disconnect(getHwComposer());
                         if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
@@ -1947,7 +1973,7 @@
                         // recreating the DisplayDevice, so we just remove it
                         // from the drawing state, so that it get re-added
                         // below.
-                        sp<DisplayDevice> hw(getDisplayDevice(display));
+                        sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
                         if (hw != NULL)
                             hw->disconnect(getHwComposer());
                         mDisplays.removeItem(display);
@@ -1957,7 +1983,7 @@
                         continue;
                     }
 
-                    const sp<DisplayDevice> disp(getDisplayDevice(display));
+                    const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));
                     if (disp != NULL) {
                         if (state.layerStack != draw[i].layerStack) {
                             disp->setLayerStack(state.layerStack);
@@ -2114,7 +2140,7 @@
                 // could be null when this layer is using a layerStack
                 // that is not visible on any display. Also can occur at
                 // screen off/on times.
-                disp = getDefaultDisplayDevice();
+                disp = getDefaultDisplayDeviceLocked();
             }
             layer->updateTransformHint(disp);
 
@@ -2470,7 +2496,9 @@
             ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
                   displayDevice->getDisplayName().string());
             eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
+
+            // |mStateLock| not needed as we are on the main thread
+            if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
               ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
             }
             return false;
@@ -3562,7 +3590,7 @@
     colorizer.reset(result);
 
     HWComposer& hwc(getHwComposer());
-    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     colorizer.bold(result);
     result.appendFormat("EGL implementation : %s\n",
@@ -3656,7 +3684,7 @@
         // Just use the primary display so we have something to return
         dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
     }
-    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
+    return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ();
 }
 
 bool SurfaceFlinger::startDdmConnection()
@@ -3791,7 +3819,6 @@
                 reply->writeInt32(mDebugDisableHWC);
                 return NO_ERROR;
             case 1013: {
-                Mutex::Autolock _l(mStateLock);
                 sp<const DisplayDevice> hw(getDefaultDisplayDevice());
                 reply->writeInt32(hw->getPageFlipCount());
                 return NO_ERROR;
@@ -4078,7 +4105,7 @@
         }
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
-            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
+            sp<const DisplayDevice> hw(flinger->getDisplayDeviceLocked(display));
             result = flinger->captureScreenImplLocked(hw, producer,
                     sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                     useIdentityTransform, rotation, isLocalScreenshot);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b17a5f2..c01f701 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -184,7 +184,8 @@
 
     // returns the default Display
     sp<const DisplayDevice> getDefaultDisplayDevice() const {
-        return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+        Mutex::Autolock _l(mStateLock);
+        return getDefaultDisplayDeviceLocked();
     }
 
     // utility function to delete a texture on the main thread
@@ -305,7 +306,7 @@
      * HWComposer::EventHandler interface
      */
     virtual void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp);
-    virtual void onHotplugReceived(int disp, bool connected);
+    virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected);
     virtual void onInvalidateReceived(HWComposer* composer);
 
     /* ------------------------------------------------------------------------
@@ -430,16 +431,33 @@
     // Create an IBinder for a builtin display and add it to current state
     void createBuiltinDisplayLocked(DisplayDevice::DisplayType type);
 
-    // NOTE: can only be called from the main thread or with mStateLock held
+
     sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) const {
+      Mutex::Autolock _l(mStateLock);
+      return getDisplayDeviceLocked(dpy);
+    }
+
+    sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) {
+      Mutex::Autolock _l(mStateLock);
+      return getDisplayDeviceLocked(dpy);
+    }
+
+    // NOTE: can only be called from the main thread or with mStateLock held
+    sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& dpy) const {
         return mDisplays.valueFor(dpy);
     }
 
     // NOTE: can only be called from the main thread or with mStateLock held
-    sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) {
+    sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& dpy) {
         return mDisplays.valueFor(dpy);
     }
 
+    sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const {
+        return getDisplayDeviceLocked(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+    }
+
+    void createDefaultDisplayDevice();
+
     int32_t getDisplayType(const sp<IBinder>& display) {
         if (!display.get()) return NAME_NOT_FOUND;
         for (int i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; ++i) {
@@ -547,7 +565,7 @@
      * VrFlinger
      */
     void clearHwcLayers(const LayerVector& layers);
-    void resetHwc();
+    void resetHwcLocked();
 
     // Check to see if we should handoff to vr flinger.
     void updateVrFlinger();
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 59c8b76..02923ae 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -579,7 +579,7 @@
 
     // make the GLContext current so that we can create textures when creating Layers
     // (which may happens before we render something)
-    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
 
     mEventControlThread = new EventControlThread(this);
     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -765,7 +765,7 @@
 }
 
 int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
-    sp<DisplayDevice> device(getDisplayDevice(display));
+    sp<const DisplayDevice> device(getDisplayDevice(display));
     if (device != NULL) {
         return device->getActiveConfig();
     }
@@ -1050,7 +1050,7 @@
     *compositorTiming = mCompositorTiming;
 }
 
-void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
+void SurfaceFlinger::onHotplugReceived(HWComposer* /*composer*/, int type, bool connected) {
     if (mEventThread == NULL) {
         // This is a temporary workaround for b/7145521.  A non-null pointer
         // does not mean EventThread has finished initializing, so this
@@ -1636,9 +1636,9 @@
                         // Call makeCurrent() on the primary display so we can
                         // be sure that nothing associated with this display
                         // is current.
-                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
+                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
                         defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
-                        sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
+                        sp<DisplayDevice> hw(getDisplayDeviceLocked(draw.keyAt(i)));
                         if (hw != NULL)
                             hw->disconnect(getHwComposer());
                         if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
@@ -1658,7 +1658,7 @@
                         // recreating the DisplayDevice, so we just remove it
                         // from the drawing state, so that it get re-added
                         // below.
-                        sp<DisplayDevice> hw(getDisplayDevice(display));
+                        sp<DisplayDevice> hw(getDisplayDeviceLocked(display));
                         if (hw != NULL)
                             hw->disconnect(getHwComposer());
                         mDisplays.removeItem(display);
@@ -1668,7 +1668,7 @@
                         continue;
                     }
 
-                    const sp<DisplayDevice> disp(getDisplayDevice(display));
+                    const sp<DisplayDevice> disp(getDisplayDeviceLocked(display));
                     if (disp != NULL) {
                         if (state.layerStack != draw[i].layerStack) {
                             disp->setLayerStack(state.layerStack);
@@ -1823,7 +1823,7 @@
                 // could be null when this layer is using a layerStack
                 // that is not visible on any display. Also can occur at
                 // screen off/on times.
-                disp = getDefaultDisplayDevice();
+                disp = getDefaultDisplayDeviceLocked();
             }
             layer->updateTransformHint(disp);
 
@@ -3231,7 +3231,7 @@
     colorizer.reset(result);
 
     HWComposer& hwc(getHwComposer());
-    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     colorizer.bold(result);
     result.appendFormat("EGL implementation : %s\n",
@@ -3307,7 +3307,7 @@
         // Just use the primary display so we have something to return
         dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
     }
-    return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
+    return getDisplayDeviceLocked(dpy)->getVisibleLayersSortedByZ();
 }
 
 bool SurfaceFlinger::startDdmConnection()
@@ -3722,7 +3722,7 @@
         }
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
-            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
+            sp<const DisplayDevice> hw(flinger->getDisplayDeviceLocked(display));
             result = flinger->captureScreenImplLocked(hw, producer,
                     sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                     useIdentityTransform, rotation, isLocalScreenshot);
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp
index 45eabca..db7d5dc 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp
@@ -28,6 +28,26 @@
   ret = parcel->writeBool(frame_.removed);
   if (ret != OK) return ret;
 
+  ret = parcel->writeUint32(static_cast<uint32_t>(frame_.active_config));
+  if (ret != OK) return ret;
+
+  ret = parcel->writeUint32(static_cast<uint32_t>(frame_.color_mode));
+  if (ret != OK) return ret;
+
+  ret = parcel->writeUint32(static_cast<uint32_t>(frame_.power_mode));
+  if (ret != OK) return ret;
+
+  ret = parcel->writeUint32(static_cast<uint32_t>(frame_.vsync_enabled));
+  if (ret != OK) return ret;
+
+  ret = parcel->writeInt32(frame_.color_transform_hint);
+  if (ret != OK) return ret;
+
+  for(size_t i = 0; i < 16; i++) {
+    ret = parcel->writeFloat(frame_.color_transform[i]);
+    if (ret != OK) return ret;
+  }
+
   std::vector<ParcelableComposerLayer> layers;
   for (size_t i = 0; i < frame_.layers.size(); ++i)
     layers.push_back(ParcelableComposerLayer(frame_.layers[i]));
@@ -50,6 +70,31 @@
   ret = parcel->readBool(&frame_.removed);
   if (ret != OK) return ret;
 
+  uint32_t value;
+  ret = parcel->readUint32(&value);
+  if (ret != OK) return ret;
+  frame_.active_config = static_cast<Config>(value);
+
+  ret = parcel->readUint32(&value);
+  if (ret != OK) return ret;
+  frame_.color_mode = static_cast<ColorMode>(value);
+
+  ret = parcel->readUint32(&value);
+  if (ret != OK) return ret;
+  frame_.power_mode = static_cast<IComposerClient::PowerMode>(value);
+
+  ret = parcel->readUint32(&value);
+  if (ret != OK) return ret;
+  frame_.vsync_enabled = static_cast<IComposerClient::Vsync>(value);
+
+  ret = parcel->readInt32(&frame_.color_transform_hint);
+  if (ret != OK) return ret;
+
+  for(size_t i = 0; i < 16; i++) {
+    ret = parcel->readFloat(&frame_.color_transform[i]);
+    if (ret != OK) return ret;
+  }
+
   std::vector<ParcelableComposerLayer> layers;
   ret = parcel->readParcelableVector(&layers);
   if (ret != OK) return ret;
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
index 15f63fa..c3621eb 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
@@ -66,6 +66,50 @@
   ret = parcel->writeUint32(layer_.app_id);
   if (ret != OK) return ret;
 
+  ret = parcel->writeUint32(layer_.z_order);
+  if (ret != OK) return ret;
+
+  ret = parcel->writeInt32(layer_.cursor_x);
+  if (ret != OK) return ret;
+
+  ret = parcel->writeInt32(layer_.cursor_y);
+  if (ret != OK) return ret;
+
+  uint32_t color = layer_.color.r |
+      (static_cast<uint32_t>(layer_.color.g) << 8) |
+      (static_cast<uint32_t>(layer_.color.b) << 16) |
+      (static_cast<uint32_t>(layer_.color.a) << 24);
+  ret = parcel->writeUint32(color);
+  if (ret != OK) return ret;
+
+  ret = parcel->writeInt32(layer_.dataspace);
+  if (ret != OK) return ret;
+
+  ret = parcel->writeInt32(layer_.transform);
+  if (ret != OK) return ret;
+
+  ret = parcel->writeUint32(static_cast<uint32_t>(layer_.visible_regions.size()));
+  if (ret != OK) return ret;
+
+  for (auto& rect: layer_.visible_regions) {
+    ret = parcel->writeInt32(rect.left);
+    ret = parcel->writeInt32(rect.top);
+    ret = parcel->writeInt32(rect.right);
+    ret = parcel->writeInt32(rect.bottom);
+    if (ret != OK) return ret;
+  }
+
+  ret = parcel->writeUint32(static_cast<uint32_t>(layer_.damaged_regions.size()));
+  if (ret != OK) return ret;
+
+  for (auto& rect: layer_.damaged_regions) {
+    ret = parcel->writeInt32(rect.left);
+    ret = parcel->writeInt32(rect.top);
+    ret = parcel->writeInt32(rect.right);
+    ret = parcel->writeInt32(rect.bottom);
+    if (ret != OK) return ret;
+  }
+
   return OK;
 }
 
@@ -125,6 +169,70 @@
   ret = parcel->readUint32(&layer_.app_id);
   if (ret != OK) return ret;
 
+  ret = parcel->readUint32(&layer_.z_order);
+  if (ret != OK) return ret;
+
+  ret = parcel->readInt32(&layer_.cursor_x);
+  if (ret != OK) return ret;
+
+  ret = parcel->readInt32(&layer_.cursor_y);
+  if (ret != OK) return ret;
+
+  uint32_t color;
+  ret = parcel->readUint32(&color);
+  if (ret != OK) return ret;
+  layer_.color.r = color & 0xFF;
+  layer_.color.g = (color >> 8) & 0xFF;
+  layer_.color.b = (color >> 16) & 0xFF;
+  layer_.color.a = (color >> 24) & 0xFF;
+
+  ret = parcel->readInt32(&layer_.dataspace);
+  if (ret != OK) return ret;
+
+  ret = parcel->readInt32(&layer_.transform);
+  if (ret != OK) return ret;
+
+  uint32_t size;
+  ret = parcel->readUint32(&size);
+  if (ret != OK) return ret;
+
+  for(size_t i = 0; i < size; i++) {
+    hwc_rect_t rect;
+    ret = parcel->readInt32(&rect.left);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.top);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.right);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.bottom);
+    if (ret != OK) return ret;
+
+    layer_.visible_regions.push_back(rect);
+  }
+
+  ret = parcel->readUint32(&size);
+  if (ret != OK) return ret;
+
+  for(size_t i = 0; i < size; i++) {
+    hwc_rect_t rect;
+    ret = parcel->readInt32(&rect.left);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.top);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.right);
+    if (ret != OK) return ret;
+
+    ret = parcel->readInt32(&rect.bottom);
+    if (ret != OK) return ret;
+
+    layer_.damaged_regions.push_back(rect);
+  }
+
   return OK;
 }
 
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 5efc482..f5d88f2 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -132,7 +132,7 @@
     std::vector<IComposerClient::Composition>* types) {
   std::sort(layers_.begin(), layers_.end(),
             [](const auto& lhs, const auto& rhs) {
-              return lhs.z_order < rhs.z_order;
+              return lhs.info.z_order < rhs.info.z_order;
             });
 
   int first_client_layer = -1, last_client_layer = -1;
@@ -220,6 +220,12 @@
   return last_frame_layers;
 }
 
+void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) {
+  color_transform_hint_ = hint;
+  if (matrix)
+    memcpy(color_transform_, matrix, sizeof(color_transform_));
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // VrHwcClient
 
@@ -397,40 +403,54 @@
 
 Error VrHwc::setActiveConfig(Display display, Config config) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
   if (config != kDefaultConfigId)
     return Error::BAD_CONFIG;
 
+  display_ptr->set_active_config(config);
   return Error::NONE;
 }
 
 Error VrHwc::setColorMode(Display display, ColorMode mode) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  display_ptr->set_color_mode(mode);
   return Error::NONE;
 }
 
 Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  display_ptr->set_power_mode(mode);
   return Error::NONE;
 }
 
 Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  display_ptr->set_vsync_enabled(enabled);
   return Error::NONE;
 }
 
 Error VrHwc::setColorTransform(Display display, const float* matrix,
                                int32_t hint) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  display_ptr->SetColorTransform(matrix, hint);
   return Error::NONE;
 }
 
@@ -500,6 +520,13 @@
   frame.display_id = display;
   frame.display_width = display_ptr->width();
   frame.display_height = display_ptr->height();
+  frame.active_config = display_ptr->active_config();
+  frame.power_mode = display_ptr->power_mode();
+  frame.vsync_enabled = display_ptr->vsync_enabled();
+  frame.color_transform_hint = display_ptr->color_transform_hint();
+  frame.color_mode = display_ptr->color_mode();
+  memcpy(frame.color_transform, display_ptr->color_transform(),
+         sizeof(frame.color_transform));
   if (status != Error::NONE)
     return status;
 
@@ -523,8 +550,16 @@
 Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
                                     int32_t y) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.cursor_x = x;
+  hwc_layer->info.cursor_y = y;
   return Error::NONE;
 }
 
@@ -550,8 +585,15 @@
 Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
                                    const std::vector<hwc_rect_t>& damage) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.damaged_regions = damage;
   return Error::NONE;
 }
 
@@ -574,8 +616,15 @@
 Error VrHwc::setLayerColor(Display display, Layer layer,
                            IComposerClient::Color color) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.color = color;
   return Error::NONE;
 }
 
@@ -598,8 +647,15 @@
 Error VrHwc::setLayerDataspace(Display display, Layer layer,
                                int32_t dataspace) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.dataspace = dataspace;
   return Error::NONE;
 }
 
@@ -662,16 +718,30 @@
 Error VrHwc::setLayerTransform(Display display, Layer layer,
                                int32_t transform) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.transform = transform;
   return Error::NONE;
 }
 
 Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
                                    const std::vector<hwc_rect_t>& visible) {
   std::lock_guard<std::mutex> guard(mutex_);
-  if (!FindDisplay(display))
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
     return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->info.visible_regions = visible;
   return Error::NONE;
 }
 
@@ -685,7 +755,7 @@
   if (!hwc_layer)
     return Error::BAD_LAYER;
 
-  hwc_layer->z_order = z;
+  hwc_layer->info.z_order = z;
 
   return Error::NONE;
 }
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
index 3da2fb8..609d925 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -56,8 +56,6 @@
     using BlendMode =
         hardware::graphics::composer::V2_1::IComposerClient::BlendMode;
 
-    // TODO(dnicoara): Add all layer properties. For now just the basics to get
-    // it going.
     Layer id;
     sp<GraphicBuffer> buffer;
     sp<Fence> fence;
@@ -67,6 +65,14 @@
     float alpha;
     uint32_t type;
     uint32_t app_id;
+    uint32_t z_order;
+    int32_t cursor_x;
+    int32_t cursor_y;
+    IComposerClient::Color color;
+    int32_t dataspace;
+    int32_t transform;
+    std::vector<hwc_rect_t> visible_regions;
+    std::vector<hwc_rect_t> damaged_regions;
   };
 
   struct Frame {
@@ -77,6 +83,12 @@
     bool removed = false;
     int32_t display_width;
     int32_t display_height;
+    Config active_config;
+    ColorMode color_mode;
+    IComposerClient::PowerMode power_mode;
+    IComposerClient::Vsync vsync_enabled;
+    float color_transform[16];
+    int32_t color_transform_hint;
     std::vector<ComposerLayer> layers;
   };
 
@@ -104,7 +116,6 @@
   }
 
   Composition composition_type;
-  uint32_t z_order;
   ComposerView::ComposerLayer info;
   IVrComposerClient::BufferMetadata buffer_metadata;
 };
@@ -133,6 +144,24 @@
 
   std::vector<Layer> UpdateLastFrameAndGetLastFrameLayers();
 
+  Config active_config() const { return active_config_; }
+  void set_active_config(Config config) { active_config_ = config; }
+
+  ColorMode color_mode() const { return color_mode_; }
+  void set_color_mode(ColorMode mode) { color_mode_ = mode; }
+
+  IComposerClient::PowerMode power_mode() const { return power_mode_; }
+  void set_power_mode(IComposerClient::PowerMode mode) { power_mode_ = mode; }
+
+  IComposerClient::Vsync vsync_enabled() const { return vsync_enabled_; }
+  void set_vsync_enabled(IComposerClient::Vsync vsync) {
+    vsync_enabled_ = vsync;
+  }
+
+  const float* color_transform() const { return color_transform_; }
+  int32_t color_transform_hint() const { return color_transform_hint_; }
+  void SetColorTransform(const float* matrix, int32_t hint);
+
  private:
   // The client target buffer and the associated fence.
   sp<GraphicBuffer> buffer_;
@@ -150,6 +179,13 @@
   int32_t width_;
   int32_t height_;
 
+  Config active_config_;
+  ColorMode color_mode_;
+  IComposerClient::PowerMode power_mode_;
+  IComposerClient::Vsync vsync_enabled_;
+  float color_transform_[16];
+  int32_t color_transform_hint_;
+
   HwcDisplay(const HwcDisplay&) = delete;
   void operator=(const HwcDisplay&) = delete;
 };
diff --git a/services/vr/vr_window_manager/hwc_callback.cpp b/services/vr/vr_window_manager/hwc_callback.cpp
index 43f5042..28e97ff 100644
--- a/services/vr/vr_window_manager/hwc_callback.cpp
+++ b/services/vr/vr_window_manager/hwc_callback.cpp
@@ -32,6 +32,15 @@
 
 }  // namespace
 
+void HwcCallback::HwcLayer::PrintLayer() {
+  ALOGI("appid=%d, type=%d, alpha=%.2f, cursor=%dx%d, color=%02X%02X%02X%02X, "
+      "crop=%.1f,%.1f,%.1f,%.1f, display=%d,%d,%d,%d, dataspace=%d, "
+      "transform=%d", appid, type, alpha, cursor_x, cursor_y, color.r, color.g,
+      color.b, color.a, crop.left, crop.top, crop.right, crop.bottom,
+      display_frame.left, display_frame.right, display_frame.top,
+      display_frame.bottom, dataspace, transform);
+}
+
 HwcCallback::HwcCallback(Client* client) : client_(client) {
 }
 
@@ -54,6 +63,11 @@
       .appid = layer.app_id,
       .type = static_cast<HwcLayer::LayerType>(layer.type),
       .alpha = layer.alpha,
+      .cursor_x = layer.cursor_x,
+      .cursor_y = layer.cursor_y,
+      .color = layer.color,
+      .dataspace = layer.dataspace,
+      .transform = layer.transform,
     };
   }
 
diff --git a/services/vr/vr_window_manager/hwc_callback.h b/services/vr/vr_window_manager/hwc_callback.h
index f1f91a1..4269430 100644
--- a/services/vr/vr_window_manager/hwc_callback.h
+++ b/services/vr/vr_window_manager/hwc_callback.h
@@ -65,6 +65,8 @@
       }
     }
 
+    void PrintLayer();
+
     sp<Fence> fence;
     sp<GraphicBuffer> buffer;
     Rectf crop;
@@ -73,6 +75,11 @@
     uint32_t appid;
     LayerType type;
     float alpha;
+    int32_t cursor_x;
+    int32_t cursor_y;
+    IComposerClient::Color color;
+    int32_t dataspace;
+    int32_t transform;
   };
 
   enum class FrameStatus {