Merge "Add flag for additional touchpad palm rejection while typing" into main
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 860a2d8..23f185e 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -104,6 +104,8 @@
         "libvintf",
         "libbinderdebug",
         "packagemanager_aidl-cpp",
+        "server_configurable_flags",
+        "device_policy_aconfig_flags_c_lib",
     ],
     srcs: [
         "DumpstateService.cpp",
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index c787113..ba0a38a 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -37,6 +37,8 @@
     Dumpstate* ds = nullptr;
     int32_t calling_uid = -1;
     std::string calling_package;
+    int32_t user_id = -1;
+    bool keep_bugreport_on_retrieval = false;
 };
 
 static binder::Status exception(uint32_t code, const std::string& msg,
@@ -60,7 +62,7 @@
 
 [[noreturn]] static void* dumpstate_thread_retrieve(void* data) {
     std::unique_ptr<DumpstateInfo> ds_info(static_cast<DumpstateInfo*>(data));
-    ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package);
+    ds_info->ds->Retrieve(ds_info->calling_uid, ds_info->calling_package, ds_info->keep_bugreport_on_retrieval);
     MYLOGD("Finished retrieving a bugreport. Exiting.\n");
     exit(0);
 }
@@ -201,9 +203,10 @@
 }
 
 binder::Status DumpstateService::retrieveBugreport(
-    int32_t calling_uid, const std::string& calling_package,
+    int32_t calling_uid, const std::string& calling_package, int32_t user_id,
     android::base::unique_fd bugreport_fd,
     const std::string& bugreport_file,
+    const bool keep_bugreport_on_retrieval,
     const sp<IDumpstateListener>& listener) {
 
     ds_ = &(Dumpstate::GetInstance());
@@ -211,6 +214,8 @@
     ds_info->ds = ds_;
     ds_info->calling_uid = calling_uid;
     ds_info->calling_package = calling_package;
+    ds_info->user_id = user_id;
+    ds_info->keep_bugreport_on_retrieval = keep_bugreport_on_retrieval;
     ds_->listener_ = listener;
     std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
     // Use a /dev/null FD when initializing options since none is provided.
diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h
index dd73319..7b76c36 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -48,8 +48,10 @@
 
     binder::Status retrieveBugreport(int32_t calling_uid,
                                      const std::string& calling_package,
+                                     int32_t user_id,
                                      android::base::unique_fd bugreport_fd,
                                      const std::string& bugreport_file,
+                                     const bool keep_bugreport_on_retrieval,
                                      const sp<IDumpstateListener>& listener)
                                      override;
 
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index fa9bcf3..97c470e 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -58,6 +58,9 @@
     // Defer user consent.
     const int BUGREPORT_FLAG_DEFER_CONSENT = 0x2;
 
+    // Keep bugreport stored after retrieval.
+    const int BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL = 0x4;
+
     /**
      * Speculatively pre-dumps UI data for a bugreport request that might come later.
      *
@@ -116,12 +119,16 @@
      *
      * @param callingUid UID of the original application that requested the report.
      * @param callingPackage package of the original application that requested the report.
+     * @param userId user Id of the original package that requested the report.
      * @param bugreportFd the file to which the zipped bugreport should be written
      * @param bugreportFile the path of the bugreport file
+     * @param keepBugreportOnRetrieval boolean to indicate if the bugreport should be kept in the
+     * platform after it has been retrieved by the caller.
      * @param listener callback for updates; optional
      */
-    void retrieveBugreport(int callingUid, @utf8InCpp String callingPackage,
+    void retrieveBugreport(int callingUid, @utf8InCpp String callingPackage, int userId,
                            FileDescriptor bugreportFd,
                            @utf8InCpp String bugreportFile,
+                           boolean keepBugreportOnRetrieval,
                            IDumpstateListener listener);
 }
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 33f6d38..4f80190 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -59,6 +59,7 @@
 #include <vector>
 
 #include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android_app_admin_flags.h>
 #include <android-base/file.h>
 #include <android-base/properties.h>
 #include <android-base/scopeguard.h>
@@ -2977,14 +2978,17 @@
     return status;
 }
 
-Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package) {
-    Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package);
+Dumpstate::RunStatus Dumpstate::Retrieve(int32_t calling_uid, const std::string& calling_package,
+                                         const bool keep_bugreport_on_retrieval) {
+    Dumpstate::RunStatus status = RetrieveInternal(calling_uid, calling_package,
+                                                    keep_bugreport_on_retrieval);
     HandleRunStatus(status);
     return status;
 }
 
 Dumpstate::RunStatus  Dumpstate::RetrieveInternal(int32_t calling_uid,
-                                                  const std::string& calling_package) {
+                                                  const std::string& calling_package,
+                                                  const bool keep_bugreport_on_retrieval) {
   consent_callback_ = new ConsentCallback();
   const String16 incidentcompanion("incidentcompanion");
   sp<android::IBinder> ics(
@@ -3019,9 +3023,12 @@
 
   bool copy_succeeded =
       android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
-  if (copy_succeeded) {
-    android::os::UnlinkAndLogOnError(path_);
+
+  if (copy_succeeded && (!android::app::admin::flags::onboarding_bugreport_v2_enabled()
+                         || !keep_bugreport_on_retrieval)) {
+        android::os::UnlinkAndLogOnError(path_);
   }
+
   return copy_succeeded ? Dumpstate::RunStatus::OK
                         : Dumpstate::RunStatus::ERROR;
 }
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 0a032ec..d01cfce 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -210,7 +210,9 @@
         BUGREPORT_USE_PREDUMPED_UI_DATA =
           android::os::IDumpstate::BUGREPORT_FLAG_USE_PREDUMPED_UI_DATA,
         BUGREPORT_FLAG_DEFER_CONSENT =
-          android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT
+          android::os::IDumpstate::BUGREPORT_FLAG_DEFER_CONSENT,
+          BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL =
+                    android::os::IDumpstate::BUGREPORT_FLAG_KEEP_BUGREPORT_ON_RETRIEVAL
     };
 
     static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
@@ -361,7 +363,8 @@
      *
      * Initialize() dumpstate before calling this method.
      */
-    RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package);
+    RunStatus Retrieve(int32_t calling_uid, const std::string& calling_package,
+                        const bool keep_bugreport_on_retrieval);
 
 
 
@@ -562,7 +565,8 @@
 
   private:
     RunStatus RunInternal(int32_t calling_uid, const std::string& calling_package);
-    RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package);
+    RunStatus RetrieveInternal(int32_t calling_uid, const std::string& calling_package,
+                                const bool keep_bugreport_on_retrieval);
 
     RunStatus DumpstateDefaultAfterCritical();
     RunStatus dumpstate();
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index ac101ec..334bae4 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -34,7 +34,6 @@
         "unique_file.cpp",
         "utils.cpp",
         "utils_default.cpp",
-        "view_compiler.cpp",
         ":installd_aidl",
     ],
     shared_libs: [
@@ -254,7 +253,6 @@
         "unique_file.cpp",
         "utils.cpp",
         "utils_default.cpp",
-        "view_compiler.cpp",
     ],
 
     static_libs: [
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 073d0c4..d7c9b40 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -69,7 +69,6 @@
 #include "installd_deps.h"
 #include "otapreopt_utils.h"
 #include "utils.h"
-#include "view_compiler.h"
 
 #include "CacheTracker.h"
 #include "CrateManager.h"
@@ -3258,17 +3257,6 @@
     return ok();
 }
 
