Merge "Always set refresh rate change callback in scheduler" into qt-dev
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index c730ab9..59c19d1 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -581,10 +581,6 @@
             // No code cache on shared storage
         } else {
             // Clear everything on shared storage
-            path = StringPrintf("%s/Android/sandbox/%s", extPath.c_str(), pkgname);
-            if (delete_dir_contents(path, true) != 0) {
-                res = error("Failed to delete contents of " + path);
-            }
             path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
             if (delete_dir_contents(path, true) != 0) {
                 res = error("Failed to delete contents of " + path);
@@ -668,10 +664,6 @@
         }
 
         auto extPath = findDataMediaPath(uuid, userId);
-        path = StringPrintf("%s/Android/sandbox/%s", extPath.c_str(), pkgname);
-        if (delete_dir_contents_and_dir(path, true) != 0) {
-            res = error("Failed to delete " + path);
-        }
         path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
         if (delete_dir_contents_and_dir(path, true) != 0) {
             res = error("Failed to delete " + path);
@@ -1694,8 +1686,6 @@
             }
 
             ATRACE_BEGIN("external");
-            auto sandboxPath = create_data_media_package_path(uuid_, userId, "sandbox", pkgname);
-            calculate_tree_size(sandboxPath, &extStats.dataSize);
             auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname);
             collectManualStats(extPath, &extStats);
             auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname);
diff --git a/include/audiomanager/IAudioManager.h b/include/audiomanager/IAudioManager.h
index d0642c6..2f5ccb8 100644
--- a/include/audiomanager/IAudioManager.h
+++ b/include/audiomanager/IAudioManager.h
@@ -38,6 +38,7 @@
         RELEASE_PLAYER                        = IBinder::FIRST_CALL_TRANSACTION + 3,
         TRACK_RECORDER                        = IBinder::FIRST_CALL_TRANSACTION + 4,
         RECORDER_EVENT                        = IBinder::FIRST_CALL_TRANSACTION + 5,
+        RELEASE_RECORDER                      = IBinder::FIRST_CALL_TRANSACTION + 6,
     };
 
     DECLARE_META_INTERFACE(AudioManager)
@@ -52,6 +53,7 @@
     /*oneway*/ virtual status_t releasePlayer(audio_unique_id_t piid) = 0;
     virtual audio_unique_id_t trackRecorder(const sp<IBinder>& recorder) = 0;
     /*oneway*/ virtual status_t recorderEvent(audio_unique_id_t riid, recorder_state_t event) = 0;
+    /*oneway*/ virtual status_t releaseRecorder(audio_unique_id_t riid) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/graphicsenv/GpuStatsInfo.cpp b/libs/graphicsenv/GpuStatsInfo.cpp
index f89b4c1..4a801be 100644
--- a/libs/graphicsenv/GpuStatsInfo.cpp
+++ b/libs/graphicsenv/GpuStatsInfo.cpp
@@ -37,6 +37,8 @@
     if ((status = parcel->writeInt32(vulkanVersion)) != OK) return status;
     if ((status = parcel->writeInt32(cpuVulkanVersion)) != OK) return status;
     if ((status = parcel->writeInt32(glesVersion)) != OK) return status;
+    if ((status = parcel->writeInt32(angleLoadingCount)) != OK) return status;
+    if ((status = parcel->writeInt32(angleLoadingFailureCount)) != OK) return status;
     return OK;
 }
 
@@ -53,6 +55,8 @@
     if ((status = parcel->readInt32(&vulkanVersion)) != OK) return status;
     if ((status = parcel->readInt32(&cpuVulkanVersion)) != OK) return status;
     if ((status = parcel->readInt32(&glesVersion)) != OK) return status;
+    if ((status = parcel->readInt32(&angleLoadingCount)) != OK) return status;
+    if ((status = parcel->readInt32(&angleLoadingFailureCount)) != OK) return status;
     return OK;
 }
 
@@ -64,6 +68,8 @@
     StringAppendF(&result, "driverBuildTime = %" PRId64 "\n", driverBuildTime);
     StringAppendF(&result, "glLoadingCount = %d\n", glLoadingCount);
     StringAppendF(&result, "glLoadingFailureCount = %d\n", glLoadingFailureCount);
