Merge "Enable AIDL fuzzers in presubmit" into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 408b926..522442f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -177,6 +177,7 @@
 #define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
 #define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
 #define XFRM_STAT_PROC_FILE "/proc/net/xfrm_stat"
+#define KERNEL_CONFIG "/proc/config.gz"
 #define WLUTIL "/vendor/xbin/wlutil"
 #define WMTRACE_DATA_DIR "/data/misc/wmtrace"
 #define OTA_METADATA_DIR "/metadata/ota"
@@ -1952,6 +1953,8 @@
     DumpFile("PSI memory", "/proc/pressure/memory");
     DumpFile("PSI io", "/proc/pressure/io");
 
+    ds.AddZipEntry(ZIP_ROOT_DIR + KERNEL_CONFIG, KERNEL_CONFIG);
+
     RunCommand("SDK EXTENSIONS", {SDK_EXT_INFO, "--dump"},
                CommandOptions::WithTimeout(10).Always().DropRoot().Build());
 
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index e54f9d3..870e8eb 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -44,6 +44,7 @@
 #include "Timeout.h"
 #include "utils.h"
 
+using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hidl::base::V1_0::DebugInfo;
@@ -522,27 +523,35 @@
     using namespace ::android::hardware;
     using namespace ::android::hidl::manager::V1_0;
     using namespace ::android::hidl::base::V1_0;
-    using std::literals::chrono_literals::operator""s;
-    auto ret = timeoutIPC(10s, manager, &IServiceManager::debugDump, [&] (const auto &infos) {
-        std::map<std::string, TableEntry> entries;
-        for (const auto &info : infos) {
-            std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" +
-                    std::string{info.instanceName.c_str()};
-            entries.emplace(interfaceName, TableEntry{
-                .interfaceName = interfaceName,
-                .transport = vintf::Transport::PASSTHROUGH,
-                .clientPids = info.clientPids,
-            }).first->second.arch |= fromBaseArchitecture(info.arch);
-        }
-        for (auto &&pair : entries) {
-            putEntry(HalType::PASSTHROUGH_LIBRARIES, std::move(pair.second));
-        }
-    });
+
+    // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+    // even though the interface function call is synchronous.
+    // However, there's no need to lock because if ret.isOk(), the background thread has
+    // already ended, so it is safe to dereference entries.
+    auto entries = std::make_shared<std::map<std::string, TableEntry>>();
+    auto ret =
+            timeoutIPC(mLshal.getDebugDumpWait(), manager, &IServiceManager::debugDump,
+                       [entries](const auto& infos) {
+                           for (const auto& info : infos) {
+                               std::string interfaceName = std::string{info.interfaceName.c_str()} +
+                                       "/" + std::string{info.instanceName.c_str()};
+                               entries->emplace(interfaceName,
+                                                TableEntry{
+                                                        .interfaceName = interfaceName,
+                                                        .transport = vintf::Transport::PASSTHROUGH,
+                                                        .clientPids = info.clientPids,
+                                                })
+                                       .first->second.arch |= fromBaseArchitecture(info.arch);
+                           }
+                       });
     if (!ret.isOk()) {
         err() << "Error: Failed to call list on getPassthroughServiceManager(): "
              << ret.description() << std::endl;
         return DUMP_ALL_LIBS_ERROR;
     }
+    for (auto&& pair : *entries) {
+        putEntry(HalType::PASSTHROUGH_LIBRARIES, std::move(pair.second));
+    }
     return OK;
 }
 
@@ -553,27 +562,40 @@
     using namespace ::android::hardware::details;
     using namespace ::android::hidl::manager::V1_0;
     using namespace ::android::hidl::base::V1_0;
-    auto ret = timeoutIPC(manager, &IServiceManager::debugDump, [&] (const auto &infos) {
-        for (const auto &info : infos) {
-            if (info.clientPids.size() <= 0) {
-                continue;
-            }
-            putEntry(HalType::PASSTHROUGH_CLIENTS, {
-                .interfaceName =
-                        std::string{info.interfaceName.c_str()} + "/" +
-                        std::string{info.instanceName.c_str()},
-                .transport = vintf::Transport::PASSTHROUGH,
-                .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
-                .clientPids = info.clientPids,
-                .arch = fromBaseArchitecture(info.arch)
-            });
-        }
-    });
+
+    // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+    // even though the interface function call is synchronous.
+    // However, there's no need to lock because if ret.isOk(), the background thread has
+    // already ended, so it is safe to dereference entries.
+    auto entries = std::make_shared<std::vector<TableEntry>>();
+    auto ret =
+            timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::debugDump,
+                       [entries](const auto& infos) {
+                           for (const auto& info : infos) {
+                               if (info.clientPids.size() <= 0) {
+                                   continue;
+                               }
+                               entries->emplace_back(
+                                       TableEntry{.interfaceName =
+                                                          std::string{info.interfaceName.c_str()} +
+                                                          "/" +
+                                                          std::string{info.instanceName.c_str()},
+                                                  .transport = vintf::Transport::PASSTHROUGH,
+                                                  .serverPid = info.clientPids.size() == 1
+                                                          ? info.clientPids[0]
+                                                          : NO_PID,
+                                                  .clientPids = info.clientPids,
+                                                  .arch = fromBaseArchitecture(info.arch)});
+                           }
+                       });
     if (!ret.isOk()) {
         err() << "Error: Failed to call debugDump on defaultServiceManager(): "
              << ret.description() << std::endl;
         return DUMP_PASSTHROUGH_ERROR;
     }
