Merge "dumpstate: Further cleanups related to new stack dumping scheme."
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 6f4ef6c..22ad718 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2259,13 +2259,13 @@
 }
 
 binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,
-        const std::string& instructionSet, const std::string& outputPath) {
+        const std::string& instructionSet, const std::unique_ptr<std::string>& outputPath) {
     ENFORCE_UID(AID_SYSTEM);
     std::lock_guard<std::recursive_mutex> lock(mLock);
 
     const char* apk_path = apkPath.c_str();
     const char* instruction_set = instructionSet.c_str();
-    const char* oat_dir = outputPath.c_str();
+    const char* oat_dir = outputPath ? outputPath->c_str() : nullptr;
 
     bool res = delete_odex(apk_path, instruction_set, oat_dir);
     return res ? ok() : error();
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index f9398da..5756b82 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -111,7 +111,7 @@
     binder::Status moveAb(const std::string& apkPath, const std::string& instructionSet,
             const std::string& outputPath);
     binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
-            const std::string& outputPath);
+            const std::unique_ptr<std::string>& outputPath);
     binder::Status reconcileSecondaryDexFile(const std::string& dexPath,
         const std::string& packageName, int32_t uid, const std::vector<std::string>& isa,
         const std::unique_ptr<std::string>& volumeUuid, int32_t storage_flag, bool* _aidl_return);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 63bea86..c8e76b0 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -76,7 +76,7 @@
     void moveAb(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
             @utf8InCpp String outputPath);
     void deleteOdex(@utf8InCpp String apkPath, @utf8InCpp String instructionSet,
-            @utf8InCpp String outputPath);
+            @nullable @utf8InCpp String outputPath);
 
     boolean reconcileSecondaryDexFile(@utf8InCpp String dexPath, @utf8InCpp String pkgName,
         int uid, in @utf8InCpp String[] isas, @nullable @utf8InCpp String volume_uuid,
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
index 82469b8..4d9b215 100644
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -1,6 +1,7 @@
 #include "include/dvr/dvr_buffer.h"
 
 #include <android/hardware_buffer.h>
+#include <dvr/dvr_shared_buffers.h>
 #include <private/dvr/buffer_hub_client.h>
 #include <ui/GraphicBuffer.h>
 
@@ -176,6 +177,11 @@
                                   hardware_buffer);
 }
 
+// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
+int dvrBufferGlobalLayoutVersionGet() {
+  return android::dvr::kSharedBufferLayoutVersion;
+}
+
 const struct native_handle* dvrWriteBufferGetNativeHandle(
     DvrWriteBuffer* write_buffer) {
   if (!write_buffer || !write_buffer->write_buffer)
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index f05a6fd..17b29d4 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -145,6 +145,7 @@
 typedef void (*DvrBufferDestroyPtr)(DvrBuffer* buffer);
 typedef int (*DvrBufferGetAHardwareBufferPtr)(
     DvrBuffer* buffer, AHardwareBuffer** hardware_buffer);
+typedef int (*DvrBufferGlobalLayoutVersionGetPtr)();
 typedef const struct native_handle* (*DvrBufferGetNativeHandlePtr)(
     DvrBuffer* buffer);
 
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
index 8cdad7d..802a0f7 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
@@ -60,6 +60,7 @@
 DVR_V1_API_ENTRY(BufferDestroy);
 DVR_V1_API_ENTRY(BufferGetAHardwareBuffer);
 DVR_V1_API_ENTRY(BufferGetNativeHandle);
+DVR_V1_API_ENTRY(BufferGlobalLayoutVersionGet);
 
 // Write buffer queue
 DVR_V1_API_ENTRY(WriteBufferQueueDestroy);
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
index af55698..935a7b2 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -95,6 +95,9 @@
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
                                 AHardwareBuffer** hardware_buffer);
 
+// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
+int dvrBufferGlobalLayoutVersionGet();
+
 // TODO(eieio): Switch to return int and take an out parameter for the native
 // handle.
 const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer);
