Merge changes If30bfa71,Ib8f78967 into oc-dev

* changes:
  pdx_benchmarks: Let the service create sockets by itself
  libpdx_uds: Fix send/receive over socket to handle signal interrupts
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index facb189..e9d06d1 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -177,9 +177,20 @@
   return count;
 }
 
+static const char* get_location_from_path(const char* path) {
+    static constexpr char kLocationSeparator = '/';
+    const char *location = strrchr(path, kLocationSeparator);
+    if (location == NULL) {
+        return path;
+    } else {
+        // Skip the separator character.
+        return location + 1;
+    }
+}
+
 static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vdex_fd, int image_fd,
         const char* input_file_name, const char* output_file_name, int swap_fd,
-        const char *instruction_set, const char* compiler_filter, bool vm_safe_mode,
+        const char* instruction_set, const char* compiler_filter, bool vm_safe_mode,
         bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) {
     static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
 
@@ -189,6 +200,9 @@
         return;
     }
 
+    // Get the relative path to the input file.
+    const char* relative_input_file_name = get_location_from_path(input_file_name);
+
     char dex2oat_Xms_flag[kPropertyValueMax];
     bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0;
 
@@ -279,7 +293,7 @@
     char dex2oat_image_fd[arraysize("--app-image-fd=") + MAX_INT_LEN];
 
     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
-    sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
+    sprintf(zip_location_arg, "--zip-location=%s", relative_input_file_name);
     sprintf(input_vdex_fd_arg, "--input-vdex-fd=%d", input_vdex_fd);
     sprintf(output_vdex_fd_arg, "--output-vdex-fd=%d", output_vdex_fd);
     sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
@@ -341,8 +355,18 @@
         sprintf(profile_arg, "--profile-file-fd=%d", profile_fd);
     }
 
+    // Get the directory of the apk to pass as a base classpath directory.
+    char base_dir[arraysize("--classpath-dir=") + PKG_PATH_MAX];
+    std::string apk_dir(input_file_name);
+    unsigned long dir_index = apk_dir.rfind('/');
+    bool has_base_dir = dir_index != std::string::npos;
+    if (has_base_dir) {
+        apk_dir = apk_dir.substr(0, dir_index);
+        sprintf(base_dir, "--classpath-dir=%s", apk_dir.c_str());
+    }
 
-    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
+
+    ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, relative_input_file_name, output_file_name);
 
     const char* argv[9  // program name, mandatory arguments and the final NULL
                      + (have_dex2oat_isa_variant ? 1 : 0)
@@ -360,6 +384,7 @@
                      + dex2oat_flags_count
                      + (profile_fd == -1 ? 0 : 1)
                      + (shared_libraries != nullptr ? 4 : 0)
+                     + (has_base_dir ? 1 : 0)
                      + (have_dex2oat_large_app_threshold ? 1 : 0)];
     int i = 0;
     argv[i++] = DEX2OAT_BIN;
@@ -424,6 +449,9 @@
         argv[i++] = RUNTIME_ARG;
         argv[i++] = shared_libraries;
     }
+    if (has_base_dir) {
+        argv[i++] = base_dir;
+    }
     // Do not add after dex2oat_flags, they should override others for debugging.
     argv[i] = NULL;
 
@@ -761,17 +789,6 @@
     exit(68);   /* only get here on exec failure */
 }
 
-static const char* get_location_from_path(const char* path) {
-    static constexpr char kLocationSeparator = '/';
-    const char *location = strrchr(path, kLocationSeparator);
-    if (location == NULL) {
-        return path;
-    } else {
-        // Skip the separator character.
-        return location + 1;
-    }
-}
-
 bool dump_profiles(int32_t uid, const std::string& pkgname, const char* code_paths) {
     std::vector<unique_fd> profile_fds;
     unique_fd reference_profile_fd;
@@ -1548,14 +1565,12 @@
             _exit(67);
         }
 
-        // Pass dex2oat the relative path to the input file.
-        const char *input_file_name = get_location_from_path(dex_path);
         run_dex2oat(input_fd.get(),
                     out_oat_fd.get(),
                     in_vdex_fd.get(),
                     out_vdex_fd.get(),
                     image_fd.get(),
-                    input_file_name,
+                    dex_path,
                     out_oat_path,
                     swap_fd.get(),
                     instruction_set,
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 78eadf2..ae4c797 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -789,40 +789,8 @@
         return false;
     }
 