+    for (auto&& entry : *entries) {
+        putEntry(HalType::PASSTHROUGH_CLIENTS, std::move(entry));
+    }
     return OK;
 }
 
@@ -583,11 +605,14 @@
     if (!shouldFetchHalType(HalType::BINDERIZED_SERVICES)) { return OK; }
 
     const vintf::Transport mode = vintf::Transport::HWBINDER;
-    hidl_vec<hidl_string> fqInstanceNames;
-    // copying out for timeoutIPC
-    auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
-        fqInstanceNames = names;
-    });
+
+    // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+    // even though the interface function call is synchronous.
+    // However, there's no need to lock because if listRet.isOk(), the background thread has
+    // already ended, so it is safe to dereference fqInstanceNames.
+    auto fqInstanceNames = std::make_shared<hidl_vec<hidl_string>>();
+    auto listRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::list,
+                              [fqInstanceNames](const auto& names) { *fqInstanceNames = names; });
     if (!listRet.isOk()) {
         err() << "Error: Failed to list services for " << mode << ": "
              << listRet.description() << std::endl;
@@ -596,7 +621,7 @@
 
     Status status = OK;
     std::map<std::string, TableEntry> allTableEntries;
-    for (const auto &fqInstanceName : fqInstanceNames) {
+    for (const auto& fqInstanceName : *fqInstanceNames) {
         // create entry and default assign all fields.
         TableEntry& entry = allTableEntries[fqInstanceName];
         entry.interfaceName = fqInstanceName;
@@ -623,7 +648,8 @@
     const auto pair = splitFirst(entry->interfaceName, '/');
     const auto &serviceName = pair.first;
     const auto &instanceName = pair.second;
-    auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
+    auto getRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::get, serviceName,
+                             instanceName);
     if (!getRet.isOk()) {
         handleError(TRANSACTION_ERROR,
                     "cannot be fetched from service manager:" + getRet.description());
@@ -637,30 +663,33 @@
 
     // getDebugInfo
     do {
-        DebugInfo debugInfo;
-        auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &received) {
-            debugInfo = received;
-        });
+        // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+        // even though the interface function call is synchronous.
+        // However, there's no need to lock because if debugRet.isOk(), the background thread has
+        // already ended, so it is safe to dereference debugInfo.
+        auto debugInfo = std::make_shared<DebugInfo>();
+        auto debugRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getDebugInfo,
+                                   [debugInfo](const auto& received) { *debugInfo = received; });
         if (!debugRet.isOk()) {
             handleError(TRANSACTION_ERROR,
                         "debugging information cannot be retrieved: " + debugRet.description());
             break; // skip getPidInfo
         }
 
-        entry->serverPid = debugInfo.pid;
-        entry->serverObjectAddress = debugInfo.ptr;
-        entry->arch = fromBaseArchitecture(debugInfo.arch);
+        entry->serverPid = debugInfo->pid;
+        entry->serverObjectAddress = debugInfo->ptr;
+        entry->arch = fromBaseArchitecture(debugInfo->arch);
 
-        if (debugInfo.pid != NO_PID) {
-            const BinderPidInfo* pidInfo = getPidInfoCached(debugInfo.pid);
+        if (debugInfo->pid != NO_PID) {
+            const BinderPidInfo* pidInfo = getPidInfoCached(debugInfo->pid);
             if (pidInfo == nullptr) {
                 handleError(IO_ERROR,
-                            "no information for PID " + std::to_string(debugInfo.pid) +
-                            ", are you root?");
+                            "no information for PID " + std::to_string(debugInfo->pid) +
+                                    ", are you root?");
                 break;
             }
-            if (debugInfo.ptr != NO_PTR) {
-                auto it = pidInfo->refPids.find(debugInfo.ptr);
+            if (debugInfo->ptr != NO_PTR) {
+                auto it = pidInfo->refPids.find(debugInfo->ptr);
                 if (it != pidInfo->refPids.end()) {
                     entry->clientPids = it->second;
                 }
@@ -672,39 +701,46 @@
 
     // hash
     do {
-        ssize_t hashIndex = -1;
-        auto ifaceChainRet = timeoutIPC(service, &IBase::interfaceChain, [&] (const auto& c) {
-            for (size_t i = 0; i < c.size(); ++i) {
-                if (serviceName == c[i]) {
-                    hashIndex = static_cast<ssize_t>(i);
-                    break;
-                }
-            }
-        });
+        // The lambda function may be executed asynchrounously because it is passed to timeoutIPC,
+        // even though the interface function call is synchronous.
+        auto hashIndexStore = std::make_shared<ssize_t>(-1);
+        auto ifaceChainRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::interfaceChain,
+                                        [hashIndexStore, serviceName](const auto& c) {
+                                            for (size_t i = 0; i < c.size(); ++i) {
+                                                if (serviceName == c[i]) {
+                                                    *hashIndexStore = static_cast<ssize_t>(i);
+                                                    break;
+                                                }
+                                            }
+                                        });
         if (!ifaceChainRet.isOk()) {
             handleError(TRANSACTION_ERROR,
                         "interfaceChain fails: " + ifaceChainRet.description());
             break; // skip getHashChain
         }
+        // if ifaceChainRet.isOk(), the background thread has already ended, so it is safe to
+        // dereference hashIndex without any locking.
+        auto hashIndex = *hashIndexStore;
         if (hashIndex < 0) {
             handleError(BAD_IMPL, "Interface name does not exist in interfaceChain.");
             break; // skip getHashChain
         }
-        auto hashRet = timeoutIPC(service, &IBase::getHashChain, [&] (const auto& hashChain) {
-            if (static_cast<size_t>(hashIndex) >= hashChain.size()) {
-                handleError(BAD_IMPL,
-                            "interfaceChain indicates position " + std::to_string(hashIndex) +
-                            " but getHashChain returns " + std::to_string(hashChain.size()) +
-                            " hashes");
-                return;
-            }
-
-            auto&& hashArray = hashChain[hashIndex];
-            entry->hash = android::base::HexString(hashArray.data(), hashArray.size());
-        });
+        // See comments about hashIndex above.
+        auto hashChain = std::make_shared<hidl_vec<hidl_array<uint8_t, 32>>>();
+        auto hashRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getHashChain,
+                                  [hashChain](const auto& ret) { *hashChain = std::move(ret); });
         if (!hashRet.isOk()) {
             handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description());
         }
+        if (static_cast<size_t>(hashIndex) >= hashChain->size()) {
+            handleError(BAD_IMPL,
+                        "interfaceChain indicates position " + std::to_string(hashIndex) +
+                                " but getHashChain returns " + std::to_string(hashChain->size()) +
+                                " hashes");
+        } else {
+            auto&& hashArray = (*hashChain)[hashIndex];
+            entry->hash = android::base::HexString(hashArray.data(), hashArray.size());
+        }
     } while (0);
     if (status == OK) {
         entry->serviceStatus = ServiceStatus::ALIVE;
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index a5f98c2..6115da7 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -250,5 +250,17 @@
     return mPassthroughManager;
 }
 
+void Lshal::setWaitTimeForTest(std::chrono::milliseconds ipcCallWait,
+                               std::chrono::milliseconds debugDumpWait) {
+    mIpcCallWait = ipcCallWait;
+    mDebugDumpWait = debugDumpWait;
+}
+std::chrono::milliseconds Lshal::getIpcCallWait() const {
+    return mIpcCallWait;
+}
+std::chrono::milliseconds Lshal::getDebugDumpWait() const {
+    return mDebugDumpWait;
+}
+
 }  // namespace lshal
 }  // namespace android
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index 50279d4..cb2820c 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <chrono>
 #include <iostream>
 #include <string>
 