+    StringAppendF(&result, "angleLoadingCount = %d\n", angleLoadingCount);
+    StringAppendF(&result, "angleLoadingFailureCount = %d\n", angleLoadingFailureCount);
     StringAppendF(&result, "vkLoadingCount = %d\n", vkLoadingCount);
     StringAppendF(&result, "vkLoadingFailureCount = %d\n", vkLoadingFailureCount);
     StringAppendF(&result, "vulkanVersion = %d\n", vulkanVersion);
@@ -78,6 +84,8 @@
     if ((status = parcel->writeUint64(driverVersionCode)) != OK) return status;
     if ((status = parcel->writeInt64Vector(glDriverLoadingTime)) != OK) return status;
     if ((status = parcel->writeInt64Vector(vkDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->writeInt64Vector(angleDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->writeBool(cpuVulkanInUse)) != OK) return status;
     return OK;
 }
 
@@ -87,6 +95,8 @@
     if ((status = parcel->readUint64(&driverVersionCode)) != OK) return status;
     if ((status = parcel->readInt64Vector(&glDriverLoadingTime)) != OK) return status;
     if ((status = parcel->readInt64Vector(&vkDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->readInt64Vector(&angleDriverLoadingTime)) != OK) return status;
+    if ((status = parcel->readBool(&cpuVulkanInUse)) != OK) return status;
     return OK;
 }
 
@@ -94,11 +104,17 @@
     std::string result;
     StringAppendF(&result, "appPackageName = %s\n", appPackageName.c_str());
     StringAppendF(&result, "driverVersionCode = %" PRIu64 "\n", driverVersionCode);
+    StringAppendF(&result, "cpuVulkanInUse = %d\n", cpuVulkanInUse);
     result.append("glDriverLoadingTime:");
     for (int32_t loadingTime : glDriverLoadingTime) {
         StringAppendF(&result, " %d", loadingTime);
     }
     result.append("\n");
+    result.append("angleDriverLoadingTime:");
+    for (int32_t loadingTime : angleDriverLoadingTime) {
+        StringAppendF(&result, " %d", loadingTime);
+    }
+    result.append("\n");
     result.append("vkDriverLoadingTime:");
     for (int32_t loadingTime : vkDriverLoadingTime) {
         StringAppendF(&result, " %d", loadingTime);
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 8728f03..407f77d 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -160,6 +160,22 @@
     mSphalLibraries = sphalLibraries;
 }
 
+void GraphicsEnv::hintActivityLaunch() {
+    ATRACE_CALL();
+
+    // If there's already graphics driver preloaded in the process, just send
+    // the stats info to GpuStats directly through async binder.
+    std::lock_guard<std::mutex> lock(mStatsLock);
+    if (mGpuStats.glDriverToSend) {
+        mGpuStats.glDriverToSend = false;
+        sendGpuStatsLocked(GraphicsEnv::Api::API_GL, true, mGpuStats.glDriverLoadingTime);
+    }
+    if (mGpuStats.vkDriverToSend) {
+        mGpuStats.vkDriverToSend = false;
+        sendGpuStatsLocked(GraphicsEnv::Api::API_VK, true, mGpuStats.vkDriverLoadingTime);
+    }
+}
+
 void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
                               const std::string& driverVersionName, uint64_t driverVersionCode,
                               int64_t driverBuildTime, const std::string& appPackageName,
@@ -220,34 +236,21 @@
     }
 }
 
-void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isLoaded, int64_t driverLoadingTime) {
+void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isDriverLoaded,
+                                  int64_t driverLoadingTime) {
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mStatsLock);
-    GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
-    bool isIntendedDriverLoaded = false;
+    const bool doNotSend = mGpuStats.appPackageName.empty();
     if (api == GraphicsEnv::Api::API_GL) {
-        driver = mGpuStats.glDriverToLoad;
-        isIntendedDriverLoaded = isLoaded &&
-                ((mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) ||
-                 (mGpuStats.glDriverToLoad == mGpuStats.glDriverFallback));
+        if (doNotSend) mGpuStats.glDriverToSend = true;
+        mGpuStats.glDriverLoadingTime = driverLoadingTime;
     } else {
-        driver = mGpuStats.vkDriverToLoad;
-        isIntendedDriverLoaded =
-                isLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+        if (doNotSend) mGpuStats.vkDriverToSend = true;
+        mGpuStats.vkDriverLoadingTime = driverLoadingTime;
     }
 
