Merge "libdebuggerd_handler: in-process crash dumping for seccomped processes."
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 6d77f4b..ac05d4c 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -64,7 +64,7 @@
 
 #define FUNCTIONFS_ENDPOINT_ALLOC       _IOR('g', 231, __u32)
 
-static constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
+static constexpr size_t ENDPOINT_ALLOC_RETRIES = 2;
 
 static int dummy_fd = -1;
 
diff --git a/adf/libadf/adf.c b/adf/libadf/adf.c
index c4d6681..10f88b0 100644
--- a/adf/libadf/adf.c
+++ b/adf/libadf/adf.c
@@ -180,6 +180,37 @@
     return (int)data.complete_fence;
 }
 
+int adf_device_post_v2(struct adf_device *dev,
+        adf_id_t *interfaces, __u32 n_interfaces,
+        struct adf_buffer_config *bufs, __u32 n_bufs,
+        void *custom_data, __u64 custom_data_size,
+        enum adf_complete_fence_type complete_fence_type,
+        int *complete_fence)
+{
+    int err;
+    struct adf_post_config_v2 data;
+
+    memset(&data, 0, sizeof(data));
+    data.interfaces = (uintptr_t)interfaces;
+    data.n_interfaces = n_interfaces;
+    data.bufs = (uintptr_t)bufs;
+    data.n_bufs = n_bufs;
+    data.custom_data = (uintptr_t)custom_data;
+    data.custom_data_size = custom_data_size;
+    data.complete_fence_type = complete_fence_type;
+
+    err = ioctl(dev->fd, ADF_POST_CONFIG_V2, &data);
+    if (err < 0)
+        return -errno;
+
+    if (complete_fence)
+        *complete_fence = data.complete_fence;
+    else if (data.complete_fence >= 0)
+        close(data.complete_fence);
+
+    return 0;
+}
+
 static int adf_device_attachment(struct adf_device *dev,
         adf_id_t overlay_engine, adf_id_t interface, bool attach)
 {
@@ -421,6 +452,21 @@
     return (int)data.fd;
 }
 
+static void adf_interface_simple_post_config_buf(struct adf_buffer_config *buf,
+        __u32 overlay_engine, __u32 w, __u32 h, __u32 format, int buf_fd,
+        __u32 offset, __u32 pitch, int acquire_fence)
+{
+    buf->overlay_engine = overlay_engine;
+    buf->w = w;
+    buf->h = h;
+    buf->format = format;
+    buf->fd[0] = buf_fd;
+    buf->offset[0] = offset;
+    buf->pitch[0] = pitch;
+    buf->n_planes = 1;
+    buf->acquire_fence = acquire_fence;
+}
+
 int adf_interface_simple_post(int fd, __u32 overlay_engine,
         __u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
         __u32 pitch, int acquire_fence)
@@ -429,16 +475,8 @@
     struct adf_simple_post_config data;
 
     memset(&data, 0, sizeof(data));
-    data.buf.overlay_engine = overlay_engine;
-    data.buf.w = w;
-    data.buf.h = h;
-    data.buf.format = format;
-    data.buf.fd[0] = buf_fd;
-    data.buf.offset[0] = offset;
-    data.buf.pitch[0] = pitch;
-    data.buf.n_planes = 1;
-    data.buf.acquire_fence = acquire_fence;
-
+    adf_interface_simple_post_config_buf(&data.buf, overlay_engine, w, h, format,
+            buf_fd, offset, pitch, acquire_fence);
     ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG, &data);
     if (ret < 0)
         return -errno;
@@ -446,6 +484,32 @@
     return (int)data.complete_fence;
 }
 