@@ -58,6 +59,11 @@
 
     void forEachCommand(const std::function<void(const Command* c)>& f) const;
 
+    void setWaitTimeForTest(std::chrono::milliseconds ipcCallWait,
+                            std::chrono::milliseconds debugDumpWait);
+    std::chrono::milliseconds getIpcCallWait() const;
+    std::chrono::milliseconds getDebugDumpWait() const;
+
 private:
     Status parseArgs(const Arg &arg);
 
@@ -70,6 +76,9 @@
 
     std::vector<std::unique_ptr<Command>> mRegisteredCommands;
 
+    std::chrono::milliseconds mIpcCallWait{500};
+    std::chrono::milliseconds mDebugDumpWait{10000};
+
     DISALLOW_COPY_AND_ASSIGN(Lshal);
 };
 
diff --git a/cmds/lshal/Timeout.h b/cmds/lshal/Timeout.h
index e8d22d9..805e8dc 100644
--- a/cmds/lshal/Timeout.h
+++ b/cmds/lshal/Timeout.h
@@ -27,8 +27,6 @@
 namespace android {
 namespace lshal {
 
-static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500};
-
 class BackgroundTaskState {
 public:
     explicit BackgroundTaskState(std::function<void(void)> &&func)
@@ -96,12 +94,5 @@
     return ret;
 }
 
-template<class Function, class I, class... Args>
-typename std::result_of<Function(I *, Args...)>::type
-timeoutIPC(const sp<I> &interfaceObject, Function &&func, Args &&... args) {
-    return timeoutIPC(IPC_CALL_WAIT, interfaceObject, func, args...);
-}
-
-
 }  // namespace lshal
 }  // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index aaf2523..8a6a67a 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -165,8 +165,7 @@
     auto intError = mComposer.getChangedCompositionTypes(
             mId, &layerIds, &types);
     uint32_t numElements = layerIds.size();
-    auto error = static_cast<Error>(intError);
-    error = static_cast<Error>(intError);
+    const auto error = static_cast<Error>(intError);
     if (error != Error::NONE) {
         return error;
     }