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(