-binder::Status InstalldNativeService::compileLayouts(const std::string& apkPath,
-                                                     const std::string& packageName,
-                                                     const std ::string& outDexFile, int uid,
-                                                     bool* _aidl_return) {
-    const char* apk_path = apkPath.c_str();
-    const char* package_name = packageName.c_str();
-    const char* out_dex_file = outDexFile.c_str();
-    *_aidl_return = android::installd::view_compiler(apk_path, package_name, out_dex_file, uid);
-    return *_aidl_return ? ok() : error("viewcompiler failed");
-}
-
 binder::Status InstalldNativeService::linkNativeLibraryDirectory(
         const std::optional<std::string>& uuid, const std::string& packageName,
         const std::string& nativeLibPath32, int32_t userId) {
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index 1ec092d..1b56144 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -146,9 +146,6 @@
 
     binder::Status controlDexOptBlocking(bool block);
 
-    binder::Status compileLayouts(const std::string& apkPath, const std::string& packageName,
-                                  const std::string& outDexFile, int uid, bool* _aidl_return);
-
     binder::Status rmdex(const std::string& codePath, const std::string& instructionSet);
 
     binder::Status mergeProfiles(int32_t uid, const std::string& packageName,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 8893e38..f5a7709 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -70,8 +70,6 @@
     // Blocks (when block is true) or unblock (when block is false) dexopt.
     // Blocking also invloves cancelling the currently running dexopt.
     void controlDexOptBlocking(boolean block);
-    boolean compileLayouts(@utf8InCpp String apkPath, @utf8InCpp String packageName,
-            @utf8InCpp String outDexFile, int uid);
 
     void rmdex(@utf8InCpp String codePath, @utf8InCpp String instructionSet);
 
diff --git a/cmds/installd/view_compiler.cpp b/cmds/installd/view_compiler.cpp
deleted file mode 100644
index 8c000a1..0000000
--- a/cmds/installd/view_compiler.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "view_compiler.h"
-
-#include <string>
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "utils.h"
-
-#include "android-base/logging.h"
-#include "android-base/stringprintf.h"
-#include "android-base/unique_fd.h"
-
-namespace android {
-namespace installd {
-
-namespace {
-
-using ::android::base::unique_fd;
-
-constexpr int kTimeoutMs = 300000;
-
-} // namespace
-
-bool view_compiler(const char* apk_path, const char* package_name, const char* out_dex_file,
-                   int uid) {
-    CHECK(apk_path != nullptr);
-    CHECK(package_name != nullptr);
-    CHECK(out_dex_file != nullptr);
-
-    // viewcompiler won't have permission to open anything, so we have to open the files first
-    // and pass file descriptors.
-
-    // Open input file
-    unique_fd infd{open(apk_path, O_RDONLY)}; // NOLINT(android-cloexec-open)
-    if (infd.get() < 0) {
-        PLOG(ERROR) << "Could not open input file: " << apk_path;
-        return false;
-    }
-
-    // Set up output file. viewcompiler can't open outputs by fd, but it can write to stdout, so
-    // we close stdout and open it towards the right output.
-    unique_fd outfd{open(out_dex_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644)};
-    if (outfd.get() < 0) {
-        PLOG(ERROR) << "Could not open output file: " << out_dex_file;
-        return false;
-    }
-    if (fchmod(outfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) != 0) {
-        PLOG(ERROR) << "Could not change output file permissions";
-        return false;
-    }
-    if (dup2(outfd, STDOUT_FILENO) < 0) {
-        PLOG(ERROR) << "Could not duplicate output file descriptor";
-        return false;
-    }
-
-    // Prepare command line arguments for viewcompiler
-    std::string args[] = {"/system/bin/viewcompiler",
-                          "--apk",
-                          "--infd",
-                          android::base::StringPrintf("%d", infd.get()),
-                          "--dex",
-                          "--package",
-                          package_name};
-    char* const argv[] = {const_cast<char*>(args[0].c_str()), const_cast<char*>(args[1].c_str()),
-                          const_cast<char*>(args[2].c_str()), const_cast<char*>(args[3].c_str()),
-                          const_cast<char*>(args[4].c_str()), const_cast<char*>(args[5].c_str()),
-                          const_cast<char*>(args[6].c_str()), nullptr};
-
-    pid_t pid = fork();
-    if (pid == 0) {
-        // Now that we've opened the files we need, drop privileges.
-        drop_capabilities(uid);
-        execv("/system/bin/viewcompiler", argv);
-        _exit(1);
-    }
-
-    int return_code = wait_child_with_timeout(pid, kTimeoutMs);
-    if (!WIFEXITED(return_code)) {
-        LOG(WARNING) << "viewcompiler failed for " << package_name << ":" << apk_path;
-        if (WTERMSIG(return_code) == SIGKILL) {
-            // If the subprocess is killed while it's writing to the file, the file is likely
-            // corrupted, so we should remove it.
-            remove_file_at_fd(outfd.get());
-        }
-        return false;
-    }
-    return WEXITSTATUS(return_code) == 0;
-}
-
-} // namespace installd
-} // namespace android
diff --git a/cmds/installd/view_compiler.h b/cmds/installd/view_compiler.h
deleted file mode 100644
index aa141ca..0000000
--- a/cmds/installd/view_compiler.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VIEW_COMPILER_H_
-#define VIEW_COMPILER_H_
-
-namespace android {
-namespace installd {
-
-bool view_compiler(const char* apk_path, const char* package_name, const char* out_dex_file,
-                   int uid);
-
-} // namespace installd
-} // namespace android
-
-#endif // VIEW_COMPILER_H_
diff --git a/libs/binder/ndk/stability.cpp b/libs/binder/ndk/stability.cpp
index 7eafb9c..73eb863 100644
--- a/libs/binder/ndk/stability.cpp
+++ b/libs/binder/ndk/stability.cpp
@@ -27,6 +27,10 @@
 #error libbinder_ndk should only be built in a system context
 #endif
 
+#ifdef __ANDROID_VENDOR__
+#error libbinder_ndk should only be built in a system context
+#endif
+
 #ifdef __ANDROID_NDK__
 #error libbinder_ndk should only be built in a system context
 #endif
diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
index 47607a0..9ebaf16 100644
--- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
+++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h
@@ -104,7 +104,7 @@
         GL_UPDATED = 2,
         VULKAN = 3,
         VULKAN_UPDATED = 4,
-        ANGLE = 5,
+        ANGLE = 5, // cover both system ANGLE and ANGLE APK
     };
 
     enum Stats {
diff --git a/libs/nativewindow/include/android/native_window_aidl.h b/libs/nativewindow/include/android/native_window_aidl.h
index a252245..0d5727d 100644
--- a/libs/nativewindow/include/android/native_window_aidl.h
+++ b/libs/nativewindow/include/android/native_window_aidl.h
@@ -34,6 +34,12 @@
 #include <android/native_window.h>
 #include <sys/cdefs.h>
 
+// Only required by the AIDL glue helper
+#ifdef __cplusplus
+#include <sstream>
+#include <string>
+#endif // __cplusplus
+
 __BEGIN_DECLS
 
 /**
@@ -80,7 +86,7 @@
  * Takes ownership of the ANativeWindow* given to it in reset() and will automatically
  * destroy it in the destructor, similar to a smart pointer container
  */
-class NativeWindow {
+class NativeWindow final {
 public:
     NativeWindow() noexcept {}
     explicit NativeWindow(ANativeWindow* _Nullable window) {
@@ -123,15 +129,29 @@
         }
         mWindow = window;
     }
-    inline ANativeWindow* _Nullable operator-> () const { return mWindow;  }
+
     inline ANativeWindow* _Nullable get() const { return mWindow; }
-    inline explicit operator bool () const { return mWindow != nullptr; }
 
     NativeWindow& operator=(NativeWindow&& other) noexcept {
         mWindow = other.release(); // steal ownership from r-value
         return *this;
     }
 
+    inline ANativeWindow* _Nullable operator->() const { return mWindow; }
+    inline explicit operator bool() const { return mWindow != nullptr; }
+    inline bool operator==(const NativeWindow& rhs) const { return mWindow == rhs.mWindow; }
+    inline bool operator!=(const NativeWindow& rhs) const { return !(*this == rhs); }
+    inline bool operator<(const NativeWindow& rhs) const { return mWindow < rhs.mWindow; }
+    inline bool operator>(const NativeWindow& rhs) const { return rhs < *this; }
+    inline bool operator>=(const NativeWindow& rhs) const { return !(*this < rhs); }
+    inline bool operator<=(const NativeWindow& rhs) const { return !(*this > rhs); }
+
+    std::string toString() const {
+        std::ostringstream ss;
+        ss << "NativeWindow: " << mWindow;
+        return ss.str();
+    }
+
     /**
      * Stops managing any contained ANativeWindow*, returning it to the caller. Ownership
      * is released.
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 04e2fff..7b2f39c 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -567,6 +567,7 @@
         return nullptr;
     }
 
+    // use ANGLE APK driver
     android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
     driver_t* hnd = nullptr;
 
@@ -635,7 +636,13 @@
 Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix,
                                                         const bool exact) {
     ATRACE_CALL();
-    android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL);
+    if (strcmp(suffix, "angle") == 0) {
+        // use system ANGLE driver
+        android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
+    } else {
+        android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::GL);
+    }
+
     driver_t* hnd = nullptr;
     void* dso = load_system_driver("GLES", suffix, exact);
     if (dso) {
diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp
index f06a045..d447d1e 100644
--- a/services/gpuservice/gpustats/GpuStats.cpp
+++ b/services/gpuservice/gpustats/GpuStats.cpp
@@ -163,11 +163,11 @@
         addLoadingTime(driver, driverLoadingTime, &appInfo);
         appInfo.appPackageName = appPackageName;
         appInfo.driverVersionCode = driverVersionCode;
-        appInfo.angleInUse = driverPackageName == "angle";
+        appInfo.angleInUse = driver == GpuStatsInfo::Driver::ANGLE;
         appInfo.lastAccessTime = std::chrono::system_clock::now();
         mAppStats.insert({appStatsKey, appInfo});
     } else {
-        mAppStats[appStatsKey].angleInUse = driverPackageName == "angle";
+        mAppStats[appStatsKey].angleInUse = driver == GpuStatsInfo::Driver::ANGLE;
         addLoadingTime(driver, driverLoadingTime, &mAppStats[appStatsKey]);
         mAppStats[appStatsKey].lastAccessTime = std::chrono::system_clock::now();
     }
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 9d0f285..17fa7be 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -245,6 +245,7 @@
     ],
     static_libs: [
         "android.frameworks.displayservice@1.0",
+        "libc++fs",
         "libdisplayservicehidl",
         "libserviceutils",
     ],
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 069d89b..ff82914 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -21,6 +21,7 @@
 #include "LayerHistory.h"
 
 #include <android-base/stringprintf.h>
+#include <com_android_graphics_surfaceflinger_flags.h>
 #include <cutils/properties.h>
 #include <gui/TraceUtils.h>
 #include <utils/Log.h>
@@ -39,8 +40,14 @@
 
 namespace {
 
+using namespace com::android::graphics::surfaceflinger;
+
 bool isLayerActive(const LayerInfo& info, nsecs_t threshold) {
-    // Layers with an explicit frame rate or frame rate category are always kept active,
+    if (flags::misc1() && !info.isVisible()) {
+        return false;
+    }
+
+    // Layers with an explicit frame rate or frame rate category are kept active,
     // but ignore NoVote.
     if (info.getSetFrameRateVote().isValid() && !info.getSetFrameRateVote().isNoVote()) {
         return true;
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 36f2475..54e9022 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -304,19 +304,22 @@
 
     if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
         if (mLayerVote.category != FrameRateCategory::Default) {
-            ATRACE_FORMAT_INSTANT("ExplicitCategory (%s)",
+            const auto voteType = mLayerVote.type == LayerHistory::LayerVoteType::NoVote
+                    ? LayerHistory::LayerVoteType::NoVote
+                    : LayerHistory::LayerVoteType::ExplicitCategory;
+            ATRACE_FORMAT_INSTANT("Vote %s (category=%s)", ftl::enum_string(voteType).c_str(),
                                   ftl::enum_string(mLayerVote.category).c_str());
-            ALOGV("%s uses frame rate category: %d", mName.c_str(),
-                  static_cast<int>(mLayerVote.category));
-            votes.push_back({LayerHistory::LayerVoteType::ExplicitCategory, Fps(),
-                             Seamlessness::Default, mLayerVote.category,
+            ALOGV("%s voted %s with category: %s", mName.c_str(),
+                  ftl::enum_string(voteType).c_str(),
+                  ftl::enum_string(mLayerVote.category).c_str());
+            votes.push_back({voteType, Fps(), Seamlessness::Default, mLayerVote.category,
                              mLayerVote.categorySmoothSwitchOnly});
         }
 
         if (mLayerVote.fps.isValid() ||
             mLayerVote.type != LayerHistory::LayerVoteType::ExplicitDefault) {
             ATRACE_FORMAT_INSTANT("Vote %s", ftl::enum_string(mLayerVote.type).c_str());
-            ALOGV("%s voted %d ", mName.c_str(), static_cast<int>(mLayerVote.type));
+            ALOGV("%s voted %d", mName.c_str(), static_cast<int>(mLayerVote.type));
             votes.push_back(mLayerVote);
         }
 
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 1d23fb5..eb69d0b 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -401,7 +401,6 @@
 
 float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate,
                                                      bool isSeamlessSwitch) const {
-    ATRACE_CALL();
     // Slightly prefer seamless switches.
     constexpr float kSeamedSwitchPenalty = 0.95f;
     const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fc51721..48be33c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -103,6 +103,7 @@
 #include <cinttypes>
 #include <cmath>
 #include <cstdint>
+#include <filesystem>
 #include <functional>
 #include <memory>
 #include <mutex>
@@ -309,6 +310,19 @@
     return LayerHandle::getLayerId(surfaceControl->getHandle());
 }
 
+/**
+ * Returns true if the file at path exists and is newer than duration.
+ */
+bool fileNewerThan(const std::string& path, std::chrono::minutes duration) {
+    using Clock = std::filesystem::file_time_type::clock;
+    std::error_code error;
+    std::filesystem::file_time_type updateTime = std::filesystem::last_write_time(path, error);
+    if (error) {
+        return false;
+    }
+    return duration > (Clock::now() - updateTime);
+}
+
 }  // namespace anonymous
 
 // ---------------------------------------------------------------------------
@@ -899,7 +913,7 @@
     TransactionTraceWriter::getInstance().setWriterFunction(
             [&](const std::string& filename, bool overwrite) {
                 auto writeFn = [&]() {
-                    if (!overwrite && access(filename.c_str(), F_OK) == 0) {
+                    if (!overwrite && fileNewerThan(filename, std::chrono::minutes{10})) {
                         ALOGD("TransactionTraceWriter: file=%s already exists", filename.c_str());
                         return;
                     }
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
index f339d22..3b2bbb0 100644
--- a/services/surfaceflinger/TEST_MAPPING
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -31,6 +31,9 @@
     },
     {
       "name": "CtsSurfaceControlTests"
+    },
+    {
+      "name": "CtsSurfaceControlTestsStaging"
     }
   ],
   "hwasan-presubmit": [
@@ -40,10 +43,5 @@
     {
       "name": "libsurfaceflinger_unittest"
     }
-  ],
-  "postsubmit": [
-    {
-      "name": "CtsSurfaceControlTestsStaging"
-    }
   ]
 }
diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp
index 0f9060d..910e685 100644
--- a/services/surfaceflinger/fuzzer/Android.bp
+++ b/services/surfaceflinger/fuzzer/Android.bp
@@ -31,6 +31,7 @@
     ],
     static_libs: [
         "android.hardware.graphics.composer@2.1-resources",
+        "libc++fs",
         "libgmock",
         "libgui_mocks",
         "libgmock_ndk",
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
index 631adf1..2f6058f 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryIntegrationTest.cpp
@@ -18,12 +18,14 @@
 #define LOG_TAG "LayerHistoryIntegrationTest"
 
 #include <Layer.h>
+#include <com_android_graphics_surfaceflinger_flags.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <log/log.h>
 
 #include <renderengine/mock/FakeExternalTexture.h>
 
+#include "FlagUtils.h"
 #include "FpsOps.h"
 #include "LayerHierarchyTest.h"
 #include "Scheduler/LayerHistory.h"
@@ -36,6 +38,7 @@
 namespace android::scheduler {
 
 using android::mock::createDisplayMode;
+using namespace com::android::graphics::surfaceflinger;
 
 class LayerHistoryIntegrationTest : public surfaceflinger::frontend::LayerSnapshotTestBase {
 protected:
@@ -492,7 +495,9 @@
     EXPECT_EQ(1, frequentLayerCount(time));
 }
 
-TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayer) {
+TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsActive) {
+    SET_FLAG_FOR_TEST(flags::misc1, false);
+
     auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1);
     auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2);
     hideLayer(2);
@@ -515,6 +520,31 @@
     EXPECT_EQ(2, frequentLayerCount(time));
 }
 
+TEST_F(LayerHistoryIntegrationTest, invisibleExplicitLayerIsNotActive) {
+    SET_FLAG_FOR_TEST(flags::misc1, true);
+
+    auto explicitVisiblelayer = createLegacyAndFrontedEndLayer(1);
+    auto explicitInvisiblelayer = createLegacyAndFrontedEndLayer(2);
+    hideLayer(2);
+    setFrameRate(1, 60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
+                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+    setFrameRate(2, 90.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
+                 ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
+    nsecs_t time = systemTime();
+
+    // Post a buffer to the layers to make them active
+    setBufferWithPresentTime(explicitVisiblelayer, time);
+    setBufferWithPresentTime(explicitInvisiblelayer, time);
+
+    EXPECT_EQ(2u, layerCount());
+    ASSERT_EQ(1u, summarizeLayerHistory(time).size());
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
+              summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(1u, activeLayerCount());
+    EXPECT_EQ(1, frequentLayerCount(time));
+}
+
 TEST_F(LayerHistoryIntegrationTest, infrequentAnimatingLayer) {
     auto layer = createLegacyAndFrontedEndLayer(1);
 
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index 33c1d86..e8831ab 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -22,10 +22,12 @@
 #define LOG_TAG "LayerHistoryTest"
 
 #include <Layer.h>
+#include <com_android_graphics_surfaceflinger_flags.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <log/log.h>
 
+#include "FlagUtils.h"
 #include "FpsOps.h"
 #include "Scheduler/LayerHistory.h"
 #include "Scheduler/LayerInfo.h"
@@ -149,6 +151,8 @@
 
 namespace {
 
+using namespace com::android::graphics::surfaceflinger;
+
 TEST_F(LayerHistoryTest, singleLayerNoVoteDefaultCompatibility) {
     const auto layer = createLayer();
     EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
@@ -555,6 +559,33 @@
     EXPECT_EQ(FrameRateCategory::High, summarizeLayerHistory(time)[0].frameRateCategory);
 }
 
+TEST_F(LayerHistoryTest, oneLayerExplicitVoteWithCategoryNotVisibleDoesNotVote) {
+    SET_FLAG_FOR_TEST(flags::misc1, true);
+
+    auto layer = createLayer();
+    EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
+    EXPECT_CALL(*layer, getFrameRateForLayerTree())
+            .WillRepeatedly(
+                    Return(Layer::FrameRate(12.34_Hz, Layer::FrameRateCompatibility::Default,
+                                            Seamlessness::OnlySeamless, FrameRateCategory::High)));
+
+    EXPECT_EQ(1, layerCount());
+    EXPECT_EQ(0, activeLayerCount());
+
+    nsecs_t time = systemTime();
+    for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
+        history().record(layer->getSequence(), layer->getLayerProps(), time, time,
+                         LayerHistory::LayerUpdateType::Buffer);
+        time += HI_FPS_PERIOD;
+    }
+
+    // Layer is not visible, so the layer is moved to inactive, infrequent, and it will not have
+    // votes to consider for refresh rate selection.
+    ASSERT_EQ(0, summarizeLayerHistory(time).size());
+    EXPECT_EQ(0, activeLayerCount());
+    EXPECT_EQ(0, frequentLayerCount(time));
+}
+
 TEST_F(LayerHistoryTest, multipleLayers) {
     auto layer1 = createLayer("A");
     auto layer2 = createLayer("B");
@@ -780,6 +811,8 @@
 }
 
 TEST_F(LayerHistoryTest, invisibleExplicitLayer) {
+    SET_FLAG_FOR_TEST(flags::misc1, false);
+
     auto explicitVisiblelayer = createLayer();
     auto explicitInvisiblelayer = createLayer();
 
@@ -810,6 +843,39 @@
     EXPECT_EQ(2, frequentLayerCount(time));
 }
 
+TEST_F(LayerHistoryTest, invisibleExplicitLayerDoesNotVote) {
+    SET_FLAG_FOR_TEST(flags::misc1, true);
+
+    auto explicitVisiblelayer = createLayer();
+    auto explicitInvisiblelayer = createLayer();
+
+    EXPECT_CALL(*explicitVisiblelayer, isVisible()).WillRepeatedly(Return(true));
+    EXPECT_CALL(*explicitVisiblelayer, getFrameRateForLayerTree())
+            .WillRepeatedly(Return(
+                    Layer::FrameRate(60_Hz, Layer::FrameRateCompatibility::ExactOrMultiple)));
+
+    EXPECT_CALL(*explicitInvisiblelayer, isVisible()).WillRepeatedly(Return(false));
+    EXPECT_CALL(*explicitInvisiblelayer, getFrameRateForLayerTree())
+            .WillRepeatedly(Return(
+                    Layer::FrameRate(90_Hz, Layer::FrameRateCompatibility::ExactOrMultiple)));
+
+    nsecs_t time = systemTime();
+
+    // Post a buffer to the layers to make them active
+    history().record(explicitVisiblelayer->getSequence(), explicitVisiblelayer->getLayerProps(),
+                     time, time, LayerHistory::LayerUpdateType::Buffer);
+    history().record(explicitInvisiblelayer->getSequence(), explicitInvisiblelayer->getLayerProps(),
+                     time, time, LayerHistory::LayerUpdateType::Buffer);
+
+    EXPECT_EQ(2, layerCount());
+    ASSERT_EQ(1, summarizeLayerHistory(time).size());
+    EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
+              summarizeLayerHistory(time)[0].vote);
+    EXPECT_EQ(60_Hz, summarizeLayerHistory(time)[0].desiredRefreshRate);
+    EXPECT_EQ(1, activeLayerCount());
+    EXPECT_EQ(1, frequentLayerCount(time));
+}
+
 TEST_F(LayerHistoryTest, infrequentAnimatingLayer) {
     auto layer = createLayer();
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 8f1982d..03af56c 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -271,7 +271,7 @@
         resetScheduler(mScheduler);
     }
 
-    void setupMockScheduler(test::MockSchedulerOptions options = {}) {
+    void setupMockScheduler(surfaceflinger::test::MockSchedulerOptions options = {}) {
         using testing::_;
         using testing::Return;
 
diff --git a/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
index 379135e..4a83d44 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTraceWriterTest.cpp
@@ -45,12 +45,21 @@
     TestableSurfaceFlinger mFlinger;
 };
 
-TEST_F(TransactionTraceWriterTest, canWriteToFile) {
+// Check that a new file is written if overwrite=true and no file exists.
+TEST_F(TransactionTraceWriterTest, canWriteToFile_overwriteTrue) {
     TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ true);
     EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
     verifyTraceFile();
 }
 
+// Check that a new file is written if overwrite=false and no file exists.
+TEST_F(TransactionTraceWriterTest, canWriteToFile_overwriteFalse) {
+    TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ false);
+    EXPECT_EQ(access(mFilename.c_str(), F_OK), 0);
+    verifyTraceFile();
+}
+
+// Check that an existing file is overwritten when overwrite=true.
 TEST_F(TransactionTraceWriterTest, canOverwriteFile) {
     std::string testLine = "test";
     {
@@ -61,6 +70,7 @@
     verifyTraceFile();
 }
 
+// Check that an existing file isn't overwritten when it is new and overwrite=false.
 TEST_F(TransactionTraceWriterTest, doNotOverwriteFile) {
     std::string testLine = "test";
     {
@@ -76,4 +86,23 @@
         EXPECT_EQ(line, testLine);
     }
 }
+
+// Check that an existing file is overwritten when it is old and overwrite=false.
+TEST_F(TransactionTraceWriterTest, overwriteOldFile) {
+    std::string testLine = "test";
+    {
+        std::ofstream file(mFilename, std::ios::out);
+        file << testLine;
+    }
+
+    // Update file modification time to 15 minutes ago.
+    using Clock = std::filesystem::file_time_type::clock;
+    std::error_code error;
+    std::filesystem::last_write_time(mFilename, Clock::now() - std::chrono::minutes{15}, error);
+    ASSERT_EQ(error.value(), 0);
+
+    TransactionTraceWriter::getInstance().invokeForTest(mFilename, /* overwrite */ false);
+    verifyTraceFile();
+}
+
 } // namespace android
\ No newline at end of file