+int adf_interface_simple_post_v2(int fd, adf_id_t overlay_engine,
+        __u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
+        __u32 pitch, int acquire_fence,
+        enum adf_complete_fence_type complete_fence_type,
+        int *complete_fence)
+{
+    int ret;
+    struct adf_simple_post_config_v2 data;
+
+    memset(&data, 0, sizeof(data));
+    adf_interface_simple_post_config_buf(&data.buf, overlay_engine, w, h, format,
+            buf_fd, offset, pitch, acquire_fence);
+    data.complete_fence_type = complete_fence_type;
+
+    ret = ioctl(fd, ADF_SIMPLE_POST_CONFIG_V2, &data);
+    if (ret < 0)
+        return -errno;
+
+    if (complete_fence)
+        *complete_fence = data.complete_fence;
+    else if (data.complete_fence >= 0)
+        close(data.complete_fence);
+
+    return 0;
+}
+
 ssize_t adf_overlay_engines(struct adf_device *dev, adf_id_t **overlay_engines)
 {
     char pattern[64];
diff --git a/adf/libadf/include/adf/adf.h b/adf/libadf/include/adf/adf.h
index b6bda34..e4c7b28 100644
--- a/adf/libadf/include/adf/adf.h
+++ b/adf/libadf/include/adf/adf.h
@@ -75,6 +75,29 @@
         struct adf_buffer_config *bufs, size_t n_bufs,
         void *custom_data, size_t custom_data_size);
 /**
+ * Atomically posts a new display configuration to the specified interfaces.
+ *
+ * Compared to adf_device_post(), adf_device_post_v2():
+ *
+ *  (*) allows the client to choose the kind of sync fence returned
+ *      (through complete_fence_type)
+ *
+ *  (*) stores the returned sync fence fd in a provided buffer, so the client
+ *      can distinguish between a permission error (ret = -1) and a successful
+ *      call that returns no fence (*complete_fence = -1)
+ *
+ * On error, returns -errno.
+ *
+ * On devices without the corresponding kernel support, returns -ENOTTY.
+ */
+int adf_device_post_v2(struct adf_device *dev,
+        adf_id_t *interfaces, __u32 n_interfaces,
+        struct adf_buffer_config *bufs, __u32 n_bufs,
+        void *custom_data, __u64 custom_data_size,
+        enum adf_complete_fence_type complete_fence_type,
+        int *complete_fence);
+
+/**
  * Attaches the specified interface and overlay engine.
  */
 int adf_device_attach(struct adf_device *dev, adf_id_t overlay_engine,
@@ -163,6 +186,28 @@
 int adf_interface_simple_post(int fd, adf_id_t overlay_engine,
         __u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
         __u32 pitch, int acquire_fence);
+/**
+ * Posts a single-plane RGB buffer to the display using the specified
+ * overlay engine.
+ *
+ * Compared to adf_interface_simple_post(), adf_interface_simple_post_v2():
+ *
+ *  (*) allows the client to choose the kind of sync fence returned
+ *      (through complete_fence_type)
+ *
+ *  (*) stores the returned sync fence fd in a provided buffer, so the client
+ *      can distinguish between a permission error (ret = -1) and a successful
+ *      call that returns no fence (*complete_fence = -1)
+ *
+ * On error, returns -errno.
+ *
+ * On devices without the corresponding kernel support, returns -ENOTTY.
+ */
+int adf_interface_simple_post_v2(int fd, adf_id_t overlay_engine,
+        __u32 w, __u32 h, __u32 format, int buf_fd, __u32 offset,
+        __u32 pitch, int acquire_fence,
+        enum adf_complete_fence_type complete_fence_type,
+        int *complete_fence);
 
 /**
  * Enumerates all overlay engines belonging to an ADF device.
diff --git a/adf/libadf/include/video/adf.h b/adf/libadf/include/video/adf.h
index 77203a5..692a425 100644
--- a/adf/libadf/include/video/adf.h
+++ b/adf/libadf/include/video/adf.h
@@ -49,69 +49,94 @@
   ADF_EVENT_DEVICE_CUSTOM = 128,
   ADF_EVENT_TYPE_MAX = 255,
 };
-struct adf_set_event {
+enum adf_complete_fence_type {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  ADF_COMPLETE_FENCE_NONE = 0,
+  ADF_COMPLETE_FENCE_PRESENT = 1,
+  ADF_COMPLETE_FENCE_RELEASE = 2,
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct adf_set_event {
   __u8 type;
   __u8 enabled;
 };
-struct adf_event {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct adf_event {
   __u8 type;
   __u32 length;
 };
-struct adf_vsync_event {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct adf_vsync_event {
   struct adf_event base;
   __aligned_u64 timestamp;
 };
-struct adf_hotplug_event {
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct adf_hotplug_event {
   struct adf_event base;
   __u8 connected;
 };
-#define ADF_MAX_PLANES 4
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADF_MAX_PLANES 4
 struct adf_buffer_config {
   __u32 overlay_engine;
   __u32 w;
-  __u32 h;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 h;
   __u32 format;
   __s32 fd[ADF_MAX_PLANES];
   __u32 offset[ADF_MAX_PLANES];
-  __u32 pitch[ADF_MAX_PLANES];
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u32 pitch[ADF_MAX_PLANES];
   __u8 n_planes;
   __s32 acquire_fence;
 };
-#define ADF_MAX_BUFFERS (4096 / sizeof(struct adf_buffer_config))
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ADF_MAX_BUFFERS (4096 / sizeof(struct adf_buffer_config))
 struct adf_post_config {
   size_t n_interfaces;
   __u32 __user * interfaces;
-  size_t n_bufs;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  size_t n_bufs;
   struct adf_buffer_config __user * bufs;
   size_t custom_data_size;
   void __user * custom_data;
-  __s32 complete_fence;
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __s32 complete_fence;
 };
+struct adf_post_config_v2 {
+  __u32 n_interfaces;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 interfaces;
+  __u32 n_bufs;
+  __u64 bufs;
+  __u64 custom_data_size;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u64 custom_data;
+  __s32 complete_fence;
+  __u8 complete_fence_type;
+};
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
 struct adf_simple_buffer_alloc {
   __u16 w;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u16 h;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 format;
   __s32 fd;
   __u32 offset;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __u32 pitch;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 };
 struct adf_simple_post_config {
   struct adf_buffer_config buf;
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
   __s32 complete_fence;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
+struct adf_simple_post_config_v2 {
+  struct adf_buffer_config buf;
+  __s32 complete_fence;
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+  __u8 complete_fence_type;
 };
 struct adf_attachment_config {
   __u32 overlay_engine;
@@ -177,4 +202,8 @@
 #define ADF_ATTACH _IOW(ADF_IOCTL_TYPE, 9, struct adf_attachment_config)
 /* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 #define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, struct adf_attachment_config)
+#define ADF_POST_CONFIG_V2 _IOW(ADF_IOCTL_TYPE, 11, struct adf_post_config_v2)
+#define ADF_SIMPLE_POST_CONFIG_V2 _IOW(ADF_IOCTL_TYPE, 12, struct adf_simple_post_config_v2)
 #endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+
diff --git a/adf/libadf/original-kernel-headers/video/adf.h b/adf/libadf/original-kernel-headers/video/adf.h
index c5d2e62..8293c1d 100644
--- a/adf/libadf/original-kernel-headers/video/adf.h
+++ b/adf/libadf/original-kernel-headers/video/adf.h
@@ -46,6 +46,15 @@
 	ADF_EVENT_TYPE_MAX = 255,
 };
 
+enum adf_complete_fence_type {
+	/* no fence */
+	ADF_COMPLETE_FENCE_NONE = 0,
+	/* fence fires when the configuration appears on the screen */
+	ADF_COMPLETE_FENCE_PRESENT = 1,
+	/* fence fires when the configuration leaves the screen */
+	ADF_COMPLETE_FENCE_RELEASE = 2,
+};
+
 /**
  * struct adf_set_event - start or stop subscribing to ADF events
  *
@@ -131,6 +140,9 @@
 /**
  * struct adf_post_config - request to flip to a new set of buffers
  *
+ * This request is equivalent to &struct adf_post_config_v2 with
+ * @complete_fence_type = %ADF_COMPLETE_FENCE_RELEASE.
+ *
  * @n_interfaces: number of interfaces targeted by the flip (input)
  * @interfaces: ids of interfaces targeted by the flip (input)
  * @n_bufs: number of buffers displayed (input)
@@ -152,6 +164,34 @@
 
 	__s32 complete_fence;
 };
+
+/**
+ * struct adf_post_config_v2 - request to flip to a new set of buffers
+ *
+ * @n_interfaces: number of interfaces targeted by the flip (input)
+ * @interfaces: ids of interfaces targeted by the flip (input)
+ * @n_bufs: number of buffers displayed (input)
+ * @bufs: description of buffers displayed (input)
+ * @custom_data_size: size of driver-private data (input)
+ * @custom_data: driver-private data (input)
+ * @complete_fence_type: one of &enum adf_complete_fence_type describing what
+ * 	fence to return (input)
+ * @complete_fence: sync_fence fd which will fire at the time
+ * 	requested by @complete_fence_type (output)
+ */
+struct adf_post_config_v2 {
+	__u32 n_interfaces;
+	__u64 interfaces; /* __u32 * packed into __u64 */
+
+	__u32 n_bufs;
+	__u64 bufs; /* struct adf_buffer_config * packed into __u64 */
+
+	__u64 custom_data_size;
+	__u64 custom_data; /* void * packed into __u64 */
+
+	__s32 complete_fence;
+	__u8 complete_fence_type;
+};
 #define ADF_MAX_INTERFACES (4096 / sizeof(__u32))
 
 /**
@@ -189,6 +229,9 @@
  * struct adf_simple_post_config - request to flip to a single buffer without
  * driver-private data
  *
+ * This request is equivalent to &struct adf_simple_post_config_v2 with
+ * @complete_fence_type = %ADF_COMPLETE_FENCE_RELEASE.
+ *
  * @buf: description of buffer displayed (input)
  * @complete_fence: sync_fence fd which will clear when this buffer has left the
  * screen (output)
@@ -199,6 +242,22 @@
 };
 
 /**
+ * struct adf_simple_post_config_v2 - request to flip to a single buffer without
+ * driver-private data
+ *
+ * @buf: description of buffer displayed (input)
+ * @complete_fence_type: one of &enum adf_complete_fence_type describing what
+ * 	fence to return (input)
+ * @complete_fence: sync_fence fd which will fire at the time
+ * 	requested by @complete_fence_type (output)
+ */
+struct adf_simple_post_config_v2 {
+	struct adf_buffer_config buf;
+	__s32 complete_fence;
+	__u8 complete_fence_type;
+};
+
+/**
  * struct adf_attachment_config - description of attachment between an overlay
  * engine and an interface
  *
@@ -318,4 +377,10 @@
 #define ADF_DETACH		_IOW(ADF_IOCTL_TYPE, 10, \
 					struct adf_attachment_config)
 
+#define ADF_POST_CONFIG_V2	_IOW(ADF_IOCTL_TYPE, 11, \
+					struct adf_post_config_v2)
+#define ADF_SIMPLE_POST_CONFIG_V2 \
+				_IOW(ADF_IOCTL_TYPE, 12, \
+					struct adf_simple_post_config_v2)
+
 #endif /* _UAPI_VIDEO_ADF_H_ */
