Merge "Clear callbacks when destroying DvrHwcClient" into oc-dr1-dev
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 5548699..abf7b06 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -14,6 +14,9 @@
         "libz",
         "libbase",
     ],
+    static_libs: [
+        "libpdx_default_transport",
+    ],
 
     init_rc: ["atrace.rc"],
 
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 93ae9da..2d9a98c 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -40,6 +40,7 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
+#include <pdx/default_transport/service_utility.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Tokenizer.h>
@@ -50,6 +51,7 @@
 #include <android-base/stringprintf.h>
 
 using namespace android;
+using pdx::default_transport::ServiceUtility;
 
 using std::string;
 
@@ -61,6 +63,7 @@
 const char* k_traceAppsNumberProperty = "debug.atrace.app_number";
 const char* k_traceAppsPropertyTemplate = "debug.atrace.app_%d";
 const char* k_coreServiceCategory = "core_services";
+const char* k_pdxServiceCategory = "pdx";
 const char* k_coreServicesProp = "ro.atrace.core.services";
 
 typedef enum { OPT, REQ } requiredness  ;
@@ -114,6 +117,7 @@
     { "network",    "Network",          ATRACE_TAG_NETWORK, { } },
     { "adb",        "ADB",              ATRACE_TAG_ADB, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
+    { k_pdxServiceCategory, "PDX services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "events/sched/sched_switch/enable" },
         { REQ,      "events/sched/sched_wakeup/enable" },
@@ -209,6 +213,7 @@
 static const char* g_outputFile = nullptr;
 
 /* Global state */
+static bool g_tracePdx = false;
 static bool g_traceAborted = false;
 static bool g_categoryEnables[arraysize(k_categories)] = {};
 static std::string g_traceFolder;
@@ -368,6 +373,10 @@
         return !android::base::GetProperty(k_coreServicesProp, "").empty();
     }
 
+    if (strcmp(category.name, k_pdxServiceCategory) == 0) {
+        return true;
+    }
+
     bool ok = category.tags != 0;
     for (int i = 0; i < MAX_SYS_FILES; i++) {
         const char* path = category.sysfiles[i].path;
@@ -790,6 +799,11 @@
         if (strcmp(k_categories[i].name, k_coreServiceCategory) == 0) {
             coreServicesTagEnabled = g_categoryEnables[i];
         }
+
+        // Set whether to poke PDX services in this session.
+        if (strcmp(k_categories[i].name, k_pdxServiceCategory) == 0) {
+            g_tracePdx = g_categoryEnables[i];
+        }
     }
 
     std::string packageList(g_debugAppCmdLine);
@@ -803,6 +817,10 @@
     ok &= pokeBinderServices();
     pokeHalServices();
 
+    if (g_tracePdx) {
+        ok &= ServiceUtility::PokeServices();
+    }
+
     // Disable all the sysfs enables.  This is done as a separate loop from
     // the enables to allow the same enable to exist in multiple categories.
     ok &= disableKernelTraceEvents();
@@ -840,6 +858,10 @@
     clearAppProperties();
     pokeBinderServices();
 
+    if (g_tracePdx) {
+        ServiceUtility::PokeServices();
+    }
+
     // Set the options back to their defaults.
     setTraceOverwriteEnable(true);
     setTraceBufferSizeKB(1);
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index baa05d0..685fdd8 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -990,14 +990,22 @@
   return oat_dir == nullptr || oat_dir[0] == '!';
 }
 