-    sendGpuStatsLocked(driver, isIntendedDriverLoaded, driverLoadingTime);
-}
-
-void GraphicsEnv::clearDriverLoadingInfo(GraphicsEnv::Api api) {
-    ATRACE_CALL();
-
-    std::lock_guard<std::mutex> lock(mStatsLock);
-    if (api == GraphicsEnv::Api::API_GL) {
-        mGpuStats.glDriverToLoad = GraphicsEnv::Driver::NONE;
-        mGpuStats.glDriverFallback = GraphicsEnv::Driver::NONE;
-    }
+    sendGpuStatsLocked(api, isDriverLoaded, driverLoadingTime);
 }
 
 static sp<IGpuService> getGpuService() {
@@ -260,7 +263,18 @@
     return interface_cast<IGpuService>(binder);
 }
 
-void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Driver driver, bool isDriverLoaded,
+void GraphicsEnv::setCpuVulkanInUse() {
+    ATRACE_CALL();
+
+    // Use the same stats lock to protect getGpuService() as well.
+    std::lock_guard<std::mutex> lock(mStatsLock);
+    const sp<IGpuService> gpuService = getGpuService();
+    if (gpuService) {
+        gpuService->setCpuVulkanInUse(mGpuStats.appPackageName, mGpuStats.driverVersionCode);
+    }
+}
+
+void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Api api, bool isDriverLoaded,
                                      int64_t driverLoadingTime) {
     ATRACE_CALL();
 
@@ -274,19 +288,31 @@
           "\tdriverBuildTime[%" PRId64 "]\n"
           "\tappPackageName[%s]\n"
           "\tvulkanVersion[%d]\n"
-          "\tdriver[%d]\n"
+          "\tapi[%d]\n"
           "\tisDriverLoaded[%d]\n"
           "\tdriverLoadingTime[%" PRId64 "]",
           mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
           mGpuStats.driverVersionCode, mGpuStats.driverBuildTime, mGpuStats.appPackageName.c_str(),
-          mGpuStats.vulkanVersion, static_cast<int32_t>(driver), isDriverLoaded, driverLoadingTime);
+          mGpuStats.vulkanVersion, static_cast<int32_t>(api), isDriverLoaded, driverLoadingTime);
+
+    GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
+    bool isIntendedDriverLoaded = false;
+    if (api == GraphicsEnv::Api::API_GL) {
+        driver = mGpuStats.glDriverToLoad;
+        isIntendedDriverLoaded =
+                isDriverLoaded && (mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE);
+    } else {
+        driver = mGpuStats.vkDriverToLoad;
+        isIntendedDriverLoaded =
+                isDriverLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+    }
 
     const sp<IGpuService> gpuService = getGpuService();
     if (gpuService) {
         gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
                                 mGpuStats.driverVersionCode, mGpuStats.driverBuildTime,
                                 mGpuStats.appPackageName, mGpuStats.vulkanVersion, driver,
-                                isDriverLoaded, driverLoadingTime);
+                                isIntendedDriverLoaded, driverLoadingTime);
     }
 }
 
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 100dca5..5f96249 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -91,6 +91,17 @@
         outStats->clear();
         return reply.readParcelableVector(outStats);
     }
+
+    virtual void setCpuVulkanInUse(const std::string& appPackageName,
+                                   const uint64_t driverVersionCode) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
+
+        data.writeUtf8AsUtf16(appPackageName);
+        data.writeUint64(driverVersionCode);
+
+        remote()->transact(BnGpuService::SET_CPU_VULKAN_IN_USE, data, &reply, IBinder::FLAG_ONEWAY);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(GpuService, "android.graphicsenv.IGpuService");
@@ -163,6 +174,19 @@
 
             return OK;
         }