diff --git a/adf/libadf/tests/Android.bp b/adf/libadf/tests/Android.bp
index 7b33300..9b3430e 100644
--- a/adf/libadf/tests/Android.bp
+++ b/adf/libadf/tests/Android.bp
@@ -17,6 +17,7 @@
 cc_test {
     name: "adf-unit-tests",
     srcs: ["adf_test.cpp"],
+    shared_libs: ["libsync"],
     static_libs: ["libadf"],
     cflags: ["-Werror"],
 }
diff --git a/adf/libadf/tests/adf_test.cpp b/adf/libadf/tests/adf_test.cpp
index eaa9342..4727c2b 100644
--- a/adf/libadf/tests/adf_test.cpp
+++ b/adf/libadf/tests/adf_test.cpp
@@ -20,6 +20,7 @@
 #include <adf/adf.h>
 #include <gtest/gtest.h>
 #include <sys/mman.h>
+#include <sync/sync.h>
 
 class AdfTest : public testing::Test {
 public:
@@ -73,24 +74,6 @@
         FAIL(); /* this should never happen */
     }
 
-    void drawCheckerboard(void *buf, uint32_t w, uint32_t h, uint32_t pitch) {
-        uint8_t *buf8 = reinterpret_cast<uint8_t *>(buf);
-        for (uint32_t y = 0; y < h / 2; y++) {
-            uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
-            for (uint32_t x = 0; x < w / 2; x++)
-                scanline[x] = 0xFF0000FF;
-            for (uint32_t x = w / 2; x < w; x++)
-                scanline[x] = 0xFF00FFFF;
-        }
-        for (uint32_t y = h / 2; y < h; y++) {
-            uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
-            for (uint32_t x = 0; x < w / 2; x++)
-                scanline[x] = 0xFFFF00FF;
-            for (uint32_t x = w / 2; x < w; x++)
-                scanline[x] = 0xFFFFFFFF;
-        }
-    }
-
     /* various helpers to call ADF and die on failure */
 
     void getInterfaceData(adf_interface_data &data) {
@@ -141,6 +124,42 @@
         free(event);
     }
 
