Merge "Pass a drawFence to drawLayers calls in cache warming"
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 9d88ca6..c0cbad8 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -14,3 +14,11 @@
     src: "android.hardware.biometrics.face.xml",
     filename_from_src: true,
 }
+
+prebuilt_etc {
+    name: "android.software.app_compat_overrides.xml",
+    product_specific: true,
+    sub_dir: "permissions",
+    src: "android.software.app_compat_overrides.xml",
+    filename_from_src: true,
+}
diff --git a/data/etc/android.software.app_compat_overrides.xml b/data/etc/android.software.app_compat_overrides.xml
new file mode 100644
index 0000000..2f9726a
--- /dev/null
+++ b/data/etc/android.software.app_compat_overrides.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<!-- Feature for devices that are opted-in to receive per-app compatibility
+     overrides. -->
+<permissions>
+  <feature name="android.software.app_compat_overrides" />
+</permissions>
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 3099296..765e21c 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -261,15 +261,15 @@
         if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
             using android::internal::Stability;
 
-            auto category = Stability::getCategory(this);
+            int16_t stability = Stability::getRepr(this);
             Stability::Level required = privateVendor ? Stability::VENDOR
                 : Stability::getLocalLevel();
 
-            if (CC_UNLIKELY(!Stability::check(category, required))) {
+            if (CC_UNLIKELY(!Stability::check(stability, required))) {
                 ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
-                    category.debugString().c_str(),
-                    String8(getInterfaceDescriptor()).c_str(),
-                    Stability::levelString(required).c_str());
+                      Stability::levelString(stability).c_str(),
+                      String8(getInterfaceDescriptor()).c_str(),
+                      Stability::levelString(required).c_str());
                 return BAD_TYPE;
             }
         }
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a2ac96e..e623874 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -173,7 +173,7 @@
 status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder)
 {
     internal::Stability::tryMarkCompilationUnit(binder.get());
-    int16_t rep = internal::Stability::getCategory(binder.get()).repr();
+    int16_t rep = internal::Stability::getRepr(binder.get());
     return writeInt32(rep);
 }
 
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index c6cf2c5..200d923 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -369,7 +369,7 @@
     return true;
 }
 
-void RpcServer::onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) {
+void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) {
     auto id = session->mId;
     LOG_ALWAYS_FATAL_IF(id == std::nullopt, "Server sessions must be initialized with ID");
     LOG_RPC_DETAIL("Dropping session with address %s", id->toString().c_str());
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 5fe0b00..1c37651 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -132,6 +132,7 @@
     if (wait) {
         LOG_ALWAYS_FATAL_IF(mShutdownListener == nullptr, "Shutdown listener not installed");
         mShutdownListener->waitForShutdown(_l);
+
         LOG_ALWAYS_FATAL_IF(!mThreads.empty(), "Shutdown failed");
     }
 
@@ -259,7 +260,7 @@
     return OK;
 }
 
