Merge "egl: handle failed eglMakeCurrent EGL_NO_CONTEXT" into oc-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index dec23d3..3041467 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -2249,13 +2249,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 7f7fa74..4011315 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -109,7 +109,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 6185ecb..f09a397 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -74,7 +74,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/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index b20a807..296b87d 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1182,13 +1182,7 @@
             ALOGE("installd cannot compute input vdex location for '%s'\n", path);
             return false;
         }
-        if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE) {
-            // When we dex2oat because of boot image change, we are going to update
-            // in-place the vdex file.
-            in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDWR, 0));
-        } else {
-            in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
-        }
+        in_vdex_wrapper_fd->reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
     }
 
     // Infer the name of the output VDEX and create it.
@@ -1197,27 +1191,12 @@
         return false;
     }
 
-    // If we are compiling because the boot image is out of date, we do not
-    // need to recreate a vdex, and can use the same existing one.
-    if (dexopt_action == DEX2OAT_FOR_BOOT_IMAGE &&
-            in_vdex_wrapper_fd->get() != -1 &&
-            in_vdex_path_str == out_vdex_path_str) {
-        // We unlink the file in case the invocation of dex2oat fails, to ensure we don't
-        // have bogus stale vdex files.
-        out_vdex_wrapper_fd->reset(
-              in_vdex_wrapper_fd->get(),
-              [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
-        // Disable auto close for the in wrapper fd (it will be done when destructing the out
-        // wrapper).
-        in_vdex_wrapper_fd->DisableAutoClose();
-    } else {
-        out_vdex_wrapper_fd->reset(
-              open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
-              [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
-        if (out_vdex_wrapper_fd->get() < 0) {
-            ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str());
-            return false;
-        }
+    out_vdex_wrapper_fd->reset(
+          open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
+          [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
+    if (out_vdex_wrapper_fd->get() < 0) {
+        ALOGE("installd cannot open vdex'%s' during dexopt\n", out_vdex_path_str.c_str());
+        return false;
     }
     if (!set_permissions_and_ownership(out_vdex_wrapper_fd->get(), is_public, uid,
             out_vdex_path_str.c_str(), is_secondary_dex)) {
@@ -1880,8 +1859,11 @@
     // Derive and delete the app image.
     bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
 
+    // Derive and delete the vdex file.
+    bool return_value_vdex = unlink_and_check(create_vdex_filename(out_path).c_str());
+
     // Report success.
-    return return_value_oat && return_value_art;
+    return return_value_oat && return_value_art && return_value_vdex;
 }
 
 }  // namespace installd
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 8b1d106..e8dc83e 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -160,6 +160,9 @@
 
     status_t getUniqueId(uint64_t* outId) const;
 
+    // Returns the CLOCK_MONOTONIC start time of the last dequeueBuffer call
+    nsecs_t getLastDequeueStartTime() const;
+
 protected:
     virtual ~Surface();
 
@@ -421,6 +424,9 @@
     nsecs_t mLastDequeueDuration = 0;
     nsecs_t mLastQueueDuration = 0;
 
+    // Stores the time right before we call IGBP::dequeueBuffer
+    nsecs_t mLastDequeueStartTime = 0;
+
     Condition mQueueBufferCondition;
 
     uint64_t mNextFrameNumber = 1;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 6583a62..7b2b5c3 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -501,13 +501,13 @@
 
     int buf = -1;
     sp<Fence> fence;
-    nsecs_t now = systemTime();
+    nsecs_t startTime = systemTime();
 
     FrameEventHistoryDelta frameTimestamps;
     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
             reqWidth, reqHeight, reqFormat, reqUsage,
             enableFrameTimestamps ? &frameTimestamps : nullptr);
-    mLastDequeueDuration = systemTime() - now;
+    mLastDequeueDuration = systemTime() - startTime;
 
     if (result < 0) {
         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
@@ -524,6 +524,9 @@
 
     Mutex::Autolock lock(mMutex);
 
+    // Write this while holding the mutex
+    mLastDequeueStartTime = startTime;
+
     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
 
     // this should never happen
@@ -1699,6 +1702,11 @@
     return mGraphicBufferProducer->getUniqueId(outId);
 }
 
+nsecs_t Surface::getLastDequeueStartTime() const {
+    Mutex::Autolock lock(mMutex);
+    return mLastDequeueStartTime;
+}
+
 status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) {
     if (out == nullptr) {
         ALOGE("%s: out must not be null!", __FUNCTION__);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index fcaa23a..81820de 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -393,6 +393,22 @@
     ASSERT_LE(removedBuffers.size(), 1u);
 }
 
+TEST_F(SurfaceTest, TestGetLastDequeueStartTime) {
+    sp<ANativeWindow> anw(mSurface);
+    ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU));
+
+    ANativeWindowBuffer* buffer = nullptr;
+    int32_t fenceFd = -1;
+
+    nsecs_t before = systemTime(CLOCK_MONOTONIC);
+    anw->dequeueBuffer(anw.get(), &buffer, &fenceFd);
+    nsecs_t after = systemTime(CLOCK_MONOTONIC);
+
+    nsecs_t lastDequeueTime = mSurface->getLastDequeueStartTime();
+    ASSERT_LE(before, lastDequeueTime);
+    ASSERT_GE(after, lastDequeueTime);
+}
+
 class FakeConsumer : public BnConsumerListener {
 public:
     void onFrameAvailable(const BufferItem& /*item*/) override {}
@@ -1568,4 +1584,4 @@
     EXPECT_EQ(-1, outDisplayPresentTime);
 }
 
-}
+} // namespace android