+    void drawCheckerboard(uint32_t &w, uint32_t &h, uint32_t &format,
+            char format_str[ADF_FORMAT_STR_SIZE], int &buf_fd, uint32_t &offset,
+            uint32_t &pitch) {
+        ASSERT_NO_FATAL_FAILURE(getCurrentMode(w, h));
+        ASSERT_NO_FATAL_FAILURE(get8888Format(format, format_str));
+
+        buf_fd = adf_interface_simple_buffer_alloc(intf, w, h, format, &offset,
+                &pitch);
+        ASSERT_GE(buf_fd, 0) << "allocating " << w << "x" << h << " " <<
+                format_str << " buffer failed: " << strerror(-buf_fd);
+        EXPECT_GE(pitch, w * 4);
+
+        void *mapped = mmap(NULL, pitch * h, PROT_WRITE, MAP_SHARED, buf_fd,
+                offset);
+        ASSERT_NE(mapped, MAP_FAILED) << "mapping " << w << "x" << h << " " <<
+                format_str << " buffer failed: " << strerror(-errno);
+
+        uint8_t *buf8 = static_cast<uint8_t *>(mapped);
+        for (uint32_t y = 0; y < h / 2; y++) {
+            uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
+            for (uint32_t x = 0; x < w / 2; x++)
+                scanline[x] = 0xFF0000FF;
+            for (uint32_t x = w / 2; x < w; x++)
+                scanline[x] = 0xFF00FFFF;
+        }
+        for (uint32_t y = h / 2; y < h; y++) {
+            uint32_t *scanline = reinterpret_cast<uint32_t *>(buf8 + y * pitch);
+            for (uint32_t x = 0; x < w / 2; x++)
+                scanline[x] = 0xFFFF00FF;
+            for (uint32_t x = w / 2; x < w; x++)
+                scanline[x] = 0xFFFFFFFF;
+        }
+
+        munmap(mapped, pitch * h);
+    }
+
 protected:
     adf_device dev;
     adf_id_t intf_id;