-void RpcSession::WaitForShutdownListener::onSessionLockedAllIncomingThreadsEnded(
+void RpcSession::WaitForShutdownListener::onSessionAllIncomingThreadsEnded(
         const sp<RpcSession>& session) {
     (void)session;
     mShutdown = true;
@@ -291,7 +292,13 @@
     // be able to do nested calls (we can't only read from it)
     sp<RpcConnection> connection = assignIncomingConnectionToThisThread(std::move(fd));
 
-    status_t status = mState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+    status_t status;
+
+    if (connection == nullptr) {
+        status = DEAD_OBJECT;
+    } else {
+        status = mState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+    }
 
     return PreJoinSetupResult{
             .connection = std::move(connection),
@@ -358,6 +365,7 @@
     sp<RpcConnection>& connection = setupResult.connection;
 
     if (setupResult.status == OK) {
+        LOG_ALWAYS_FATAL_IF(!connection, "must have connection if setup succeeded");
         JavaThreadAttacher javaThreadAttacher;
         while (true) {
             status_t status = session->state()->getAndExecuteCommand(connection, session,
@@ -373,9 +381,6 @@
               statusToString(setupResult.status).c_str());
     }
 
-    LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection),
-                        "bad state: connection object guaranteed to be in list");
-
     sp<RpcSession::EventListener> listener;
     {
         std::lock_guard<std::mutex> _l(session->mMutex);
@@ -387,6 +392,12 @@
         listener = session->mEventListener.promote();
     }
 
+    // done after all cleanup, since session shutdown progresses via callbacks here
+    if (connection != nullptr) {
+        LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection),
+                            "bad state: connection object guaranteed to be in list");
+    }
+
     session = nullptr;
 
     if (listener != nullptr) {
@@ -577,24 +588,35 @@
 
 sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(unique_fd fd) {
     std::lock_guard<std::mutex> _l(mMutex);
+
+    // Don't accept any more connections, some have shutdown. Usually this
+    // happens when new connections are still being established as part of a
+    // very short-lived session which shuts down after it already started
+    // accepting new connections.
+    if (mIncomingConnections.size() < mMaxIncomingConnections) {
+        return nullptr;
+    }
+
     sp<RpcConnection> session = sp<RpcConnection>::make();
     session->fd = std::move(fd);
     session->exclusiveTid = gettid();
+
     mIncomingConnections.push_back(session);
+    mMaxIncomingConnections = mIncomingConnections.size();
 
     return session;
 }
 
 bool RpcSession::removeIncomingConnection(const sp<RpcConnection>& connection) {
-    std::lock_guard<std::mutex> _l(mMutex);
+    std::unique_lock<std::mutex> _l(mMutex);
     if (auto it = std::find(mIncomingConnections.begin(), mIncomingConnections.end(), connection);
         it != mIncomingConnections.end()) {
         mIncomingConnections.erase(it);
         if (mIncomingConnections.size() == 0) {
             sp<EventListener> listener = mEventListener.promote();
             if (listener) {
-                listener->onSessionLockedAllIncomingThreadsEnded(
-                        sp<RpcSession>::fromExisting(this));
+                _l.unlock();
+                listener->onSessionAllIncomingThreadsEnded(sp<RpcSession>::fromExisting(this));
             }
         }
         return true;
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index 00b69d5..2d05fb2 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -23,20 +23,6 @@
 namespace android {
 namespace internal {
 
-// the libbinder parcel format is currently unstable
-
-// oldest version which is supported
-constexpr uint8_t kBinderWireFormatOldest = 1;
-// current version
-constexpr uint8_t kBinderWireFormatVersion = 1;
-
-Stability::Category Stability::Category::currentFromLevel(Level level) {
-    return {
-        .version = kBinderWireFormatVersion,
-        .level = level,
-    };
-}
-
 void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
     // Downgrading a remote binder would require also copying the version from
     // the binder sent here. In practice though, we don't need to downgrade the
@@ -44,8 +30,7 @@
     // what we can do to it.
     LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
 
-    auto stability = Category::currentFromLevel(level);
-    status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
+    status_t result = setRepr(binder.get(), level, REPR_LOG | REPR_ALLOW_DOWNGRADE);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
@@ -61,41 +46,31 @@
     forceDowngradeToStability(binder, Level::VENDOR);
 }
 
-std::string Stability::Category::debugString() {
-    return levelString(level) + " wire protocol version "
-        + std::to_string(version);
-}
-
 void Stability::markCompilationUnit(IBinder* binder) {
-    auto stability = Category::currentFromLevel(getLocalLevel());
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, getLocalLevel(), REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 void Stability::markVintf(IBinder* binder) {
-    auto stability = Category::currentFromLevel(Level::VINTF);
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, Level::VINTF, REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 std::string Stability::debugToString(const sp<IBinder>& binder) {
-    auto stability = getCategory(binder.get());
-    return stability.debugString();
+    return levelString(getRepr(binder.get()));
 }
 
 void Stability::markVndk(IBinder* binder) {
-    auto stability = Category::currentFromLevel(Level::VENDOR);
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, Level::VENDOR, REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
-    return check(getCategory(binder.get()), Level::VINTF);
+    return check(getRepr(binder.get()), Level::VINTF);
 }
 
 void Stability::tryMarkCompilationUnit(IBinder* binder) {
-    auto stability = Category::currentFromLevel(getLocalLevel());
-    (void) setRepr(binder, stability.repr(), REPR_NONE);
+    (void)setRepr(binder, getLocalLevel(), REPR_NONE);
 }
 
 Stability::Level Stability::getLocalLevel() {
@@ -111,92 +86,77 @@
 #endif
 }
 
-status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) {
+status_t Stability::setRepr(IBinder* binder, int32_t setting, uint32_t flags) {
     bool log = flags & REPR_LOG;
     bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
 
-    auto current = getCategory(binder);
-    auto setting = Category::fromRepr(representation);
-
-    // If we have ahold of a binder with a newer declared version, then it
-    // should support older versions, and we will simply write our parcels with
-    // the current wire parcel format.
-    if (setting.version < kBinderWireFormatOldest) {
-        // always log, because this shouldn't happen
-        ALOGE("Cannot accept binder with older binder wire protocol version "
-              "%u. Versions less than %u are unsupported.", setting.version,
-               kBinderWireFormatOldest);
-        return BAD_TYPE;
-    }
+    int16_t current = getRepr(binder);
 
     // null binder is always written w/ 'UNDECLARED' stability
     if (binder == nullptr) {
-        if (setting.level == UNDECLARED) {
+        if (setting == UNDECLARED) {
             return OK;
         } else {
             if (log) {
-                ALOGE("Null binder written with stability %s.",
-                    levelString(setting.level).c_str());
+                ALOGE("Null binder written with stability %s.", levelString(setting).c_str());
             }
             return BAD_TYPE;
         }
     }
 
-    if (!isDeclaredLevel(setting.level)) {
+    if (!isDeclaredLevel(setting)) {
         if (log) {
-            ALOGE("Can only set known stability, not %u.", setting.level);
+            ALOGE("Can only set known stability, not %d.", setting);
         }
         return BAD_TYPE;
     }
+    Level levelSetting = static_cast<Level>(setting);
 
     if (current == setting) return OK;
 
-    bool hasAlreadyBeenSet = current.repr() != 0;
-    bool isAllowedDowngrade = allowDowngrade && check(current, setting.level);
+    bool hasAlreadyBeenSet = current != Level::UNDECLARED;
+    bool isAllowedDowngrade = allowDowngrade && check(current, levelSetting);
     if (hasAlreadyBeenSet && !isAllowedDowngrade) {
         if (log) {
             ALOGE("Interface being set with %s but it is already marked as %s",
-                  setting.debugString().c_str(),
-                  current.debugString().c_str());
+                  levelString(setting).c_str(), levelString(current).c_str());
         }
         return BAD_TYPE;
     }
 
     if (isAllowedDowngrade) {
-        ALOGI("Interface set with %s downgraded to %s stability",
-              current.debugString().c_str(),
-              setting.debugString().c_str());
+        ALOGI("Interface set with %s downgraded to %s stability", levelString(current).c_str(),
+              levelString(setting).c_str());
     }
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        local->mStability = setting.repr();
+        local->mStability = setting;
     } else {
-        binder->remoteBinder()->mStability = setting.repr();
+        binder->remoteBinder()->mStability = setting;
     }
 
     return OK;
 }
 
-Stability::Category Stability::getCategory(IBinder* binder) {
+int16_t Stability::getRepr(IBinder* binder) {
     if (binder == nullptr) {
-        return Category::currentFromLevel(Level::UNDECLARED);
+        return Level::UNDECLARED;
     }
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        return Category::fromRepr(local->mStability);
+        return local->mStability;
     }
 
-    return Category::fromRepr(binder->remoteBinder()->mStability);
+    return binder->remoteBinder()->mStability;
 }
 
-bool Stability::check(Category provided, Level required) {
-    bool stable = (provided.level & required) == required;
+bool Stability::check(int16_t provided, Level required) {
+    bool stable = (provided & required) == required;
 
-    if (provided.level != UNDECLARED && !isDeclaredLevel(provided.level)) {
-        ALOGE("Unknown stability when checking interface stability %d.",
-              provided.level);
+    if (provided != UNDECLARED && !isDeclaredLevel(provided)) {
+        ALOGE("Unknown stability when checking interface stability %d.", provided);
 
         stable = false;
     }
@@ -204,11 +164,11 @@
     return stable;
 }
 
-bool Stability::isDeclaredLevel(Level stability) {
+bool Stability::isDeclaredLevel(int32_t stability) {
     return stability == VENDOR || stability == SYSTEM || stability == VINTF;
 }
 
-std::string Stability::levelString(Level level) {
+std::string Stability::levelString(int32_t level) {
     switch (level) {
         case Level::UNDECLARED: return "undeclared stability";
         case Level::VENDOR: return "vendor stability";
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index c8d2857..a8094dd 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -156,7 +156,7 @@
     friend sp<RpcServer>;
     RpcServer();
 
-    void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+    void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
     void onSessionIncomingThreadEnded() override;
 
     static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd);
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index fdca2a9..2101df8 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -177,19 +177,19 @@
 
     class EventListener : public virtual RefBase {
     public:
-        virtual void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0;
+        virtual void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0;
         virtual void onSessionIncomingThreadEnded() = 0;
     };
 
     class WaitForShutdownListener : public EventListener {
     public:
-        void onSessionLockedAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+        void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
         void onSessionIncomingThreadEnded() override;
         void waitForShutdown(std::unique_lock<std::mutex>& lock);
 
     private:
         std::condition_variable mCv;
-        bool mShutdown = false;
+        volatile bool mShutdown = false;
     };
 
     struct RpcConnection : public RefBase {
@@ -297,6 +297,7 @@
     // hint index into clients, ++ when sending an async transaction
     size_t mOutgoingConnectionsOffset = 0;
     std::vector<sp<RpcConnection>> mOutgoingConnections;
+    size_t mMaxIncomingConnections = 0;
     std::vector<sp<RpcConnection>> mIncomingConnections;
     std::map<std::thread::id, std::thread> mThreads;
 };
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index 629b565..ce4362f 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -44,10 +44,9 @@
 //   to old servers, and new servers know how to interpret the 8-byte result,
 //   they can still communicate.
 //
-// Every binder object has a stability level associated with it, and when
-// communicating with a binder, we make sure that the command we sent is one
-// that it knows how to process. The summary of stability of a binder is
-// represented by a Stability::Category object.
+// This class is specifically about (1). (2) is not currently tracked by
+// libbinder for regular binder calls, and everything on the system uses the
+// same copy of libbinder.
 
 class Stability final {
 public:
@@ -128,7 +127,10 @@
 
     static void tryMarkCompilationUnit(IBinder* binder);
 
-    enum Level : uint8_t {
+    // Currently, we use int16_t for Level so that it can fit in BBinder.
+    // However, on the wire, we have 4 bytes reserved for stability, so whenever
+    // we ingest a Level, we always accept an int32_t.
+    enum Level : int16_t {
         UNDECLARED = 0,
 
         VENDOR = 0b000011,
@@ -136,37 +138,6 @@
         VINTF = 0b111111,
     };
 
-    // This is the format of stability passed on the wire. It is only 2 bytes
-    // long, but 2 bytes in addition to this are reserved here. The difference
-    // in size is in order to free up space in BBinder, which is fixed by
-    // prebuilts inheriting from it.
-    struct Category {
-        static inline Category fromRepr(int16_t representation) {
-            return *reinterpret_cast<Category*>(&representation);
-        }
-        int16_t repr() const { return *reinterpret_cast<const int16_t*>(this); }
-        static inline Category currentFromLevel(Level level);
-
-        bool operator== (const Category& o) const {
-            return repr() == o.repr();
-        }
-        bool operator!= (const Category& o) const {
-            return !(*this == o);
-        }
-
-        std::string debugString();
-
-        // This is the version of the wire protocol associated with the host
-        // process of a particular binder. As the wire protocol changes, if
-        // sending a transaction to a binder with an old version, the Parcel
-        // class must write parcels according to the version documented here.
-        uint8_t version;
-
-        // bitmask of Stability::Level
-        Level level;
-    };
-    static_assert(sizeof(Category) == sizeof(int16_t));
-
     // returns the stability according to how this was built
     static Level getLocalLevel();
 
@@ -179,18 +150,18 @@
       REPR_ALLOW_DOWNGRADE = 2,
     };
     // applies stability to binder if stability level is known
-    __attribute__((warn_unused_result))
-    static status_t setRepr(IBinder* binder, int32_t representation, uint32_t flags);
+    __attribute__((warn_unused_result)) static status_t setRepr(IBinder* binder, int32_t setting,
+                                                                uint32_t flags);
 
     // get stability information as encoded on the wire
-    static Category getCategory(IBinder* binder);
+    static int16_t getRepr(IBinder* binder);
 
     // whether a transaction on binder is allowed, if the transaction
     // is done from a context with a specific stability level
-    static bool check(Category provided, Level required);
+    static bool check(int16_t provided, Level required);
 
-    static bool isDeclaredLevel(Level level);
-    static std::string levelString(Level level);
+    static bool isDeclaredLevel(int32_t level);
+    static std::string levelString(int32_t level);
 
     Stability();
 };
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index d7fdab5..cf774fd 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -979,6 +979,8 @@
 void QueryPresentationProperties(
     VkPhysicalDevice physicalDevice,
     VkPhysicalDevicePresentationPropertiesANDROID* presentation_properties) {
+    ATRACE_CALL();
+
     // Request the android-specific presentation properties via GPDP2
     VkPhysicalDeviceProperties2 properties = {
         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
@@ -994,7 +996,17 @@
     presentation_properties->pNext = nullptr;
     presentation_properties->sharedImage = VK_FALSE;
 
-    GetPhysicalDeviceProperties2(physicalDevice, &properties);
+    const auto& driver = GetData(physicalDevice).driver;
+
+    if (driver.GetPhysicalDeviceProperties2) {
+        // >= 1.1 driver, supports core GPDP2 entrypoint.
+        driver.GetPhysicalDeviceProperties2(physicalDevice, &properties);
+    } else if (driver.GetPhysicalDeviceProperties2KHR) {
+        // Old driver, but may support presentation properties
+        // if we have the GPDP2 extension. Otherwise, no presentation
+        // properties supported.
+        driver.GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
+    }
 }
 
 VkResult EnumerateDeviceExtensionProperties(