+// Best-effort check whether we can fit the the path into our buffers.
+// Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
+// without a swap file, if necessary. Reference profiles file also add an extra ".prof"
+// extension to the cache path (5 bytes).
+// TODO(calin): move away from char* buffers and PKG_PATH_MAX.
+static bool validate_dex_path_size(const std::string& dex_path) {
+    if (dex_path.size() >= (PKG_PATH_MAX - 8)) {
+        LOG(ERROR) << "dex_path too long: " << dex_path;
+        return false;
+    }
+    return true;
+}
+
 static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
             const char* oat_dir, bool is_secondary_dex, /*out*/ char* out_oat_path) {
-    // Early best-effort check whether we can fit the the path into our buffers.
-    // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
-    // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
-    // extension to the cache path (5 bytes).
-    if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
-        ALOGE("apk_path too long '%s'\n", apk_path);
+    if (!validate_dex_path_size(apk_path)) {
         return false;
     }
 
@@ -1350,33 +1358,29 @@
 // The analyzer will check if the dex_file needs to be (re)compiled to match the compiler_filter.
 // If this is for a profile guided compilation, profile_was_updated will tell whether or not
 // the profile has changed.
-static void exec_dexoptanalyzer(const std::string& dex_file, const char* instruction_set,
-        const char* compiler_filter, bool profile_was_updated) {
+static void exec_dexoptanalyzer(const std::string& dex_file, const std::string& instruction_set,
+        const std::string& compiler_filter, bool profile_was_updated) {
     static const char* DEXOPTANALYZER_BIN = "/system/bin/dexoptanalyzer";
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
-    if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
-        ALOGE("Instruction set %s longer than max length of %d",
-              instruction_set, MAX_INSTRUCTION_SET_LEN);
+    if (instruction_set.size() >= MAX_INSTRUCTION_SET_LEN) {
+        LOG(ERROR) << "Instruction set " << instruction_set
+                << " longer than max length of " << MAX_INSTRUCTION_SET_LEN;
         return;
     }
 
-    char dex_file_arg[strlen("--dex-file=") + PKG_PATH_MAX];
-    char isa_arg[strlen("--isa=") + MAX_INSTRUCTION_SET_LEN];
-    char compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
+    std::string dex_file_arg = "--dex-file=" + dex_file;
+    std::string isa_arg = "--isa=" + instruction_set;
+    std::string compiler_filter_arg = "--compiler-filter=" + compiler_filter;
     const char* assume_profile_changed = "--assume-profile-changed";
 
-    sprintf(dex_file_arg, "--dex-file=%s", dex_file.c_str());
-    sprintf(isa_arg, "--isa=%s", instruction_set);
-    sprintf(compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
-
     // program name, dex file, isa, filter, the final NULL
     const char* argv[5 + (profile_was_updated ? 1 : 0)];
     int i = 0;
     argv[i++] = DEXOPTANALYZER_BIN;
-    argv[i++] = dex_file_arg;
-    argv[i++] = isa_arg;
-    argv[i++] = compiler_filter_arg;
+    argv[i++] = dex_file_arg.c_str();
+    argv[i++] = isa_arg.c_str();
+    argv[i++] = compiler_filter_arg.c_str();
     if (profile_was_updated) {
         argv[i++] = assume_profile_changed;
     }
@@ -1490,6 +1494,9 @@
         }
     }
     const std::string& dex_path = *dex_path_out;
+    if (!validate_dex_path_size(dex_path)) {
+        return false;
+    }
     if (!validate_secondary_dex_path(pkgname, dex_path, volume_uuid, uid, storage_flag)) {
         LOG(ERROR) << "Could not validate secondary dex path " << dex_path;
         return false;
@@ -1560,6 +1567,10 @@
         LOG_FATAL("dexopt flags contains unknown fields\n");
     }
 
+    if (!validate_dex_path_size(dex_path)) {
+        return false;
+    }
+
     bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
     bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
     bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
@@ -1749,6 +1760,10 @@
         /*out*/bool* out_secondary_dex_exists) {
     // Set out to false to start with, just in case we have validation errors.
     *out_secondary_dex_exists = false;
+    if (!validate_dex_path_size(dex_path)) {
+        return false;
+    }
+
     if (isas.size() == 0) {
         LOG(ERROR) << "reconcile_secondary_dex_file called with empty isas vector";
         return false;
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index 6a81cfc..2597c79 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -31,7 +31,7 @@
 constexpr const char* DALVIK_CACHE_POSTFIX = "@classes.dex";
 
 constexpr size_t PKG_NAME_MAX = 128u;   /* largest allowed package name */
-constexpr size_t PKG_PATH_MAX = 256u;   /* max size of any path we use */
+constexpr size_t PKG_PATH_MAX = 1024u;  /* max size of any path we use */
 
 /****************************************************************************
  * IMPORTANT: These values are passed from Java code. Keep them in sync with
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
index aa2ed94..2e1655f 100644
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ b/libs/vr/libdvr/dvr_buffer_queue.cpp
@@ -313,7 +313,10 @@
 int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
                               DvrReadBuffer* read_buffer, int* out_fence_fd,
                               void* out_meta, size_t meta_size_bytes) {
-  if (!read_queue || !read_buffer || !out_fence_fd || !out_meta)
+  if (!read_queue || !read_buffer || !out_fence_fd)
+    return -EINVAL;
+
+  if (meta_size_bytes != 0 && !out_meta)
     return -EINVAL;
 
   return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta,
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
index caf208d..95c04f1 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
@@ -124,6 +124,8 @@
 //     signals the release of underlying buffer. The consumer should wait until
 //     this fence clears before reading data from it.
 // @param out_meta The memory area where a metadata object will be filled.
+//     Can be nullptr iff |meta_size_bytes| is zero (i.e., there is no
+//     metadata).
 // @param meta_size_bytes Size of the metadata object caller expects. If it
 //     doesn't match the size of actually metadata transported by the buffer
 //     queue, the method returns -EINVAL.
diff --git a/libs/vr/libdvr/include/dvr/dvr_pose.h b/libs/vr/libdvr/include/dvr/dvr_pose.h
index 4256cf9..b3df028 100644
--- a/libs/vr/libdvr/include/dvr/dvr_pose.h
+++ b/libs/vr/libdvr/include/dvr/dvr_pose.h
@@ -43,16 +43,24 @@
 } DvrPoseAsync;
 
 enum {
-  DVR_POSE_FLAG_INVALID = (1UL << 0),       // This pose is invalid.
-  DVR_POSE_FLAG_INITIALIZING = (1UL << 1),  // The pose delivered during
-                                            // initialization and it may not be
-                                            // correct.
+  DVR_POSE_FLAG_INVALID = (1ULL << 0),       // This pose is invalid.
+  DVR_POSE_FLAG_INITIALIZING = (1ULL << 1),  // The pose delivered during
+                                             // initialization and it may not be
+                                             // correct.
   DVR_POSE_FLAG_3DOF =
-      (1UL << 2),  // This pose is derived from 3Dof sensors. If
-                   // this is not set, pose is derived using
-                   // 3Dof and 6Dof sensors.
+      (1ULL << 2),  // This pose is derived from 3Dof sensors. If
+                    // this is not set, pose is derived using
+                    // 3Dof and 6Dof sensors.
   DVR_POSE_FLAG_FLOOR_HEIGHT_INVALID =
-      (1UL << 3),  // If set the floor height is invalid.
+      (1ULL << 3),  // If set the floor height is invalid.
+
+  // Bits that indicate the tracking system state.
+  DVR_POSE_FLAG_SERVICE_EXCEPTION = (1ULL << 32),
+  DVR_POSE_FLAG_FISHEYE_OVER_EXPOSED = (1ULL << 33),
+  DVR_POSE_FLAG_FISHEYE_UNDER_EXPOSED = (1ULL << 34),
+  DVR_POSE_FLAG_COLOR_OVER_EXPOSED = (1ULL << 35),
+  DVR_POSE_FLAG_COLOR_UNDER_EXPOSED = (1ULL << 36),
+  DVR_POSE_FLAG_TOO_FEW_FEATURES_TRACKED = (1ULL << 37)
 };
 
 // Represents a sensor pose sample.
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 5158612..497b1cb 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -37,15 +37,11 @@
 
  protected:
   void SetUp() override {
-    auto config = ProducerQueueConfigBuilder()
-                      .SetDefaultWidth(kBufferWidth)
-                      .SetDefaultHeight(kBufferHeight)
-                      .SetDefaultFormat(kBufferFormat)
-                      .SetMetadata<TestMeta>()
-                      .Build();
-    write_queue_ =
-        new DvrWriteBufferQueue(ProducerQueue::Create(config, UsagePolicy{}));
-    ASSERT_NE(nullptr, write_queue_);
+    config_builder_ = ProducerQueueConfigBuilder()
+                          .SetDefaultWidth(kBufferWidth)
+                          .SetDefaultHeight(kBufferHeight)
+                          .SetDefaultFormat(kBufferFormat)
+                          .SetMetadata<TestMeta>();
   }
 
   void TearDown() override {
@@ -55,6 +51,12 @@
     }
   }
 
+  void CreateWriteBufferQueue() {
+    write_queue_ = new DvrWriteBufferQueue(
+        ProducerQueue::Create(config_builder_.Build(), UsagePolicy{}));
+    ASSERT_NE(nullptr, write_queue_);
+  }
+
   void AllocateBuffers(size_t buffer_count) {
     auto status = write_queue_->producer_queue()->AllocateBuffers(
         kBufferWidth, kBufferHeight, kLayerCount, kBufferFormat, kBufferUsage,
@@ -73,18 +75,23 @@
              buffer_removed_count_);
   }
 
+  ProducerQueueConfigBuilder config_builder_;
   DvrWriteBufferQueue* write_queue_{nullptr};
   int buffer_available_count_{0};
   int buffer_removed_count_{0};
 };
 
-TEST_F(DvrBufferQueueTest, TestWrite_QueueDestroy) {
+TEST_F(DvrBufferQueueTest, TestWrite_QueueCreateDestroy) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+
   dvrWriteBufferQueueDestroy(write_queue_);
   write_queue_ = nullptr;
 }
 
 TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) {
-  AllocateBuffers(kQueueCapacity);
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));
+
   size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
 
   ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
@@ -92,6 +99,8 @@
 }
 
 TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+
   DvrReadBufferQueue* read_queue = nullptr;
   int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
 
@@ -102,6 +111,8 @@
 }
 
 TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+
   DvrReadBufferQueue* read_queue1 = nullptr;
   DvrReadBufferQueue* read_queue2 = nullptr;
   int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
@@ -119,7 +130,8 @@
 }
 
 TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) {
-  AllocateBuffers(3);
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(3));
 
   DvrReadBuffer* read_buffer = nullptr;
   DvrWriteBuffer* write_buffer = nullptr;
@@ -152,6 +164,9 @@
 }
 
 TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));
+
   static constexpr int kTimeout = 0;
   DvrReadBufferQueue* read_queue = nullptr;
   DvrReadBuffer* rb = nullptr;
@@ -172,8 +187,6 @@
   dvrReadBufferCreateEmpty(&rb);
   ASSERT_NE(nullptr, rb);
 
-  AllocateBuffers(kQueueCapacity);
-
   // Gain buffer for writing.
   ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb, &fence_fd);
   ASSERT_EQ(0, ret);
@@ -221,6 +234,8 @@
 }
 
 TEST_F(DvrBufferQueueTest, TestGetExternalSurface) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+
   ANativeWindow* window = nullptr;
 
   // The |write_queue_| doesn't have proper metadata (must be
@@ -251,6 +266,9 @@
 // Before each dequeue operation, we resize the buffer queue and expect the
 // queue always return buffer with desired dimension.
 TEST_F(DvrBufferQueueTest, TestResizeBuffer) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));
+
   static constexpr int kTimeout = 0;
   int fence_fd = -1;
 
@@ -278,8 +296,6 @@
   dvrWriteBufferCreateEmpty(&wb3);
   ASSERT_NE(nullptr, wb3);
 
-  AllocateBuffers(kQueueCapacity);
-
   // Handle all pending events on the read queue.
   ret = dvrReadBufferQueueHandleEvents(read_queue);
   ASSERT_EQ(0, ret);
@@ -369,6 +385,71 @@
   dvrReadBufferQueueDestroy(read_queue);
 }
 
+TEST_F(DvrBufferQueueTest, DequeueEmptyMetadata) {
+  // Overrides default queue parameters: Empty metadata.
+  config_builder_.SetMetadata<void>();
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1));
+
+  DvrReadBuffer* rb = nullptr;
+  DvrWriteBuffer* wb = nullptr;
+  dvrReadBufferCreateEmpty(&rb);
+  dvrWriteBufferCreateEmpty(&wb);
+
+  DvrReadBufferQueue* read_queue = nullptr;
+  EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
+
+  const int kTimeoutMs = 0;
+  int fence_fd = -1;
+  EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd));
+
+  EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, nullptr, 0));
+  EXPECT_EQ(0, dvrWriteBufferClear(wb));
+  dvrWriteBufferDestroy(wb);
+  wb = nullptr;
+
+  // When acquire buffer, it's legit to pass nullptr as out_meta iff metadata
+  // size is Zero.
+  EXPECT_EQ(0, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd,
+                                         nullptr, 0));
+  EXPECT_TRUE(dvrReadBufferIsValid(rb));
+}
+
+TEST_F(DvrBufferQueueTest, DequeueMismatchMetadata) {
+  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
+  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1));
+
+  DvrReadBuffer* rb = nullptr;
+  DvrWriteBuffer* wb = nullptr;
+  dvrReadBufferCreateEmpty(&rb);
+  dvrWriteBufferCreateEmpty(&wb);
+
+  DvrReadBufferQueue* read_queue = nullptr;
+  EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
+
+  const int kTimeoutMs = 0;
+  int fence_fd = -1;
+  EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd));
+
+  TestMeta seq = 42U;
+  EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, &seq, sizeof(seq)));
+  EXPECT_EQ(0, dvrWriteBufferClear(wb));
+  dvrWriteBufferDestroy(wb);
+  wb = nullptr;
+
+  // Dequeue with wrong metadata will cause EINVAL.
+  int8_t wrong_metadata;
+  EXPECT_EQ(-EINVAL,
+            dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd,
+                                      &wrong_metadata, sizeof(wrong_metadata)));
+  EXPECT_FALSE(dvrReadBufferIsValid(rb));
+
+  // Dequeue with empty metadata will cause EINVAL.
+  EXPECT_EQ(-EINVAL, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb,
+                                               &fence_fd, nullptr, 0));
+  EXPECT_FALSE(dvrReadBufferIsValid(rb));
+}
+
 }  // namespace
 
 }  // namespace dvr