@@ -310,27 +329,11 @@
 }
 
 TEST_F(AdfTest, simple_buffer) {
-    uint32_t w = 0, h = 0;
-    ASSERT_NO_FATAL_FAILURE(getCurrentMode(w, h));
-
-    uint32_t format = 0;
+    int buf_fd;
+    uint32_t w, h, format, offset, pitch;
     char format_str[ADF_FORMAT_STR_SIZE];
-    ASSERT_NO_FATAL_FAILURE(get8888Format(format, format_str));
-
-    uint32_t offset;
-    uint32_t pitch;
-    int buf_fd = adf_interface_simple_buffer_alloc(intf, w, h, format, &offset,
-            &pitch);
-    ASSERT_GE(buf_fd, 0) << "allocating " << w << "x" << h << " " <<
-            format_str << " buffer failed: " << strerror(-buf_fd);
-    EXPECT_GE(pitch, w * 4);
-
-    void *mapped = mmap(NULL, pitch * h, PROT_WRITE, MAP_SHARED, buf_fd,
-            offset);
-    ASSERT_NE(mapped, MAP_FAILED) << "mapping " << w << "x" << h << " " <<
-            format_str << " buffer failed: " << strerror(-errno);
-    drawCheckerboard(mapped, w, h, pitch);
-    munmap(mapped, pitch * h);
+    ASSERT_NO_FATAL_FAILURE(drawCheckerboard(w, h, format, format_str,
+            buf_fd, offset, pitch));
 
     ASSERT_NO_FATAL_FAILURE(attach());
     ASSERT_NO_FATAL_FAILURE(blank(DRM_MODE_DPMS_ON));
@@ -342,3 +345,59 @@
             format_str << " buffer failed: " << strerror(-release_fence);
     close(release_fence);
 }