diff --git a/libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h b/libs/vr/libdvr/include/dvr/dvr_config.h
similarity index 74%
rename from libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h
rename to libs/vr/libdvr/include/dvr/dvr_config.h
index cfe9d62..3d2c066 100644
--- a/libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h
+++ b/libs/vr/libdvr/include/dvr/dvr_config.h
@@ -1,17 +1,18 @@
-#ifndef ANDROID_DVR_VRFLINGER_CONFIG_H
-#define ANDROID_DVR_VRFLINGER_CONFIG_H
+#ifndef ANDROID_DVR_CONFIG_H
+#define ANDROID_DVR_CONFIG_H
 
 // This header is shared by VrCore and Android and must be kept in sync.
 
+#include <stdint.h>
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
 // This is a shared memory buffer for passing config data from VrCore to
 // libvrflinger in SurfaceFlinger.
-struct DvrVrFlingerConfig {
+struct __attribute__((packed, aligned(16))) DvrConfig {
   // Offset before vsync to submit frames to hardware composer.
-  int frame_post_offset_ns{4000000};
+  int32_t frame_post_offset_ns{4000000};
 
   // If the number of pending fences goes over this count at the point when we
   // are about to submit a new frame to HWC, we will drop the frame. This
@@ -20,11 +21,14 @@
   // the next vsync, at the point when the DMA to the display completes.
   // Currently we use a smart display and the EDS timing coincides with zero
   // pending fences, so this is 0.
-  size_t allowed_pending_fence_count{0};
+  int32_t allowed_pending_fence_count{0};
 
   // New fields should always be added to the end for backwards compat.
+
+  // Reserved padding to 16 bytes.
+  uint8_t pad[8];
 };
 
 __END_DECLS
 
-#endif  // ANDROID_DVR_VRFLINGER_CONFIG_H
+#endif  // ANDROID_DVR_CONFIG_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
index ce17f0c..096f800 100644
--- a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
+++ b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
@@ -1,8 +1,8 @@
 #ifndef ANDROID_DVR_SHARED_BUFFERS_H_
 #define ANDROID_DVR_SHARED_BUFFERS_H_
 
+#include <dvr/dvr_config.h>
 #include <dvr/dvr_pose.h>
-#include <dvr/dvr_vrflinger_config.h>
 #include <dvr/dvr_vsync.h>
 #include <libbroadcastring/broadcast_ring.h>
 
@@ -11,7 +11,7 @@
 namespace dvr {
 
 // Increment when the layout for the buffers change.
-constexpr uint32_t kSharedBufferLayoutVersion = 1;
+enum : uint32_t { kSharedBufferLayoutVersion = 1 };
 
 // Note: These buffers will be mapped from various system processes as well
 // as VrCore and the application processes in a r/w manner.
@@ -26,6 +26,7 @@
 static_assert(sizeof(DvrPoseAsync) == 128, "Unexpected size for DvrPoseAsync");
 static_assert(sizeof(DvrPose) == 96, "Unexpected size for DvrPose");
 static_assert(sizeof(DvrVsync) == 32, "Unexpected size for DvrVsync");
+static_assert(sizeof(DvrConfig) == 16, "Unexpected size for DvrConfig");
 
 // A helper class that provides compile time sized traits for the BroadcastRing.
 template <class DvrType, size_t StaticCount>
@@ -41,13 +42,12 @@
 // Traits classes.
 using DvrPoseTraits = DvrRingBufferTraits<DvrPose, 0>;
 using DvrVsyncTraits = DvrRingBufferTraits<DvrVsync, 2>;
-using DvrVrFlingerConfigTraits = DvrRingBufferTraits<DvrVrFlingerConfig, 2>;
+using DvrConfigTraits = DvrRingBufferTraits<DvrConfig, 2>;
 
 // The broadcast ring classes that will expose the data.
 using DvrPoseRing = BroadcastRing<DvrPose, DvrPoseTraits>;
 using DvrVsyncRing = BroadcastRing<DvrVsync, DvrVsyncTraits>;
-using DvrVrFlingerConfigRing =
-    BroadcastRing<DvrVrFlingerConfig, DvrVrFlingerConfigTraits>;
+using DvrConfigRing = BroadcastRing<DvrConfig, DvrConfigTraits>;
 
 // This is a shared memory buffer for passing pose data estimated at vsyncs.
 //
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
index 419083f..566f9de 100644
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -1,9 +1,9 @@
 #include <android/hardware_buffer.h>
 #include <dvr/dvr_buffer.h>
+#include <dvr/dvr_config.h>
 #include <dvr/dvr_display_manager.h>
 #include <dvr/dvr_shared_buffers.h>
 #include <dvr/dvr_surface.h>
-#include <dvr/dvr_vrflinger_config.h>
 #include <system/graphics.h>
 
 #include <base/logging.h>
@@ -285,8 +285,8 @@
   const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
                          AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
 
-  size_t correct_size = DvrVrFlingerConfigRing::MemorySize();
-  size_t wrong_size = DvrVrFlingerConfigRing::MemorySize(0);
+  size_t correct_size = DvrConfigRing::MemorySize();
+  size_t wrong_size = DvrConfigRing::MemorySize(0);
 
   // Setup an invalid config buffer (too small) and assert that it fails.
   DvrBuffer* setup_buffer = nullptr;
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 7a78d1f..c18ae82 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -481,9 +481,9 @@
 
 int HardwareComposer::MapConfigBuffer(IonBuffer& ion_buffer) {
   std::lock_guard<std::mutex> lock(shared_config_mutex_);
-  shared_config_ring_ = DvrVrFlingerConfigRing();
+  shared_config_ring_ = DvrConfigRing();
 
-  if (ion_buffer.width() < DvrVrFlingerConfigRing::MemorySize()) {
+  if (ion_buffer.width() < DvrConfigRing::MemorySize()) {
     ALOGE("HardwareComposer::MapConfigBuffer: invalid buffer size.");
     return -EINVAL;
   }
@@ -497,8 +497,7 @@
     return -EPERM;
   }
 
-  shared_config_ring_ =
-      DvrVrFlingerConfigRing::Create(buffer_base, ion_buffer.width());
+  shared_config_ring_ = DvrConfigRing::Create(buffer_base, ion_buffer.width());
   ion_buffer.Unlock();
 
   return 0;
@@ -506,7 +505,7 @@
 
 void HardwareComposer::ConfigBufferDeleted() {
   std::lock_guard<std::mutex> lock(shared_config_mutex_);
-  shared_config_ring_ = DvrVrFlingerConfigRing();
+  shared_config_ring_ = DvrConfigRing();
 }
 
 void HardwareComposer::UpdateConfigBuffer() {
@@ -514,7 +513,7 @@
   if (!shared_config_ring_.is_valid())
     return;
   // Copy from latest record in shared_config_ring_ to local copy.
-  DvrVrFlingerConfig record;
+  DvrConfig record;
   if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
     post_thread_config_ = record;
   }
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index de6f9ff..98e8905 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -17,7 +17,7 @@
 #include <tuple>
 #include <vector>
 
-#include <dvr/dvr_vrflinger_config.h>
+#include <dvr/dvr_config.h>
 #include <dvr/dvr_vsync.h>
 #include <pdx/file_handle.h>
 #include <pdx/rpc/variant.h>
@@ -452,10 +452,10 @@
   std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
 
   // Broadcast ring for receiving config data from the DisplayManager.
-  DvrVrFlingerConfigRing shared_config_ring_;
+  DvrConfigRing shared_config_ring_;
   uint32_t shared_config_ring_sequence_{0};
   // Config buffer for reading from the post thread.
-  DvrVrFlingerConfig post_thread_config_;
+  DvrConfig post_thread_config_;
   std::mutex shared_config_mutex_;
 
   static constexpr int kPostThreadInterrupted = 1;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 6bff38a..835e72b 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -897,19 +897,15 @@
             egl_tls_t::setContext(EGL_NO_CONTEXT);
         }
     } else {
-        // Force return to current context for drivers that cannot handle errors
-        EGLBoolean restore_result = EGL_FALSE;
 
-        // get a reference to the old current objects
-        ContextRef _c2(dp.get(), cur_c);
-        SurfaceRef _d2(dp.get(), cur_c->draw);
-        SurfaceRef _r2(dp.get(), cur_c->read);
+        if (cur_c != NULL) {
+            // Force return to current context for drivers that cannot handle errors
+            EGLBoolean restore_result = EGL_FALSE;
+            // get a reference to the old current objects
+            ContextRef _c2(dp.get(), cur_c);
+            SurfaceRef _d2(dp.get(), cur_c->draw);
+            SurfaceRef _r2(dp.get(), cur_c->read);
 
-        if (cur_c == NULL) {
-            restore_result = dp->makeCurrent(c, cur_c,
-                    EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT,
-                    EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        } else {
             c = cur_c;
             impl_ctx = c->context;
             impl_draw = EGL_NO_SURFACE;
@@ -925,13 +921,13 @@
             restore_result = dp->makeCurrent(c, cur_c,
                     cur_c->draw, cur_c->read, cur_c->context,
                     impl_draw, impl_read, impl_ctx);
-        }
-        if (restore_result == EGL_TRUE) {
-            _c2.acquire();
-            _r2.acquire();
-            _d2.acquire();
-        } else {
-            ALOGE("Could not restore original EGL context");
+            if (restore_result == EGL_TRUE) {
+                _c2.acquire();
+                _r2.acquire();
+                _d2.acquire();
+            } else {
+                ALOGE("Could not restore original EGL context");
+            }
         }
         // this will ALOGE the error
         egl_connection_t* const cnx = &gEGLImpl;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d19f964..9e139f2 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2531,6 +2531,14 @@
     return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
 }
 
+size_t Layer::getChildrenCount() const {
+    size_t count = 0;
+    for (const sp<Layer>& child : mCurrentChildren) {
+        count += 1 + child->getChildrenCount();
+    }
+    return count;
+}
+
 void Layer::addChild(const sp<Layer>& layer) {
     mCurrentChildren.add(layer);
     layer->setParent(this);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c9ebf99..6955d73 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -518,6 +518,7 @@
                                  const LayerVector::Visitor& visitor);
     void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor);
 
+    size_t getChildrenCount() const;
     void addChild(const sp<Layer>& layer);
     // Returns index if removed, or negative value otherwise
     // for symmetry with Vector::remove
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index beefc50..3682d16 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2666,8 +2666,13 @@
         if (parent == nullptr) {
             mCurrentState.layersSortedByZ.add(lbc);
         } else {
+            if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) {
+                ALOGE("addClientLayer called with a removed parent");
+                return NAME_NOT_FOUND;
+            }
             parent->addChild(lbc);
         }
+
         mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
         mLayersAdded = true;
         mNumLayers++;
@@ -2686,6 +2691,17 @@
     const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
         mCurrentState.layersSortedByZ.remove(layer);
 
+    if (p != nullptr) {
+        sp<Layer> ancestor = p;
+        while (ancestor->getParent() != nullptr) {
+            ancestor = ancestor->getParent();
+        }
+        if (mCurrentState.layersSortedByZ.indexOf(ancestor) < 0) {
+            ALOGE("removeLayer called with a layer whose parent has been removed");
+            return NAME_NOT_FOUND;
+        }
+    }
+
     // As a matter of normal operation, the LayerCleaner will produce a second
     // attempt to remove the surface. The Layer will be kept alive in mDrawingState
     // so we will succeed in promoting it, but it's already been removed
@@ -2702,7 +2718,7 @@
 
     mLayersPendingRemoval.add(layer);
     mLayersRemoved = true;
-    mNumLayers--;
+    mNumLayers -= 1 + layer->getChildrenCount();
     setTransactionFlags(eTransactionNeeded);
     return NO_ERROR;
 }
@@ -4331,8 +4347,6 @@
         err |= native_window_set_scaling_mode(window, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
         err |= native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
         err |= native_window_set_usage(window, usage);
-        err |= native_window_set_buffers_data_space(window, hw->getWideColorSupport()
-                ? HAL_DATASPACE_DISPLAY_P3 : HAL_DATASPACE_V0_SRGB);
 
         if (err == NO_ERROR) {
             ANativeWindowBuffer* buffer;
@@ -4359,6 +4373,14 @@
                             hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
                             useIdentityTransform, rotation);
 
+#ifdef USE_HWC2
+                        if (hasWideColorDisplay) {
+                            native_window_set_buffers_data_space(window,
+                                getRenderEngine().usesWideColor() ?
+                                    HAL_DATASPACE_DISPLAY_P3 : HAL_DATASPACE_V0_SRGB);
+                        }
+#endif
+
                         // Attempt to create a sync khr object that can produce a sync point. If that
                         // isn't available, create a non-dupable sync object in the fallback path and
                         // wait on it directly.