+        case SET_CPU_VULKAN_IN_USE: {
+            CHECK_INTERFACE(IGpuService, data, reply);
+
+            std::string appPackageName;
+            if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
+
+            uint64_t driverVersionCode;
+            if ((status = data.readUint64(&driverVersionCode)) != OK) return status;
+
+            setCpuVulkanInUse(appPackageName, driverVersionCode);
+
+            return OK;
+        }
         case SHELL_COMMAND_TRANSACTION: {
             int in = data.readFileDescriptor();
             int out = data.readFileDescriptor();
diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
index 98ab02b..edcccfe 100644
--- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
+++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
@@ -47,6 +47,8 @@
     int32_t vulkanVersion = 0;
     int32_t cpuVulkanVersion = 0;
     int32_t glesVersion = 0;
+    int32_t angleLoadingCount = 0;
+    int32_t angleLoadingFailureCount = 0;
 };
 
 /*
@@ -66,6 +68,8 @@
     uint64_t driverVersionCode = 0;
     std::vector<int64_t> glDriverLoadingTime = {};
     std::vector<int64_t> vkDriverLoadingTime = {};
+    std::vector<int64_t> angleDriverLoadingTime = {};
+    bool cpuVulkanInUse = false;
 };
 
 } // namespace android
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index b10cab7..7d62750 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -55,6 +55,10 @@
         Driver glDriverFallback;
         Driver vkDriverToLoad;
         Driver vkDriverFallback;
+        bool glDriverToSend;
+        bool vkDriverToSend;
+        int64_t glDriverLoadingTime;
+        int64_t vkDriverLoadingTime;
 
         GpuStats()
               : driverPackageName(""),
@@ -66,7 +70,11 @@
                 glDriverToLoad(Driver::NONE),
                 glDriverFallback(Driver::NONE),
                 vkDriverToLoad(Driver::NONE),
-                vkDriverFallback(Driver::NONE) {}
+                vkDriverFallback(Driver::NONE),
+                glDriverToSend(false),
+                vkDriverToSend(false),
+                glDriverLoadingTime(0),
+                vkDriverLoadingTime(0) {}
     };
 
 public:
@@ -84,13 +92,14 @@
     // which is required by android_link_namespaces.
     void setDriverPathAndSphalLibraries(const std::string path, const std::string sphalLibraries);
     android_namespace_t* getDriverNamespace();
+    void hintActivityLaunch();
     void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
                      uint64_t versionCode, int64_t driverBuildTime,
                      const std::string& appPackageName, const int32_t vulkanVersion);
+    void setCpuVulkanInUse();
     void setDriverToLoad(Driver driver);
     void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
-    void clearDriverLoadingInfo(Api api);
-    void sendGpuStatsLocked(Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
+    void sendGpuStatsLocked(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
 
     bool shouldUseAngle(std::string appName);
     bool shouldUseAngle();
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
index 5bf0269..34f1c7e 100644
--- a/libs/graphicsenv/include/graphicsenv/IGpuService.h
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -40,6 +40,10 @@
                              const int32_t vulkanVersion, GraphicsEnv::Driver driver,
                              bool isDriverLoaded, int64_t driverLoadingTime) = 0;
 
+    // set CPU Vulkan in use signal from GraphicsEnvironment.
+    virtual void setCpuVulkanInUse(const std::string& appPackageName,
+                                   const uint64_t driverVersionCode) = 0;
+
     // get GPU global stats from GpuStats module.
     virtual status_t getGpuStatsGlobalInfo(std::vector<GpuStatsGlobalInfo>* outStats) const = 0;
 
@@ -53,6 +57,7 @@
         SET_GPU_STATS = IBinder::FIRST_CALL_TRANSACTION,
         GET_GPU_STATS_GLOBAL_INFO,
         GET_GPU_STATS_APP_INFO,
+        SET_CPU_VULKAN_IN_USE,
         // Always append new enum to the end.
     };
 
diff --git a/services/audiomanager/IAudioManager.cpp b/services/audiomanager/IAudioManager.cpp
index f5d4826..6235f06 100644
--- a/services/audiomanager/IAudioManager.cpp
+++ b/services/audiomanager/IAudioManager.cpp
@@ -122,6 +122,13 @@
         data.writeInt32((int32_t) event);
         return remote()->transact(RECORDER_EVENT, data, &reply, IBinder::FLAG_ONEWAY);
     }
+
+    virtual status_t releaseRecorder(audio_unique_id_t riid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioManager::getInterfaceDescriptor());
+        data.writeInt32((int32_t) riid);
+        return remote()->transact(RELEASE_RECORDER, data, &reply, IBinder::FLAG_ONEWAY);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioManager, "android.media.IAudioService");
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index b42884e..8accf9d 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -75,6 +75,13 @@
     return OK;
 }
 
+void GpuService::setCpuVulkanInUse(const std::string& appPackageName,
+                                   const uint64_t driverVersionCode) {
+    ATRACE_CALL();
+
+    mGpuStats->setCpuVulkanInUse(appPackageName, driverVersionCode);
+}
+
 status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
     ATRACE_CALL();
 
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index 3e02b4a..8226901 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -50,6 +50,8 @@
                      int64_t driverLoadingTime) override;
     status_t getGpuStatsGlobalInfo(std::vector<GpuStatsGlobalInfo>* outStats) const override;
     status_t getGpuStatsAppInfo(std::vector<GpuStatsAppInfo>* outStats) const override;
+    void setCpuVulkanInUse(const std::string& appPackageName,
+                           const uint64_t driverVersionCode) override;
 
     /*
      * IBinder interface
diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp
index 5174c86..37c6abc 100644
--- a/services/gpuservice/gpustats/GpuStats.cpp
+++ b/services/gpuservice/gpustats/GpuStats.cpp
@@ -27,7 +27,7 @@
 
 namespace android {
 
-static bool addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
+static void addLoadingCount(GraphicsEnv::Driver driver, bool isDriverLoaded,
                             GpuStatsGlobalInfo* const outGlobalInfo) {
     switch (driver) {
         case GraphicsEnv::Driver::GL:
@@ -40,13 +40,13 @@
             outGlobalInfo->vkLoadingCount++;
             if (!isDriverLoaded) outGlobalInfo->vkLoadingFailureCount++;
             break;
+        case GraphicsEnv::Driver::ANGLE:
+            outGlobalInfo->angleLoadingCount++;
+            if (!isDriverLoaded) outGlobalInfo->angleLoadingFailureCount++;
+            break;
         default:
-            // Currently we don't support GraphicsEnv::Driver::ANGLE because the
-            // basic driver package info only belongs to system or updated driver.
-            return false;
+            break;
     }
-
-    return true;
 }
 
 static void addLoadingTime(GraphicsEnv::Driver driver, int64_t driverLoadingTime,
@@ -54,13 +54,20 @@
     switch (driver) {
         case GraphicsEnv::Driver::GL:
         case GraphicsEnv::Driver::GL_UPDATED:
-            if (outAppInfo->glDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
-            outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+            if (outAppInfo->glDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->glDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
             break;
         case GraphicsEnv::Driver::VULKAN:
         case GraphicsEnv::Driver::VULKAN_UPDATED:
-            if (outAppInfo->vkDriverLoadingTime.size() >= GpuStats::MAX_NUM_LOADING_TIMES) break;
-            outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+            if (outAppInfo->vkDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->vkDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
+            break;
+        case GraphicsEnv::Driver::ANGLE:
+            if (outAppInfo->angleDriverLoadingTime.size() < GpuStats::MAX_NUM_LOADING_TIMES) {
+                outAppInfo->angleDriverLoadingTime.emplace_back(driverLoadingTime);
+            }
             break;
         default:
             break;
@@ -90,26 +97,24 @@
 
     if (!mGlobalStats.count(driverVersionCode)) {
         GpuStatsGlobalInfo globalInfo;
-        if (!addLoadingCount(driver, isDriverLoaded, &globalInfo)) {
-            return;
-        }
+        addLoadingCount(driver, isDriverLoaded, &globalInfo);
         globalInfo.driverPackageName = driverPackageName;
         globalInfo.driverVersionName = driverVersionName;
         globalInfo.driverVersionCode = driverVersionCode;
         globalInfo.driverBuildTime = driverBuildTime;
         globalInfo.vulkanVersion = vulkanVersion;
         mGlobalStats.insert({driverVersionCode, globalInfo});
-    } else if (!addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode])) {
-        return;
-    }
-
-    if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
-        ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
-        return;
+    } else {
+        addLoadingCount(driver, isDriverLoaded, &mGlobalStats[driverVersionCode]);
     }
 
     const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
     if (!mAppStats.count(appStatsKey)) {
+        if (mAppStats.size() >= MAX_NUM_APP_RECORDS) {
+            ALOGV("GpuStatsAppInfo has reached maximum size. Ignore new stats.");
+            return;
+        }
+
         GpuStatsAppInfo appInfo;
         addLoadingTime(driver, driverLoadingTime, &appInfo);
         appInfo.appPackageName = appPackageName;
@@ -121,6 +126,16 @@
     addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
 }
 
+void GpuStats::setCpuVulkanInUse(const std::string& appPackageName,
+                                 const uint64_t driverVersionCode) {
+    const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode);
+    if (!mAppStats.count(appStatsKey)) {
+        return;
+    }
+
+    mAppStats[appStatsKey].cpuVulkanInUse = true;
+}
+
 void GpuStats::interceptSystemDriverStatsLocked() {
     // Append cpuVulkanVersion and glesVersion to system driver stats
     if (!mGlobalStats.count(0) || mGlobalStats[0].glesVersion) {
diff --git a/services/gpuservice/gpustats/GpuStats.h b/services/gpuservice/gpustats/GpuStats.h
index 49699ee..b293f59 100644
--- a/services/gpuservice/gpustats/GpuStats.h
+++ b/services/gpuservice/gpustats/GpuStats.h
@@ -37,6 +37,8 @@
                 uint64_t driverVersionCode, int64_t driverBuildTime,
                 const std::string& appPackageName, const int32_t vulkanVersion,
                 GraphicsEnv::Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
+    // Set CPU Vulkan in use signal into app stats.
+    void setCpuVulkanInUse(const std::string& appPackageName, const uint64_t driverVersionCode);
     // dumpsys interface
     void dump(const Vector<String16>& args, std::string* result);
     // Pull gpu global stats
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index be75c64..fcd4f29 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -539,6 +539,9 @@
     }
     Info& info(mActivationCount.editValueAt(activationIndex));
     info.removeBatchParamsForIdent(ident);
+    if (info.numActiveClients() == 0) {
+        info.isActive = false;
+    }
 }
 
 status_t SensorDevice::activate(void* ident, int handle, int enabled) {
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 639ce78..fa1e232 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1686,26 +1686,29 @@
     const int32_t opCode = sensor.getRequiredAppOp();
     const int32_t appOpMode = sAppOpsManager.checkOp(opCode,
             IPCThreadState::self()->getCallingUid(), opPackageName);
+    bool appOpAllowed = appOpMode == AppOpsManager::MODE_ALLOWED;
 
-    // Ensure that the AppOp is allowed
-    //
-    // This check is also required to ensure that the user hasn't revoked the necessary permissions
-    // to access the Step Detector and Step Counter when the application targets pre-Q. Without this
-    // check, if the user revokes the pre-Q install-time GMS Core AR permission, the app would
-    // still be able to receive Step Counter and Step Detector events.
     bool canAccess = false;
-    if (opCode >= 0 && appOpMode == AppOpsManager::MODE_ALLOWED) {
-        if (hasPermissionForSensor(sensor)) {
+    if (hasPermissionForSensor(sensor)) {
+        // Ensure that the AppOp is allowed, or that there is no necessary app op for the sensor
+        if (opCode < 0 || appOpAllowed) {
             canAccess = true;
-        } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER ||
-                   sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) {
-            int targetSdkVersion = getTargetSdkVersion(opPackageName);
-            // Allow access to the sensor if the application targets pre-Q, which is before the
-            // requirement to hold the AR permission to access Step Counter and Step Detector events
-            // was introduced.
-            if (targetSdkVersion > 0 && targetSdkVersion <= __ANDROID_API_P__) {
-                canAccess = true;
-            }
+        }
+    } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER ||
+            sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) {
+        int targetSdkVersion = getTargetSdkVersion(opPackageName);
+        // Allow access to the sensor if the application targets pre-Q, which is before the
+        // requirement to hold the AR permission to access Step Counter and Step Detector events
+        // was introduced, and the user hasn't revoked the app op.
+        //
+        // Verifying the app op is required to ensure that the user hasn't revoked the necessary
+        // permissions to access the Step Detector and Step Counter when the application targets
+        // pre-Q. Without this check, if the user revokes the pre-Q install-time GMS Core AR
+        // permission, the app would still be able to receive Step Counter and Step Detector events.
+        if (appOpAllowed &&
+                targetSdkVersion > 0 &&
+                targetSdkVersion <= __ANDROID_API_P__) {
+            canAccess = true;
         }
     }
 
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 0d14267..3684260 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -168,11 +168,8 @@
         mPhaseCallback(std::make_unique<SamplingOffsetCallback>(*this, mScheduler,
                                                                 tunables.mSamplingOffset)),
         lastSampleTime(0ns) {
-    {
-        std::lock_guard threadLock(mThreadMutex);
-        mThread = std::thread([this]() { threadMain(); });
-        pthread_setname_np(mThread.native_handle(), "RegionSamplingThread");
-    }
+    mThread = std::thread([this]() { threadMain(); });
+    pthread_setname_np(mThread.native_handle(), "RegionSamplingThread");
     mIdleTimer.start();
 }
 
@@ -186,12 +183,11 @@
     mIdleTimer.stop();
 
     {
-        std::lock_guard lock(mMutex);
+        std::lock_guard lock(mThreadControlMutex);
         mRunning = false;
         mCondition.notify_one();
     }
 
-    std::lock_guard threadLock(mThreadMutex);
     if (mThread.joinable()) {
         mThread.join();
     }
@@ -205,17 +201,17 @@
 
     sp<IBinder> asBinder = IInterface::asBinder(listener);
     asBinder->linkToDeath(this);
-    std::lock_guard lock(mMutex);
+    std::lock_guard lock(mSamplingMutex);
     mDescriptors.emplace(wp<IBinder>(asBinder), Descriptor{samplingArea, stopLayer, listener});
 }
 
 void RegionSamplingThread::removeListener(const sp<IRegionSamplingListener>& listener) {
-    std::lock_guard lock(mMutex);
+    std::lock_guard lock(mSamplingMutex);
     mDescriptors.erase(wp<IBinder>(IInterface::asBinder(listener)));
 }
 
 void RegionSamplingThread::checkForStaleLuma() {
-    std::lock_guard lock(mMutex);
+    std::lock_guard lock(mThreadControlMutex);
 
     if (mDiscardedFrames) {
         ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForZeroPhase));
@@ -233,7 +229,7 @@
 }
 
 void RegionSamplingThread::doSample() {
-    std::lock_guard lock(mMutex);
+    std::lock_guard lock(mThreadControlMutex);
     auto now = std::chrono::nanoseconds(systemTime(SYSTEM_TIME_MONOTONIC));
     if (lastSampleTime + mTunables.mSamplingPeriod > now) {
         ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::idleTimerWaiting));
@@ -254,7 +250,7 @@
 }
 
 void RegionSamplingThread::binderDied(const wp<IBinder>& who) {
-    std::lock_guard lock(mMutex);
+    std::lock_guard lock(mSamplingMutex);
     mDescriptors.erase(who);
 }
 
@@ -315,6 +311,7 @@
 
 void RegionSamplingThread::captureSample() {
     ATRACE_CALL();
+    std::lock_guard lock(mSamplingMutex);
 
     if (mDescriptors.empty()) {
         return;
@@ -387,19 +384,8 @@
                                    PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
     }
 
-    // When calling into SF, we post a message into the SF message queue (so the
-    // screen capture runs on the main thread). This message blocks until the
-    // screenshot is actually captured, but before the capture occurs, the main
-    // thread may perform a normal refresh cycle. At the end of this cycle, it
-    // can request another sample (because layers changed), which triggers a
-    // call into sampleNow. When sampleNow attempts to grab the mutex, we can
-    // deadlock.
-    //
-    // To avoid this, we drop the mutex while we call into SF.
-    mMutex.unlock();
     bool ignored;
     mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false, ignored);
-    mMutex.lock();
 
     std::vector<Descriptor> activeDescriptors;
     for (const auto& descriptor : descriptors) {
@@ -429,15 +415,19 @@
     ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
 }
 
-void RegionSamplingThread::threadMain() {
-    std::lock_guard lock(mMutex);
+// NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
+void RegionSamplingThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
+    std::unique_lock<std::mutex> lock(mThreadControlMutex);
     while (mRunning) {
         if (mSampleRequested) {
             mSampleRequested = false;
+            lock.unlock();
             captureSample();
+            lock.lock();
         }
-        mCondition.wait(mMutex,
-                        [this]() REQUIRES(mMutex) { return mSampleRequested || !mRunning; });
+        mCondition.wait(lock, [this]() REQUIRES(mThreadControlMutex) {
+            return mSampleRequested || !mRunning;
+        });
     }
 }
 
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 72b2042..08134e6 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -100,7 +100,7 @@
     void binderDied(const wp<IBinder>& who) override;
     void checkForStaleLuma();
 
-    void captureSample() REQUIRES(mMutex);
+    void captureSample();
     void threadMain();
 
     SurfaceFlinger& mFlinger;
@@ -110,19 +110,18 @@
 
     std::unique_ptr<SamplingOffsetCallback> const mPhaseCallback;
 
-    std::mutex mThreadMutex;
-    std::thread mThread GUARDED_BY(mThreadMutex);
+    std::thread mThread;
 
-    std::mutex mMutex;
+    std::mutex mThreadControlMutex;
     std::condition_variable_any mCondition;
-    bool mRunning GUARDED_BY(mMutex) = true;
-    bool mSampleRequested GUARDED_BY(mMutex) = false;
+    bool mRunning GUARDED_BY(mThreadControlMutex) = true;
+    bool mSampleRequested GUARDED_BY(mThreadControlMutex) = false;
+    bool mDiscardedFrames GUARDED_BY(mThreadControlMutex) = false;
+    std::chrono::nanoseconds lastSampleTime GUARDED_BY(mThreadControlMutex);
 
-    std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mMutex);
-    std::chrono::nanoseconds lastSampleTime GUARDED_BY(mMutex);
-    bool mDiscardedFrames GUARDED_BY(mMutex) = false;
-
-    sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mMutex) = nullptr;
+    std::mutex mSamplingMutex;
+    std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex);
+    sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 66ccf54..661c889 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -590,7 +590,11 @@
 }
 
 void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
-    postMessageAsync(new LambdaMessage([=] { getRenderEngine().deleteTextures(1, &texture); }));
+    std::lock_guard lock(mTexturePoolMutex);
+    // We don't change the pool size, so the fix-up logic in postComposition will decide whether
+    // to actually delete this or not based on mTexturePoolSize
+    mTexturePool.push_back(texture);
+    ATRACE_INT("TexturePoolSize", mTexturePool.size());
 }
 
 // Do not call property_set on main thread which will be blocked by init
@@ -2076,12 +2080,18 @@
 
     {
         std::lock_guard lock(mTexturePoolMutex);
-        const size_t refillCount = mTexturePoolSize - mTexturePool.size();
-        if (refillCount > 0) {
+        if (mTexturePool.size() < mTexturePoolSize) {
+            const size_t refillCount = mTexturePoolSize - mTexturePool.size();
             const size_t offset = mTexturePool.size();
             mTexturePool.resize(mTexturePoolSize);
             getRenderEngine().genTextures(refillCount, mTexturePool.data() + offset);
             ATRACE_INT("TexturePoolSize", mTexturePool.size());
+        } else if (mTexturePool.size() > mTexturePoolSize) {
+            const size_t deleteCount = mTexturePool.size() - mTexturePoolSize;
+            const size_t offset = mTexturePoolSize;
+            getRenderEngine().deleteTextures(deleteCount, mTexturePool.data() + offset);
+            mTexturePool.resize(mTexturePoolSize);
+            ATRACE_INT("TexturePoolSize", mTexturePool.size());
         }
     }
 
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 4e040a3..2bcb568 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -41,7 +41,7 @@
 
     virtual void parseArgs(bool asProto, const Vector<String16>& args, std::string& result) = 0;
     virtual bool isEnabled() = 0;
-    virtual std::string miniDump();
+    virtual std::string miniDump() = 0;
 
     virtual void incrementTotalFrames() = 0;
     virtual void incrementMissedFrames() = 0;
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index bebfa6c..7c0ecb3 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -856,7 +856,7 @@
     }
 
     static void cleanupInjectedLayers(CompositionTest* test) {
-        EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(2);
+        EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(1);
         Base::cleanupInjectedLayers(test);
     }
 
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 613fa13..23506ba 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1174,6 +1174,11 @@
                                                      &properties);
     ATRACE_END();
 
+    if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
+        // Log that the app is hitting software Vulkan implementation
+        android::GraphicsEnv::getInstance().setCpuVulkanInUse();
+    }
+
     data->driver_device = dev;
     data->driver_version = properties.driverVersion;
 
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index bc00190..a22f60e 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -222,6 +222,15 @@
             window,
             &refresh_duration);
     }
+    uint64_t get_refresh_duration()
+    {
+        ANativeWindow* window = surface.window.get();
+        native_window_get_refresh_cycle_duration(
+            window,
+            &refresh_duration);
+        return static_cast<uint64_t>(refresh_duration);
+
+    }
 
     Surface& surface;
     uint32_t num_images;
@@ -1730,8 +1739,7 @@
     Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle);
     VkResult result = VK_SUCCESS;
 
-    pDisplayTimingProperties->refreshDuration =
-            static_cast<uint64_t>(swapchain.refresh_duration);
+    pDisplayTimingProperties->refreshDuration = swapchain.get_refresh_duration();
 
     return result;
 }