+
+TEST_F(AdfTest, simple_buffer_v2) {
+    int buf_fd;
+    uint32_t w, h, format, offset, pitch;
+    char format_str[ADF_FORMAT_STR_SIZE];
+    ASSERT_NO_FATAL_FAILURE(drawCheckerboard(w, h, format, format_str,
+            buf_fd, offset, pitch));
+
+    ASSERT_NO_FATAL_FAILURE(attach());
+    ASSERT_NO_FATAL_FAILURE(blank(DRM_MODE_DPMS_ON));
+
+    int config_1_release;
+    int err = adf_interface_simple_post_v2(intf, eng_id, w, h,
+            format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_RELEASE,
+            &config_1_release);
+    if (err == -ENOTTY) {
+        GTEST_LOG_(INFO) << "ADF_SIMPLE_POST_CONFIG_V2 not supported on this kernel";
+        return;
+    }
+    ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
+            format_str << " buffer failed: " << strerror(-err);
+
+    err = sync_wait(config_1_release, 1000);
+    ASSERT_EQ(-1, err) <<
+            "waiting for config 1's release fence should not have suceeded";
+    ASSERT_EQ(ETIME, errno) <<
+            "config 1's release fence should have timed out, but failed instead: " <<
+            strerror(errno);
+
+    int config_2_present;
+    err = adf_interface_simple_post_v2(intf, eng_id, w, h,
+            format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_PRESENT,
+            &config_2_present);
+    ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
+            format_str << " buffer failed: " << strerror(-err);
+
+    err = sync_wait(config_2_present, 1000);
+    ASSERT_EQ(0, err) <<
+            "waiting for config 2's present fence failed: " << strerror(errno);
+    err = sync_wait(config_1_release, 0);
+    ASSERT_EQ(0, err) <<
+            "waiting for config 1's release fence failed: " << strerror(errno);
+    close(config_1_release);
+    close(config_2_present);
+
+    int config_3_no_fence;
+    err = adf_interface_simple_post_v2(intf, eng_id, w, h,
+            format, buf_fd, offset, pitch, -1, ADF_COMPLETE_FENCE_NONE,
+            &config_3_no_fence);
+    ASSERT_GE(err, 0) << "posting " << w << "x" << h << " " <<
+            format_str << " buffer failed: " << strerror(-err);
+    ASSERT_EQ(-1, config_3_no_fence) <<
+            "fence returned even though the fence type was ADF_COMPLETE_FENCE_NONE";
+
+    close(buf_fd);
+}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a7354a7..a4cc5f2 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -225,7 +225,12 @@
 void RecordBootloaderTimings(BootEventRecordStore* boot_event_store) {
   // |ro.boot.boottime| is of the form 'stage1:time1,...,stageN:timeN'.
   std::string value = GetProperty("ro.boot.boottime");
+  if (value.empty()) {
+    // ro.boot.boottime is not reported on all devices.
+    return;
+  }
 
+  int32_t total_time = 0;
   auto stages = android::base::Split(value, ",");
   for (auto const &stageTiming : stages) {
     // |stageTiming| is of the form 'stage:time'.
@@ -235,10 +240,13 @@
     std::string stageName = stageTimingValues[0];
     int32_t time_ms;
     if (android::base::ParseInt(stageTimingValues[1], &time_ms)) {
+      total_time += time_ms;
       boot_event_store->AddBootEventWithValue(
           "boottime.bootloader." + stageName, time_ms);
     }
   }
+
+  boot_event_store->AddBootEventWithValue("boottime.bootloader.total", total_time);
 }
 
 // Records several metrics related to the time it takes to boot the device,
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 9d24b89..08b0047 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -155,6 +155,14 @@
     return false;
   }
 