-    int RunPreopt() {
-        if (ShouldSkipPreopt()) {
-            return 0;
-        }
-
-        int dexopt_result = dexopt(package_parameters_.apk_path,
-                                   package_parameters_.uid,
-                                   package_parameters_.pkgName,
-                                   package_parameters_.instruction_set,
-                                   package_parameters_.dexopt_needed,
-                                   package_parameters_.oat_dir,
-                                   package_parameters_.dexopt_flags,
-                                   package_parameters_.compiler_filter,
-                                   package_parameters_.volume_uuid,
-                                   package_parameters_.shared_libraries,
-                                   package_parameters_.se_info);
-        if (dexopt_result == 0) {
-            return 0;
-        }
-
-        // If the dexopt failed, we may have a stale boot image from a previous OTA run.
-        // Then regenerate and retry.
-        if (WEXITSTATUS(dexopt_result) !=
-                static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
-            return dexopt_result;
-        }
-
-        if (!PrepareBootImage(/* force */ true)) {
-            LOG(ERROR) << "Forced boot image creating failed. Original error return was "
-                         << dexopt_result;
-            return dexopt_result;
-        }
-
-        LOG(WARNING) << "Original dexopt failed, re-trying after boot image was regenerated.";
+    // Run dexopt with the parameters of package_parameters_.
+    int Dexopt() {
         return dexopt(package_parameters_.apk_path,
                       package_parameters_.uid,
                       package_parameters_.pkgName,
@@ -836,6 +804,43 @@
                       package_parameters_.se_info);
     }
 
+    int RunPreopt() {
+        if (ShouldSkipPreopt()) {
+            return 0;
+        }
+
+        int dexopt_result = Dexopt();
+        if (dexopt_result == 0) {
+            return 0;
+        }
+
+        // If the dexopt failed, we may have a stale boot image from a previous OTA run.
+        // Then regenerate and retry.
+        if (WEXITSTATUS(dexopt_result) ==
+                static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
+            if (!PrepareBootImage(/* force */ true)) {
+                LOG(ERROR) << "Forced boot image creating failed. Original error return was "
+                        << dexopt_result;
+                return dexopt_result;
+            }
+
+            int dexopt_result_boot_image_retry = Dexopt();
+            if (dexopt_result_boot_image_retry == 0) {
+                return 0;
+            }
+        }
+
+        // If this was a profile-guided run, we may have profile version issues. Try to downgrade,
+        // if possible.
+        if ((package_parameters_.dexopt_flags & DEXOPT_PROFILE_GUIDED) == 0) {
+            return dexopt_result;
+        }
+
+        LOG(WARNING) << "Downgrading compiler filter in an attempt to progress compilation";
+        package_parameters_.dexopt_flags &= ~DEXOPT_PROFILE_GUIDED;
+        return Dexopt();
+    }
+
     ////////////////////////////////////
     // Helpers, mostly taken from ART //
     ////////////////////////////////////
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 5810335..9250806 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -487,6 +487,7 @@
     // is considered a no-op.
     //
     // Return of a value other than NO_ERROR means an error has occurred:
+    // * NO_INIT - the producer is not connected
     // * BAD_VALUE - one of the following has occurred:
     //             * the api specified does not match the one that was connected
     //             * api was out of range (see above).
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index a540ab9..49552dc 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1267,7 +1267,10 @@
                     mCore->mSidebandStream.clear();
                     mCore->mDequeueCondition.broadcast();
                     listener = mCore->mConsumerListener;
-                } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+                } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+                    BQ_LOGE("disconnect: not connected (req=%d)", api);
+                    status = NO_INIT;
+                } else {
                     BQ_LOGE("disconnect: still connected to another API "
                             "(cur=%d req=%d)", mCore->mConnectedApi, api);
                     status = BAD_VALUE;
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 893c0a6..60c1277 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -1181,4 +1181,21 @@
     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
 }
 
+TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
+    createBufferQueue();
+    sp<DummyConsumer> dc(new DummyConsumer);
+    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
+    IGraphicBufferProducer::QueueBufferOutput output;
+    sp<IProducerListener> dummyListener(new DummyProducerListener);
+    ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+    ASSERT_EQ(OK, mProducer->connect(
+            dummyListener, NATIVE_WINDOW_API_CPU, true, &output));
+    ASSERT_EQ(BAD_VALUE, mProducer->connect(
+            dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output));
+
+    ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
+    ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+    ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
+}
+
 } // namespace android
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index ebd7da0..e236c31 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -450,7 +450,9 @@
 
   std::unique_lock<std::mutex> lock(core_->mutex_);
 
-  if (api != core_->connected_api_) {
+  if (BufferHubQueueCore::kNoConnectedApi == core_->connected_api_) {
+    return NO_INIT;
+  } else if (api != core_->connected_api_) {
     return BAD_VALUE;
   }
 
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
index e7fdb91..28820e7 100644
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -1,5 +1,6 @@
 #include "include/dvr/dvr_buffer.h"
 
+#include <android/hardware_buffer.h>
 #include <private/dvr/buffer_hub_client.h>
 #include <ui/GraphicBuffer.h>
 
@@ -54,6 +55,16 @@
       false /* keep ownership */));
 }
 
+int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
+                             AHardwareBuffer** hardware_buffer) {
+  if (!hardware_buffer || !graphic_buffer) {
+    return -EINVAL;
+  }
+  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(graphic_buffer);
+  AHardwareBuffer_acquire(*hardware_buffer);
+  return 0;
+}
+
 }  // anonymous namespace
 
 extern "C" {
@@ -68,9 +79,8 @@
 
 int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer) {
-  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
-      write_buffer->write_buffer->buffer()->buffer().get());
-  return 0;
+  return ConvertToAHardwareBuffer(
+      write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
 int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
@@ -99,9 +109,8 @@
 
 int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer) {
-  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
-      read_buffer->read_buffer->buffer()->buffer().get());
-  return 0;
+  return ConvertToAHardwareBuffer(
+      read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
 }
 
 int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
@@ -127,13 +136,8 @@
 
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
                                 AHardwareBuffer** hardware_buffer) {
-  if (!hardware_buffer) {
-    return -EINVAL;
-  }
-
-  *hardware_buffer =
-      reinterpret_cast<AHardwareBuffer*>(buffer->buffer->buffer().get());
-  return 0;
+  return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(),
+                                  hardware_buffer);
 }
 
 const struct native_handle* dvrWriteBufferGetNativeHandle(
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
index b2cf0d7..3e8357c 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -18,6 +18,7 @@
 // Write buffer
 void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
 int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
+// Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer);
 int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
@@ -30,6 +31,7 @@
 // Read buffer
 void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
 int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
+// Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer);
 int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
@@ -41,6 +43,7 @@
 
 // Buffer
 void dvrBufferDestroy(DvrBuffer* buffer);
+// Caller must call AHardwareBuffer_release on hardware_buffer.
 int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
                                 AHardwareBuffer** hardware_buffer);
 const struct native_handle* dvrBufferGetNativeHandle(DvrBuffer* buffer);
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
index 52531a9..2866f47 100644
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -42,11 +42,12 @@
   AHardwareBuffer* hardware_buffer1 = nullptr;
   int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
   ASSERT_EQ(0, e1);
+  ASSERT_NE(nullptr, hardware_buffer1);
 
   AHardwareBuffer* hardware_buffer2 = nullptr;
   int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
   ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer1);
+  ASSERT_NE(nullptr, hardware_buffer2);
 
   AHardwareBuffer_Desc desc1 = {};
   AHardwareBuffer_describe(hardware_buffer1, &desc1);
@@ -88,6 +89,10 @@
   ASSERT_EQ(desc3.usage1, 0u);
 
   dvrBufferDestroy(buffer3);
+
+  AHardwareBuffer_release(hardware_buffer1);
+  AHardwareBuffer_release(hardware_buffer2);
+  AHardwareBuffer_release(hardware_buffer3);
 }
 
 TEST_F(DvrNamedBufferTest, TestMultipleNamedBuffers) {
@@ -141,6 +146,7 @@
   ASSERT_EQ(desc.usage0, AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE);
 
   dvrBufferDestroy(setup_buffer);
+  AHardwareBuffer_release(hardware_buffer);
 }