+  // Make the fd O_APPEND so that our output is guaranteed to be at the end of a file.
+  // (This also makes selinux rules consistent, because selinux distinguishes between writing to
+  // a regular fd, and writing to an fd with O_APPEND).
+  int flags = fcntl(tmp_output_fd.get(), F_GETFL);
+  if (fcntl(tmp_output_fd.get(), F_SETFL, flags | O_APPEND) != 0) {
+    PLOG(WARNING) << "failed to set output fd flags";
+  }
+
   *tombstoned_socket = std::move(sockfd);
   *output_fd = std::move(tmp_output_fd);
   return true;
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 956c702..6939428 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -29,17 +29,11 @@
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/include \
     system/vold \
-    system/extras/ext4_utils \
-    bootable/recovery
+    system/extras/ext4_utils
 LOCAL_MODULE:= libfs_mgr
 LOCAL_STATIC_LIBRARIES := $(common_static_libraries)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Werror
-ifeq ($(TARGET_USERIMAGES_USE_EXT4), true)
-  ifeq ($(TARGET_USES_MKE2FS), true)
-    LOCAL_CFLAGS += -DTARGET_USES_MKE2FS
-  endif
-endif
 ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
 endif
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index be84e8a..1768078 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -103,9 +103,7 @@
     char tmpmnt_opts[64] = "errors=remount-ro";
     const char *e2fsck_argv[] = {
         E2FSCK_BIN,
-#ifndef TARGET_USES_MKE2FS // "-f" only for old ext4 generation tool
         "-f",
-#endif
         "-y",
         blk_device
     };
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index e957f6b..b30417f 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -33,53 +33,6 @@
 #include "fs_mgr.h"
 #include "fs_mgr_priv.h"
 
-#include "bootloader.h"
-
-// Copies slot_suffix from misc into |out_suffix|. Returns 0 on
-// success, -1 on error or if there is no non-empty slot_suffix.
-static int get_active_slot_suffix_from_misc(struct fstab *fstab,
-                                            char *out_suffix,
-                                            size_t suffix_len)
-{
-    int n;
-    int misc_fd;
-    ssize_t num_read;
-    struct bootloader_message_ab msg;
-
-    misc_fd = -1;
-    for (n = 0; n < fstab->num_entries; n++) {
-        if (strcmp(fstab->recs[n].mount_point, "/misc") == 0) {
-            misc_fd = open(fstab->recs[n].blk_device, O_RDONLY);
-            if (misc_fd == -1) {
-                PERROR << "Error opening misc partition '"
-                       << fstab->recs[n].blk_device << "'";
-                return -1;
-            } else {
-                break;
-            }
-        }
-    }
-
-    if (misc_fd == -1) {
-        LERROR << "Error finding misc partition";
-        return -1;
-    }
-
-    num_read = TEMP_FAILURE_RETRY(read(misc_fd, &msg, sizeof(msg)));
-    // Linux will never return partial reads when reading from block
-    // devices so no need to worry about them.
-    if (num_read != sizeof(msg)) {
-        PERROR << "Error reading bootloader_message";
-        close(misc_fd);
-        return -1;
-    }
-    close(misc_fd);
-    if (msg.slot_suffix[0] == '\0')
-        return -1;
-    strncpy(out_suffix, msg.slot_suffix, suffix_len);
-    return 0;
-}
-
 // finds slot_suffix in androidboot.slot_suffix kernel command line argument
 // or in the device tree node at /firmware/android/slot_suffix property
 static int get_active_slot_suffix_from_kernel(char *out_suffix,
@@ -123,11 +76,10 @@
     return -1;
 }
 
-// Gets slot_suffix from either the kernel cmdline / device tree / firmware
-// or the misc partition. Sets |out_suffix| on success and returns 0. Returns
-// -1 if slot_suffix could not be determined.
-static int get_active_slot_suffix(struct fstab *fstab, char *out_suffix,
-                                  size_t suffix_len)
+// Gets slot_suffix from either the kernel cmdline / device tree.  Sets
+// |out_suffix| on success and returns 0. Returns -1 if slot_suffix could not
+// be determined.
+static int get_active_slot_suffix(char *out_suffix, size_t suffix_len)
 {
     char propbuf[PROPERTY_VALUE_MAX];
 
@@ -140,22 +92,14 @@
         return 0;
     }
 
-    // if the property is not set, we are either being invoked too early
-    // or the slot suffix in mentioned in the misc partition. If its
-    // "too early", try to find the slotsuffix ourselves in the kernel command
-    // line or the device tree
+    // if the property is not set, we are probably being invoked early during
+    // boot.  Try to find the slotsuffix ourselves in the kernel command line
+    // or the device tree
     if (get_active_slot_suffix_from_kernel(out_suffix, suffix_len) == 0) {
         LINFO << "Using slot suffix '" << out_suffix << "' from kernel";
         return 0;
     }
 
-    // If we couldn't get the suffix from the kernel cmdline, try the
-    // the misc partition.
-    if (get_active_slot_suffix_from_misc(fstab, out_suffix, suffix_len) == 0) {
-        LINFO << "Using slot suffix '" << out_suffix << "' from misc";
-        return 0;
-    }
-
     LERROR << "Error determining slot_suffix";
 
     return -1;
@@ -174,8 +118,7 @@
 
             if (!got_suffix) {
                 memset(suffix, '\0', sizeof(suffix));
-                if (get_active_slot_suffix(fstab, suffix,
-                                           sizeof(suffix) - 1) != 0) {
+                if (get_active_slot_suffix(suffix, sizeof(suffix) - 1) != 0) {
                   return -1;
                 }
                 got_suffix = 1;
diff --git a/init/init.cpp b/init/init.cpp
index 9c1e23b..7f7eb2f 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -47,6 +47,7 @@
 #include <cutils/iosched_policy.h>
 #include <cutils/list.h>
 #include <cutils/sockets.h>
+#include <libavb/libavb.h>
 #include <private/android_filesystem_config.h>
 
 #include <fstream>
@@ -959,6 +960,9 @@
         property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
         property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
 
+        // Set libavb version for Framework-only OTA match in Treble build.
+        property_set("ro.boot.init.avb_version", std::to_string(AVB_MAJOR_VERSION).c_str());
+
         // Clean up our environment.
         unsetenv("INIT_SECOND_STAGE");
         unsetenv("INIT_STARTED_AT");
diff --git a/libutils/RefBase.cpp b/libutils/RefBase.cpp
index 1f8395b..4252ba6 100644
--- a/libutils/RefBase.cpp
+++ b/libutils/RefBase.cpp
@@ -22,7 +22,6 @@
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <typeinfo>
 #include <unistd.h>
 
 #include <utils/RefBase.h>