summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/dumpstate/dumpstate.cpp108
-rw-r--r--cmds/dumpstate/dumpstate.h3
-rw-r--r--cmds/servicemanager/ServiceManager.cpp2
-rw-r--r--include/input/InputTransport.h14
-rw-r--r--libs/binder/Binder.cpp33
-rw-r--r--libs/binder/Parcel.cpp16
-rw-r--r--libs/binder/include/binder/Binder.h4
-rw-r--r--libs/binder/include/binder/IBinder.h44
-rw-r--r--libs/binder/tests/binderLibTest.cpp60
-rw-r--r--libs/gui/ISurfaceComposer.cpp5
-rw-r--r--libs/gui/ITransactionCompletedListener.cpp2
-rw-r--r--libs/gui/SurfaceComposerClient.cpp7
-rw-r--r--libs/gui/include/gui/ITransactionCompletedListener.h47
-rw-r--r--libs/gui/include/gui/LayerMetadata.h7
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h3
-rw-r--r--libs/input/IInputFlinger.cpp6
-rw-r--r--libs/input/InputTransport.cpp88
-rw-r--r--libs/input/tests/InputChannel_test.cpp27
-rw-r--r--libs/renderengine/Android.bp3
-rw-r--r--libs/ui/Android.bp3
-rw-r--r--libs/ui/Gralloc4.cpp405
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp20
-rw-r--r--libs/ui/GraphicBufferMapper.cpp22
-rw-r--r--libs/ui/include/ui/Gralloc4.h95
-rw-r--r--libs/ui/include/ui/GraphicBufferMapper.h1
-rw-r--r--services/gpuservice/GpuService.cpp2
-rw-r--r--services/surfaceflinger/BufferLayer.h4
-rw-r--r--services/surfaceflinger/BufferQueueLayer.h2
-rw-r--r--services/surfaceflinger/BufferStateLayer.cpp8
-rw-r--r--services/surfaceflinger/BufferStateLayer.h4
-rw-r--r--services/surfaceflinger/ColorLayer.cpp4
-rw-r--r--services/surfaceflinger/ColorLayer.h4
-rw-r--r--services/surfaceflinger/CompositionEngine/Android.bp9
-rw-r--r--services/surfaceflinger/ContainerLayer.h2
-rw-r--r--services/surfaceflinger/Layer.cpp6
-rw-r--r--services/surfaceflinger/Layer.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h8
-rw-r--r--services/surfaceflinger/TransactionCompletedThread.cpp28
-rw-r--r--services/surfaceflinger/TransactionCompletedThread.h51
-rw-r--r--services/surfaceflinger/test.pngbin3058273 -> 0 bytes
-rw-r--r--services/surfaceflinger/tests/fakehwc/Android.bp2
-rw-r--r--services/vr/hardware_composer/Android.bp2
42 files changed, 877 insertions, 289 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 2044943db2..a8e6738228 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1287,7 +1287,6 @@ static Dumpstate::RunStatus dumpstate() {
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
RunCommand("UPTIME", {"uptime"});
DumpBlockStatFiles();
- dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
DumpFile("MEMORY INFO", "/proc/meminfo");
RunCommand("CPU INFO", {"top", "-b", "-n", "1", "-H", "-s", "6", "-o",
"pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name"});
@@ -3672,110 +3671,3 @@ time_t get_mtime(int fd, time_t default_mtime) {
}
return info.st_mtime;
}
-
-void dump_emmc_ecsd(const char *ext_csd_path) {
- // List of interesting offsets
- struct hex {
- char str[2];
- };
- static const size_t EXT_CSD_REV = 192 * sizeof(hex);
- static const size_t EXT_PRE_EOL_INFO = 267 * sizeof(hex);
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268 * sizeof(hex);
- static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269 * sizeof(hex);
-
- std::string buffer;
- if (!android::base::ReadFileToString(ext_csd_path, &buffer)) {
- return;
- }
-
- printf("------ %s Extended CSD ------\n", ext_csd_path);
-
- if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
- return;
- }
-
- int ext_csd_rev = 0;
- std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) {
- printf("*** %s: EXT_CSD_REV parse error \"%s\"\n\n", ext_csd_path, sub.c_str());
- return;
- }
-
- static const char *ver_str[] = {
- "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
- };
- printf("rev 1.%d (MMC %s)\n", ext_csd_rev,
- (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ? ver_str[ext_csd_rev]
- : "Unknown");
- if (ext_csd_rev < 7) {
- printf("\n");
- return;
- }
-
- if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
- return;
- }
-
- int ext_pre_eol_info = 0;
- sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) {
- printf("*** %s: PRE_EOL_INFO parse error \"%s\"\n\n", ext_csd_path, sub.c_str());
- return;
- }
-
- static const char *eol_str[] = {
- "Undefined",
- "Normal",
- "Warning (consumed 80% of reserve)",
- "Urgent (consumed 90% of reserve)"
- };
- printf(
- "PRE_EOL_INFO %d (MMC %s)\n", ext_pre_eol_info,
- eol_str[(ext_pre_eol_info < (int)(sizeof(eol_str) / sizeof(eol_str[0]))) ? ext_pre_eol_info
- : 0]);
-
- for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
- lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
- lifetime += sizeof(hex)) {
- int ext_device_life_time_est;
- static const char *est_str[] = {
- "Undefined",
- "0-10% of device lifetime used",
- "10-20% of device lifetime used",
- "20-30% of device lifetime used",
- "30-40% of device lifetime used",
- "40-50% of device lifetime used",
- "50-60% of device lifetime used",
- "60-70% of device lifetime used",
- "70-80% of device lifetime used",
- "80-90% of device lifetime used",
- "90-100% of device lifetime used",
- "Exceeded the maximum estimated device lifetime",
- };
-
- if (buffer.length() < (lifetime + sizeof(hex))) {
- printf("*** %s: truncated content %zu\n", ext_csd_path, buffer.length());
- break;
- }
-
- ext_device_life_time_est = 0;
- sub = buffer.substr(lifetime, sizeof(hex));
- if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) {
- printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n", ext_csd_path,
- (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
- sub.c_str());
- continue;
- }
- printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
- (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
- ext_device_life_time_est,
- est_str[(ext_device_life_time_est < (int)(sizeof(est_str) / sizeof(est_str[0])))
- ? ext_device_life_time_est
- : 0]);
- }
-
- printf("\n");
-}
-
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index ccc9f4261c..5ba84cad84 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -589,9 +589,6 @@ bool is_dir(const char* pathname);
/** Gets the last modification time of a file, or default time if file is not found. */
time_t get_mtime(int fd, time_t default_mtime);
-/* Dumps eMMC Extended CSD data. */
-void dump_emmc_ecsd(const char *ext_csd_path);
-
/** Gets command-line arguments. */
void format_args(int argc, const char *argv[], std::string *args);
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index f35f360dec..4d5c76ab95 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -67,7 +67,7 @@ bool isValidServiceName(const std::string& name) {
if (name.size() > 127) return false;
for (char c : name) {
- if (c == '_' || c == '-' || c == '.') continue;
+ if (c == '_' || c == '-' || c == '.' || c == '/') continue;
if (c >= 'a' && c <= 'z') continue;
if (c >= 'A' && c <= 'Z') continue;
if (c >= '0' && c <= '9') continue;
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 690e0a11c8..28b8d80074 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -42,6 +42,8 @@
#include <utils/Timers.h>
#include <utils/Vector.h>
+#include <android-base/unique_fd.h>
+
namespace android {
class Parcel;
@@ -166,8 +168,7 @@ protected:
virtual ~InputChannel();
public:
- InputChannel() = default;
- InputChannel(const std::string& name, int fd);
+ static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd);
/* Creates a pair of input channels.
*
@@ -177,7 +178,7 @@ public:
sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
inline std::string getName() const { return mName; }
- inline int getFd() const { return mFd; }
+ inline int getFd() const { return mFd.get(); }
/* Sends a message to the other endpoint.
*
@@ -208,16 +209,15 @@ public:
sp<InputChannel> dup() const;
status_t write(Parcel& out) const;
- status_t read(const Parcel& from);
+ static sp<InputChannel> read(const Parcel& from);
sp<IBinder> getToken() const;
void setToken(const sp<IBinder>& token);
private:
- void setFd(int fd);
-
+ InputChannel(const std::string& name, android::base::unique_fd fd);
std::string mName;
- int mFd = -1;
+ android::base::unique_fd mFd;
sp<IBinder> mToken = nullptr;
};
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index f3483ca8c3..693045e7f3 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -81,6 +81,24 @@ status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int e
return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);
}
+status_t IBinder::getExtension(sp<IBinder>* out) {
+ BBinder* local = this->localBinder();
+ if (local != nullptr) {
+ *out = local->getExtension();
+ return OK;
+ }
+
+ BpBinder* proxy = this->remoteBinder();
+ LOG_ALWAYS_FATAL_IF(proxy == nullptr);
+
+ Parcel data;
+ Parcel reply;
+ status_t status = transact(EXTENSION_TRANSACTION, data, &reply);
+ if (status != OK) return status;
+
+ return reply.readNullableStrongBinder(out);
+}
+
// ---------------------------------------------------------------------------
class BBinder::Extras
@@ -88,6 +106,7 @@ class BBinder::Extras
public:
// unlocked objects
bool mRequestingSid = false;
+ sp<IBinder> mExtension;
// for below objects
Mutex mLock;
@@ -130,6 +149,9 @@ status_t BBinder::transact(
case PING_TRANSACTION:
err = pingBinder();
break;
+ case EXTENSION_TRANSACTION:
+ err = reply->writeStrongBinder(getExtension());
+ break;
default:
err = onTransact(code, data, reply, flags);
break;
@@ -222,6 +244,17 @@ void BBinder::setRequestingSid(bool requestingSid)
e->mRequestingSid = requestingSid;
}
+sp<IBinder> BBinder::getExtension() {
+ Extras* e = mExtras.load(std::memory_order_acquire);
+ if (e == nullptr) return nullptr;
+ return e->mExtension;
+}
+
+void BBinder::setExtension(const sp<IBinder>& extension) {
+ Extras* e = getOrCreateExtras();
+ e->mExtension = extension;
+}
+
BBinder::~BBinder()
{
Extras* e = mExtras.load(std::memory_order_relaxed);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index ed6c834af8..3a7a7a9c3f 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2354,6 +2354,22 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
mObjectsSize = 0;
break;
}
+ const flat_binder_object* flat
+ = reinterpret_cast<const flat_binder_object*>(mData + offset);
+ uint32_t type = flat->hdr.type;
+ if (!(type == BINDER_TYPE_BINDER || type == BINDER_TYPE_HANDLE ||
+ type == BINDER_TYPE_FD)) {
+ // We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
+ // them in libbinder. If we do receive them, it probably means a kernel bug; try to
+ // recover gracefully by clearing out the objects, and releasing the objects we do
+ // know about.
+ android_errorWriteLog(0x534e4554, "135930648");
+ ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
+ __func__, type, (uint64_t)offset);
+ releaseObjects();
+ mObjectsSize = 0;
+ break;
+ }
minOffset = offset + sizeof(flat_binder_object);
}
scanForFds();
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index dec75f5a64..1095c7f28c 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -64,6 +64,10 @@ public:
// This must be called before the object is sent to another process. Not thread safe.
void setRequestingSid(bool requestSid);
+ sp<IBinder> getExtension();
+ // This must be called before the object is sent to another process. Not thread safe.
+ void setExtension(const sp<IBinder>& extension);
+
protected:
virtual ~BBinder();
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index aa44285b6e..408037e711 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -59,6 +59,7 @@ public:
SHELL_COMMAND_TRANSACTION = B_PACK_CHARS('_','C','M','D'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
+ EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
@@ -86,6 +87,49 @@ public:
Vector<String16>& args, const sp<IShellCallback>& callback,
const sp<IResultReceiver>& resultReceiver);
+ /**
+ * This allows someone to add their own additions to an interface without
+ * having to modify the original interface.
+ *
+ * For instance, imagine if we have this interface:
+ * interface IFoo { void doFoo(); }
+ *
+ * If an unrelated owner (perhaps in a downstream codebase) wants to make a
+ * change to the interface, they have two options:
+ *
+ * A). Historical option that has proven to be BAD! Only the original
+ * author of an interface should change an interface. If someone
+ * downstream wants additional functionality, they should not ever
+ * change the interface or use this method.
+ *
+ * BAD TO DO: interface IFoo { BAD TO DO
+ * BAD TO DO: void doFoo(); BAD TO DO
+ * BAD TO DO: + void doBar(); // adding a method BAD TO DO
+ * BAD TO DO: } BAD TO DO
+ *
+ * B). Option that this method enables!
+ * Leave the original interface unchanged (do not change IFoo!).
+ * Instead, create a new interface in a downstream package:
+ *
+ * package com.<name>; // new functionality in a new package
+ * interface IBar { void doBar(); }
+ *
+ * When registering the interface, add:
+ * sp<MyFoo> foo = new MyFoo; // class in AOSP codebase
+ * sp<MyBar> bar = new MyBar; // custom extension class
+ * foo->setExtension(bar); // use method in BBinder
+ *
+ * Then, clients of IFoo can get this extension:
+ * sp<IBinder> binder = ...;
+ * sp<IFoo> foo = interface_cast<IFoo>(binder); // handle if null
+ * sp<IBinder> barBinder;
+ * ... handle error ... = binder->getExtension(&barBinder);
+ * sp<IBar> bar = interface_cast<IBar>(barBinder);
+ * // if bar is null, then there is no extension or a different
+ * // type of extension
+ */
+ status_t getExtension(sp<IBinder>* out);
+
// NOLINTNEXTLINE(google-default-arguments)
virtual status_t transact( uint32_t code,
const Parcel& data,
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 9de346054d..5c6cf9db64 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -72,6 +72,7 @@ enum BinderLibTestTranscationCode {
BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION,
BINDER_LIB_TEST_ECHO_VECTOR,
+ BINDER_LIB_TEST_REJECT_BUF,
};
pid_t start_server_process(int arg2, bool usePoll = false)
@@ -769,6 +770,24 @@ TEST_F(BinderLibTest, PromoteLocal) {
EXPECT_TRUE(strong_from_weak == nullptr);
}
+TEST_F(BinderLibTest, LocalGetExtension) {
+ sp<BBinder> binder = new BBinder();
+ sp<IBinder> ext = new BBinder();
+ binder->setExtension(ext);
+ EXPECT_EQ(ext, binder->getExtension());
+}
+
+TEST_F(BinderLibTest, RemoteGetExtension) {
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != nullptr);
+
+ sp<IBinder> extension;
+ EXPECT_EQ(NO_ERROR, server->getExtension(&extension));
+ ASSERT_NE(nullptr, extension.get());
+
+ EXPECT_EQ(NO_ERROR, extension->pingBinder());
+}
+
TEST_F(BinderLibTest, CheckHandleZeroBinderHighBitsZeroCookie) {
status_t ret;
Parcel data, reply;
@@ -1006,6 +1025,34 @@ TEST_F(BinderLibTest, VectorSent) {
EXPECT_EQ(readValue, testValue);
}
+TEST_F(BinderLibTest, BufRejected) {
+ Parcel data, reply;
+ uint32_t buf;
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != nullptr);
+
+ binder_buffer_object obj {
+ .hdr = { .type = BINDER_TYPE_PTR },
+ .buffer = reinterpret_cast<binder_uintptr_t>((void*)&buf),
+ .length = 4,
+ .flags = 0,
+ };
+ data.setDataCapacity(1024);
+ // Write a bogus object at offset 0 to get an entry in the offset table
+ data.writeFileDescriptor(0);
+ EXPECT_EQ(data.objectsCount(), 1);
+ uint8_t *parcelData = const_cast<uint8_t*>(data.data());
+ // And now, overwrite it with the buffer object
+ memcpy(parcelData, &obj, sizeof(obj));
+ data.setDataSize(sizeof(obj));
+
+ status_t ret = server->transact(BINDER_LIB_TEST_REJECT_BUF, data, &reply);
+ // Either the kernel should reject this transaction (if it's correct), but
+ // if it's not, the server implementation should return an error if it
+ // finds an object in the received Parcel.
+ EXPECT_NE(NO_ERROR, ret);
+}
+
class BinderLibTestService : public BBinder
{
public:
@@ -1288,6 +1335,9 @@ class BinderLibTestService : public BBinder
reply->writeUint64Vector(vector);
return NO_ERROR;
}
+ case BINDER_LIB_TEST_REJECT_BUF: {
+ return data.objectsCount() == 0 ? BAD_VALUE : NO_ERROR;
+ }
default:
return UNKNOWN_TRANSACTION;
};
@@ -1312,6 +1362,16 @@ int run_server(int index, int readypipefd, bool usePoll)
BinderLibTestService* testServicePtr;
{
sp<BinderLibTestService> testService = new BinderLibTestService(index);
+
+ /*
+ * Normally would also contain functionality as well, but we are only
+ * testing the extension mechanism.
+ */
+ testService->setExtension(new BBinder());
+
+ // Required for test "BufRejected'
+ testService->setRequestingSid(true);
+
/*
* We need this below, but can't hold a sp<> because it prevents the
* node from being cleaned up automatically. It's safe in this case
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 12deaf0bd6..dc161b7222 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -93,7 +93,7 @@ public:
if (data.writeVectorSize(listenerCallbacks) == NO_ERROR) {
for (const auto& [listener, callbackIds] : listenerCallbacks) {
- data.writeStrongBinder(IInterface::asBinder(listener));
+ data.writeStrongBinder(listener);
data.writeInt64Vector(callbackIds);
}
}
@@ -1042,8 +1042,7 @@ status_t BnSurfaceComposer::onTransact(
std::vector<ListenerCallbacks> listenerCallbacks;
int32_t listenersSize = data.readInt32();
for (int32_t i = 0; i < listenersSize; i++) {
- auto listener =
- interface_cast<ITransactionCompletedListener>(data.readStrongBinder());
+ auto listener = data.readStrongBinder();
std::vector<CallbackId> callbackIds;
data.readInt64Vector(&callbackIds);
listenerCallbacks.emplace_back(listener, callbackIds);
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index 74cd4f1ede..acda6001cc 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -151,7 +151,7 @@ status_t ListenerStats::readFromParcel(const Parcel* input) {
return NO_ERROR;
}
-ListenerStats ListenerStats::createEmpty(const sp<ITransactionCompletedListener>& listener,
+ListenerStats ListenerStats::createEmpty(const sp<IBinder>& listener,
const std::unordered_set<CallbackId>& callbackIds) {
ListenerStats listenerStats;
listenerStats.listener = listener;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index e6b1beb2c4..5faf010d72 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -548,7 +548,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
continue;
}
- listenerCallbacks.emplace_back(listener, std::move(callbackIds));
+ listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
// If the listener has any SurfaceControls set on this Transaction update the surface state
for (const auto& surfaceControl : surfaceControls) {
@@ -795,14 +795,15 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMetadata(
- const sp<SurfaceControl>& sc, uint32_t key, std::vector<uint8_t> data) {
+ const sp<SurfaceControl>& sc, uint32_t key, const Parcel& p) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eMetadataChanged;
- s->metadata.mMap[key] = std::move(data);
+
+ s->metadata.mMap[key] = {p.data(), p.data() + p.dataSize()};
registerSurfaceControlForCallback(sc);
return *this;
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index cbfd365692..178ca2d7e2 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -31,6 +31,7 @@
namespace android {
class ITransactionCompletedListener;
+class ListenerCallbacks;
using CallbackId = int64_t;
@@ -72,10 +73,10 @@ public:
status_t writeToParcel(Parcel* output) const override;
status_t readFromParcel(const Parcel* input) override;
- static ListenerStats createEmpty(const sp<ITransactionCompletedListener>& listener,
+ static ListenerStats createEmpty(const sp<IBinder>& listener,
const std::unordered_set<CallbackId>& callbackIds);
- sp<ITransactionCompletedListener> listener;
+ sp<IBinder> listener;
std::vector<TransactionStats> transactionStats;
};
@@ -97,13 +98,11 @@ public:
class ListenerCallbacks {
public:
- ListenerCallbacks(const sp<ITransactionCompletedListener>& listener,
- const std::unordered_set<CallbackId>& callbacks)
+ ListenerCallbacks(const sp<IBinder>& listener, const std::unordered_set<CallbackId>& callbacks)
: transactionCompletedListener(listener),
callbackIds(callbacks.begin(), callbacks.end()) {}
- ListenerCallbacks(const sp<ITransactionCompletedListener>& listener,
- const std::vector<CallbackId>& ids)
+ ListenerCallbacks(const sp<IBinder>& listener, const std::vector<CallbackId>& ids)
: transactionCompletedListener(listener), callbackIds(ids) {}
bool operator==(const ListenerCallbacks& rhs) const {
@@ -116,8 +115,42 @@ public:
return callbackIds.front() == rhs.callbackIds.front();
}
- sp<ITransactionCompletedListener> transactionCompletedListener;
+ sp<IBinder> transactionCompletedListener;
std::vector<CallbackId> callbackIds;
};
+struct IListenerHash {
+ std::size_t operator()(const sp<IBinder>& strongPointer) const {
+ return std::hash<IBinder*>{}(strongPointer.get());
+ }
+};
+
+struct CallbackIdsHash {
+ // CallbackId vectors have several properties that let us get away with this simple hash.
+ // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is
+ // empty we can still hash 0.
+ // 2) CallbackId vectors for the same listener either are identical or contain none of the
+ // same members. It is sufficient to just check the first CallbackId in the vectors. If
+ // they match, they are the same. If they do not match, they are not the same.
+ std::size_t operator()(const std::vector<CallbackId>& callbackIds) const {
+ return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front());
+ }
+};
+
+struct ListenerCallbacksHash {
+ std::size_t HashCombine(size_t value1, size_t value2) const {
+ return value1 ^ (value2 + 0x9e3779b9 + (value1 << 6) + (value1 >> 2));
+ }
+
+ std::size_t operator()(const ListenerCallbacks& listenerCallbacks) const {
+ struct IListenerHash listenerHasher;
+ struct CallbackIdsHash callbackIdsHasher;
+
+ std::size_t listenerHash = listenerHasher(listenerCallbacks.transactionCompletedListener);
+ std::size_t callbackIdsHash = callbackIdsHasher(listenerCallbacks.callbackIds);
+
+ return HashCombine(listenerHash, callbackIdsHash);
+ }
+};
+
} // namespace android
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 47f0cede3a..d58e019799 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -22,7 +22,12 @@
namespace android {
-enum { METADATA_OWNER_UID = 1, METADATA_WINDOW_TYPE = 2, METADATA_TASK_ID = 3 };
+enum {
+ METADATA_OWNER_UID = 1,
+ METADATA_WINDOW_TYPE = 2,
+ METADATA_TASK_ID = 3,
+ METADATA_MOUSE_CURSOR = 4,
+};
struct LayerMetadata : public Parcelable {
std::unordered_map<uint32_t, std::vector<uint8_t>> mMap;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 22ab62da44..f303a03254 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -379,8 +379,7 @@ public:
Transaction& setCrop_legacy(const sp<SurfaceControl>& sc, const Rect& crop);
Transaction& setCornerRadius(const sp<SurfaceControl>& sc, float cornerRadius);
Transaction& setLayerStack(const sp<SurfaceControl>& sc, uint32_t layerStack);
- Transaction& setMetadata(const sp<SurfaceControl>& sc, uint32_t key,
- std::vector<uint8_t> data);
+ Transaction& setMetadata(const sp<SurfaceControl>& sc, uint32_t key, const Parcel& p);
// Defers applying any changes made in this transaction until the Layer
// identified by handle reaches the given frameNumber. If the Layer identified
// by handle is removed, then we will apply this transaction regardless of
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index d6a73bfd27..90f6e09a69 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -92,15 +92,13 @@ status_t BnInputFlinger::onTransact(
}
case REGISTER_INPUT_CHANNEL_TRANSACTION: {
CHECK_INTERFACE(IInputFlinger, data, reply);
- sp<InputChannel> channel = new InputChannel();
- channel->read(data);
+ sp<InputChannel> channel = InputChannel::read(data);
registerInputChannel(channel);
break;
}
case UNREGISTER_INPUT_CHANNEL_TRANSACTION: {
CHECK_INTERFACE(IInputFlinger, data, reply);
- sp<InputChannel> channel = new InputChannel();
- channel->read(data);
+ sp<InputChannel> channel = InputChannel::read(data);
unregisterInputChannel(channel);
break;
}
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 2ff301e270..7835651f11 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -227,35 +227,28 @@ void InputMessage::getSanitizedCopy(InputMessage* msg) const {
// --- InputChannel ---
-InputChannel::InputChannel(const std::string& name, int fd) :
- mName(name) {
+sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) {
+ const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
+ if (result != 0) {
+ LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
+ strerror(errno));
+ return nullptr;
+ }
+ return new InputChannel(name, std::move(fd));
+}
+
+InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd)
+ : mName(name), mFd(std::move(fd)) {
#if DEBUG_CHANNEL_LIFECYCLE
ALOGD("Input channel constructed: name='%s', fd=%d",
mName.c_str(), fd);
#endif
-
- setFd(fd);
}
InputChannel::~InputChannel() {
#if DEBUG_CHANNEL_LIFECYCLE
- ALOGD("Input channel destroyed: name='%s', fd=%d",
- mName.c_str(), mFd);
+ ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
#endif
-
- ::close(mFd);
-}
-
-void InputChannel::setFd(int fd) {
- if (mFd > 0) {
- ::close(mFd);
- }
- mFd = fd;
- if (mFd > 0) {
- int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
- "non-blocking. errno=%d", mName.c_str(), errno);
- }
}
status_t InputChannel::openInputChannelPair(const std::string& name,
@@ -276,13 +269,13 @@ status_t InputChannel::openInputChannelPair(const std::string& name,
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
- std::string serverChannelName = name;
- serverChannelName += " (server)";
- outServerChannel = new InputChannel(serverChannelName, sockets[0]);
+ std::string serverChannelName = name + " (server)";
+ android::base::unique_fd serverFd(sockets[0]);
+ outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd));
- std::string clientChannelName = name;
- clientChannelName += " (client)";
- outClientChannel = new InputChannel(clientChannelName, sockets[1]);
+ std::string clientChannelName = name + " (client)";
+ android::base::unique_fd clientFd(sockets[1]);
+ outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd));
return OK;
}
@@ -292,7 +285,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) {
msg->getSanitizedCopy(&cleanMsg);
ssize_t nWrite;
do {
- nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
+ nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (nWrite == -1 && errno == EINTR);
if (nWrite < 0) {
@@ -327,7 +320,7 @@ status_t InputChannel::sendMessage(const InputMessage* msg) {
status_t InputChannel::receiveMessage(InputMessage* msg) {
ssize_t nRead;
do {
- nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
+ nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
} while (nRead == -1 && errno == EINTR);
if (nRead < 0) {
@@ -365,39 +358,44 @@ status_t InputChannel::receiveMessage(InputMessage* msg) {
}
sp<InputChannel> InputChannel::dup() const {
- int fd = ::dup(getFd());
- return fd >= 0 ? new InputChannel(getName(), fd) : nullptr;
+ android::base::unique_fd newFd(::dup(getFd()));
+ if (!newFd.ok()) {
+ ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), mName.c_str(),
+ strerror(errno));
+ return nullptr;
+ }
+ return InputChannel::create(mName, std::move(newFd));
}
-
status_t InputChannel::write(Parcel& out) const {
- status_t s = out.writeString8(String8(getName().c_str()));
-
+ status_t s = out.writeCString(getName().c_str());
if (s != OK) {
return s;
}
+
s = out.writeStrongBinder(mToken);
if (s != OK) {
return s;
}
- s = out.writeDupFileDescriptor(getFd());
-
+ s = out.writeUniqueFileDescriptor(mFd);
return s;
}
-status_t InputChannel::read(const Parcel& from) {
- mName = from.readString8();
- mToken = from.readStrongBinder();
-
- int rawFd = from.readFileDescriptor();
- setFd(::dup(rawFd));
-
- if (mFd < 0) {
- return BAD_VALUE;
+sp<InputChannel> InputChannel::read(const Parcel& from) {
+ std::string name = from.readCString();
+ sp<IBinder> token = from.readStrongBinder();
+ android::base::unique_fd rawFd;
+ status_t fdResult = from.readUniqueFileDescriptor(&rawFd);
+ if (fdResult != OK) {
+ return nullptr;
}
- return OK;
+ sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd));
+ if (channel != nullptr) {
+ channel->setToken(token);
+ }
+ return channel;
}
sp<IBinder> InputChannel::getToken() const {
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
index f1675c0d36..af74edd65d 100644
--- a/libs/input/tests/InputChannel_test.cpp
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -22,11 +22,12 @@
#include <time.h>
#include <errno.h>
+#include <binder/Binder.h>
#include <gtest/gtest.h>
#include <input/InputTransport.h>
-#include <utils/Timers.h>
#include <utils/StopWatch.h>
#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
namespace android {
@@ -43,20 +44,28 @@ TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptor
// of a pipe and to check for EPIPE on the other end after the channel is destroyed.
Pipe pipe;
- sp<InputChannel> inputChannel = new InputChannel("channel name", pipe.sendFd);
+ android::base::unique_fd sendFd(pipe.sendFd);
+
+ sp<InputChannel> inputChannel = InputChannel::create("channel name", std::move(sendFd));
+ EXPECT_NE(inputChannel, nullptr) << "channel should be successfully created";
EXPECT_STREQ("channel name", inputChannel->getName().c_str())
<< "channel should have provided name";
- EXPECT_EQ(pipe.sendFd, inputChannel->getFd())
- << "channel should have provided fd";
+ EXPECT_NE(-1, inputChannel->getFd()) << "channel should have valid fd";
- inputChannel.clear(); // destroys input channel
+ // InputChannel should be the owner of the file descriptor now
+ ASSERT_FALSE(sendFd.ok());
+}
- EXPECT_EQ(-EPIPE, pipe.readSignal())
- << "channel should have closed fd when destroyed";
+TEST_F(InputChannelTest, SetAndGetToken) {
+ Pipe pipe;
+ sp<InputChannel> channel =
+ InputChannel::create("test channel", android::base::unique_fd(pipe.sendFd));
+ EXPECT_EQ(channel->getToken(), nullptr);
- // clean up fds of Pipe endpoints that were closed so we don't try to close them again
- pipe.sendFd = -1;
+ sp<IBinder> token = new BBinder();
+ channel->setToken(token);
+ EXPECT_EQ(token, channel->getToken());
}
TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index cc252d67ae..136ad0da62 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -71,9 +71,6 @@ cc_library_static {
"-fvisibility=hidden",
"-Werror=format",
],
- cppflags: [
- "-fwhole-program-vtables", // requires ThinLTO
- ],
srcs: [
":librenderengine_sources",
":librenderengine_gl_sources",
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 2bbb0ee50a..8462fe7584 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -65,6 +65,7 @@ cc_library_shared {
"Gralloc.cpp",
"Gralloc2.cpp",
"Gralloc3.cpp",
+ "Gralloc4.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
@@ -89,10 +90,12 @@ cc_library_shared {
"android.frameworks.bufferhub@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
"android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
"libbase",
"libcutils",
"libhidlbase",
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
new file mode 100644
index 0000000000..dc105c095c
--- /dev/null
+++ b/libs/ui/Gralloc4.cpp
@@ -0,0 +1,405 @@
+/*
+ * Copyright 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.
+ */
+
+#define LOG_TAG "Gralloc4"
+
+#include <hidl/ServiceManagement.h>
+#include <hwbinder/IPCThreadState.h>
+#include <ui/Gralloc4.h>
+
+#include <inttypes.h>
+#include <log/log.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#include <sync/sync.h>
+#pragma clang diagnostic pop
+
+using android::hardware::graphics::allocator::V4_0::IAllocator;
+using android::hardware::graphics::common::V1_2::BufferUsage;
+using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V4_0::Error;
+using android::hardware::graphics::mapper::V4_0::IMapper;
+using android::hardware::graphics::mapper::V4_0::YCbCrLayout;
+
+namespace android {
+
+namespace {
+
+static constexpr Error kTransactionError = Error::NO_RESOURCES;
+
+uint64_t getValidUsageBits() {
+ static const uint64_t validUsageBits = []() -> uint64_t {
+ uint64_t bits = 0;
+ for (const auto bit :
+ hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
+ bits = bits | bit;
+ }
+ return bits;
+ }();
+ return validUsageBits;
+}
+
+static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
+ IMapper::Rect outRect{};
+ outRect.left = rect.left;
+ outRect.top = rect.top;
+ outRect.width = rect.width();
+ outRect.height = rect.height();
+ return outRect;
+}
+static inline void sBufferDescriptorInfo(uint32_t width, uint32_t height,
+ android::PixelFormat format, uint32_t layerCount,
+ uint64_t usage,
+ IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+ outDescriptorInfo->width = width;
+ outDescriptorInfo->height = height;
+ outDescriptorInfo->layerCount = layerCount;
+ outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
+ outDescriptorInfo->usage = usage;
+}
+
+} // anonymous namespace
+
+void Gralloc4Mapper::preload() {
+ android::hardware::preloadPassthroughService<IMapper>();
+}
+
+Gralloc4Mapper::Gralloc4Mapper() {
+ mMapper = IMapper::getService();
+ if (mMapper == nullptr) {
+ ALOGI("mapper 4.x is not supported");
+ return;
+ }
+ if (mMapper->isRemote()) {
+ LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
+ }
+}
+
+bool Gralloc4Mapper::isLoaded() const {
+ return mMapper != nullptr;
+}
+
+status_t Gralloc4Mapper::validateBufferDescriptorInfo(
+ IMapper::BufferDescriptorInfo* descriptorInfo) const {
+ uint64_t validUsageBits = getValidUsageBits();
+
+ if (descriptorInfo->usage & ~validUsageBits) {
+ ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
+ descriptorInfo->usage & ~validUsageBits);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
+ void* outBufferDescriptor) const {
+ IMapper::BufferDescriptorInfo* descriptorInfo =
+ static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
+ BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
+
+ status_t status = validateBufferDescriptorInfo(descriptorInfo);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ Error error;
+ auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+ *outDescriptor = tmpDescriptor;
+ };
+
+ hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
+
+ return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const {
+ Error error;
+ auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+ *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
+ });
+
+ return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapper->freeBuffer(buffer);
+
+ auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
+ ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
+}
+
+status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
+ uint32_t height, android::PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ uint32_t stride) const {
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
+
+ return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
+}
+
+void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
+ uint32_t* outNumInts) const {
+ *outNumFds = uint32_t(bufferHandle->numFds);
+ *outNumInts = uint32_t(bufferHandle->numInts);
+
+ Error error;
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapper->getTransportSize(buffer,
+ [&](const auto& tmpError, const auto& tmpNumFds,
+ const auto& tmpNumInts) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+ *outNumFds = tmpNumFds;
+ *outNumInts = tmpNumInts;
+ });
+
+ error = (ret.isOk()) ? error : kTransactionError;
+
+ ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
+}
+
+status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+ int acquireFence, void** outData, int32_t* outBytesPerPixel,
+ int32_t* outBytesPerStride) const {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ IMapper::Rect accessRegion = sGralloc4Rect(bounds);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ Error error;
+ auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData,
+ const auto& tmpBytesPerPixel, const auto& tmpBytesPerStride) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+ *outData = tmpData;
+ if (outBytesPerPixel) {
+ *outBytesPerPixel = tmpBytesPerPixel;
+ }
+ if (outBytesPerStride) {
+ *outBytesPerStride = tmpBytesPerStride;
+ }
+ });
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ error = (ret.isOk()) ? error : kTransactionError;
+
+ ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
+
+ return static_cast<status_t>(error);
+}
+
+status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+ int acquireFence, android_ycbcr* ycbcr) const {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ IMapper::Rect accessRegion = sGralloc4Rect(bounds);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ YCbCrLayout layout;
+ Error error;
+ auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ layout = tmpLayout;
+ });
+
+ if (error == Error::NONE) {
+ ycbcr->y = layout.y;
+ ycbcr->cb = layout.cb;
+ ycbcr->cr = layout.cr;
+ ycbcr->ystride = static_cast<size_t>(layout.yStride);
+ ycbcr->cstride = static_cast<size_t>(layout.cStride);
+ ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
+ }
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ Error error;
+ auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle && fenceHandle->numFds == 1) {
+ int fd = dup(fenceHandle->data[0]);
+ if (fd >= 0) {
+ releaseFence = fd;
+ } else {
+ ALOGD("failed to dup unlock release fence");
+ sync_wait(fenceHandle->data[0], -1);
+ }
+ }
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("unlock(%p) failed with %d", buffer, error);
+ }
+
+ return releaseFence;
+}
+
+status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
+ uint32_t layerCount, uint64_t usage,
+ bool* outSupported) const {
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+
+ Error error;
+ auto ret = mMapper->isSupported(descriptorInfo,
+ [&](const auto& tmpError, const auto& tmpSupported) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+ if (outSupported) {
+ *outSupported = tmpSupported;
+ }
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
+ error);
+ }
+
+ return static_cast<status_t>(error);
+}
+
+Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
+ mAllocator = IAllocator::getService();
+ if (mAllocator == nullptr) {
+ ALOGW("allocator 3.x is not supported");
+ return;
+ }
+}
+
+bool Gralloc4Allocator::isLoaded() const {
+ return mAllocator != nullptr;
+}
+
+std::string Gralloc4Allocator::dumpDebugInfo() const {
+ std::string debugInfo;
+
+ mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+ return debugInfo;
+}
+
+status_t Gralloc4Allocator::allocate(uint32_t width, uint32_t height, android::PixelFormat format,
+ uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
+ IMapper::BufferDescriptorInfo descriptorInfo;
+ sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+
+ BufferDescriptor descriptor;
+ status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
+ static_cast<void*>(&descriptor));
+ if (error != NO_ERROR) {
+ return error;
+ }
+
+ auto ret = mAllocator->allocate(descriptor, bufferCount,
+ [&](const auto& tmpError, const auto& tmpStride,
+ const auto& tmpBuffers) {
+ error = static_cast<status_t>(tmpError);
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ // import buffers
+ for (uint32_t i = 0; i < bufferCount; i++) {
+ error = mMapper.importBuffer(tmpBuffers[i],
+ &outBufferHandles[i]);
+ if (error != NO_ERROR) {
+ for (uint32_t j = 0; j < i; j++) {
+ mMapper.freeBuffer(outBufferHandles[j]);
+ outBufferHandles[j] = nullptr;
+ }
+ return;
+ }
+ }
+ *outStride = tmpStride;
+ });
+
+ // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
+ hardware::IPCThreadState::self()->flushCommands();
+
+ return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
+}
+
+} // namespace android
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 9c7d1fda90..eb787a2e40 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -33,6 +33,7 @@
#include <ui/Gralloc.h>
#include <ui/Gralloc2.h>
#include <ui/Gralloc3.h>
+#include <ui/Gralloc4.h>
#include <ui/GraphicBufferMapper.h>
namespace android {
@@ -47,16 +48,23 @@ KeyedVector<buffer_handle_t,
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
+ mAllocator = std::make_unique<const Gralloc4Allocator>(
+ reinterpret_cast<const Gralloc4Mapper&>(mMapper.getGrallocMapper()));
+ if (mAllocator->isLoaded()) {
+ return;
+ }
mAllocator = std::make_unique<const Gralloc3Allocator>(
reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
- if (!mAllocator->isLoaded()) {
- mAllocator = std::make_unique<const Gralloc2Allocator>(
- reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
+ if (mAllocator->isLoaded()) {
+ return;
}
-
- if (!mAllocator->isLoaded()) {
- LOG_ALWAYS_FATAL("gralloc-allocator is missing");
+ mAllocator = std::make_unique<const Gralloc2Allocator>(
+ reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
+ if (mAllocator->isLoaded()) {
+ return;
}
+
+ LOG_ALWAYS_FATAL("gralloc-allocator is missing");
}
GraphicBufferAllocator::~GraphicBufferAllocator() {}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 25b7247b1b..4d087d151c 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -35,6 +35,7 @@
#include <ui/Gralloc.h>
#include <ui/Gralloc2.h>
#include <ui/Gralloc3.h>
+#include <ui/Gralloc4.h>
#include <ui/GraphicBuffer.h>
#include <system/graphics.h>
@@ -47,20 +48,27 @@ ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
void GraphicBufferMapper::preloadHal() {
Gralloc2Mapper::preload();
Gralloc3Mapper::preload();
+ Gralloc4Mapper::preload();
}
GraphicBufferMapper::GraphicBufferMapper() {
+ mMapper = std::make_unique<const Gralloc4Mapper>();
+ if (mMapper->isLoaded()) {
+ mMapperVersion = Version::GRALLOC_4;
+ return;
+ }
mMapper = std::make_unique<const Gralloc3Mapper>();
- if (!mMapper->isLoaded()) {
- mMapper = std::make_unique<const Gralloc2Mapper>();
- mMapperVersion = Version::GRALLOC_2;
- } else {
+ if (mMapper->isLoaded()) {
mMapperVersion = Version::GRALLOC_3;
+ return;
}
-
- if (!mMapper->isLoaded()) {
- LOG_ALWAYS_FATAL("gralloc-mapper is missing");
+ mMapper = std::make_unique<const Gralloc2Mapper>();
+ if (mMapper->isLoaded()) {
+ mMapperVersion = Version::GRALLOC_2;
+ return;
}
+
+ LOG_ALWAYS_FATAL("gralloc-mapper is missing");
}
status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
new file mode 100644
index 0000000000..14b65bc220
--- /dev/null
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 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 ANDROID_UI_GRALLOC4_H
+#define ANDROID_UI_GRALLOC4_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
+#include <android/hardware/graphics/common/1.1/types.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#include <ui/Gralloc.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class Gralloc4Mapper : public GrallocMapper {
+public:
+ static void preload();
+
+ Gralloc4Mapper();
+
+ bool isLoaded() const override;
+
+ status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
+
+ status_t importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const override;
+
+ void freeBuffer(buffer_handle_t bufferHandle) const override;
+
+ status_t validateBufferSize(buffer_handle_t bufferHandle, uint32_t width, uint32_t height,
+ android::PixelFormat format, uint32_t layerCount, uint64_t usage,
+ uint32_t stride) const override;
+
+ void getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
+ uint32_t* outNumInts) const override;
+
+ status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+ int acquireFence, void** outData, int32_t* outBytesPerPixel,
+ int32_t* outBytesPerStride) const override;
+
+ status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+ int acquireFence, android_ycbcr* ycbcr) const override;
+
+ int unlock(buffer_handle_t bufferHandle) const override;
+
+ status_t isSupported(uint32_t width, uint32_t height, android::PixelFormat format,
+ uint32_t layerCount, uint64_t usage, bool* outSupported) const override;
+
+private:
+ // Determines whether the passed info is compatible with the mapper.
+ status_t validateBufferDescriptorInfo(
+ hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo* descriptorInfo) const;
+
+ sp<hardware::graphics::mapper::V4_0::IMapper> mMapper;
+};
+
+class Gralloc4Allocator : public GrallocAllocator {
+public:
+ // An allocator relies on a mapper, and that mapper must be alive at all
+ // time.
+ Gralloc4Allocator(const Gralloc4Mapper& mapper);
+
+ bool isLoaded() const override;
+
+ std::string dumpDebugInfo() const override;
+
+ status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+ uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+ buffer_handle_t* outBufferHandles) const override;
+
+private:
+ const Gralloc4Mapper& mMapper;
+ sp<hardware::graphics::allocator::V4_0::IAllocator> mAllocator;
+};
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC4_H
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 24614549be..c401a4863c 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -44,6 +44,7 @@ public:
enum Version {
GRALLOC_2,
GRALLOC_3,
+ GRALLOC_4,
};
static void preloadHal();
static inline GraphicBufferMapper& get() { return getInstance(); }
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index e50dfca0a1..42d566f7a2 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -261,7 +261,7 @@ status_t GpuService::doDump(int fd, const Vector<String16>& args, bool /*asProto
dumpDriverInfo = true;
} else if (args[index] == String16("--gpumem")) {
dumpMemory = true;
- } else if (args[index].compare(String16("--gpumem=")) > 0) {
+ } else if (args[index].startsWith(String16("--gpumem="))) {
dumpMemory = true;
pid = atoi(String8(&args[index][9]));
}
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index fb8d7d027f..ee44cbe836 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -62,10 +62,6 @@ public:
void useSurfaceDamage() override;
void useEmptyDamage() override;
- // getTypeId - Provide unique string for each class type in the Layer
- // hierarchy
- const char* getTypeId() const override { return "BufferLayer"; }
-
bool isOpaque(const Layer::State& s) const override;
// isVisible - true if this layer is visible, false otherwise
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 392b706416..3bc625e462 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -38,6 +38,8 @@ public:
// Interface implementation for Layer
// -----------------------------------------------------------------------
public:
+ const char* getType() const override { return "BufferQueueLayer"; }
+
void onLayerDisplayed(const sp<Fence>& releaseFence) override;
void setTransformHint(uint32_t orientation) const override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 611decf550..e0804ff50e 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -227,10 +227,10 @@ bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, nsecs_t postTi
setTransactionFlags(eTransactionNeeded);
mFlinger->mTimeStats->setPostTime(getSequence(), mFrameNumber, getName().c_str(), postTime);
- mDesiredPresentTime = desiredPresentTime;
+ mCurrentState.desiredPresentTime = desiredPresentTime;
if (mFlinger->mUseSmart90ForVideo) {
- const nsecs_t presentTime = (mDesiredPresentTime == -1) ? 0 : mDesiredPresentTime;
+ const nsecs_t presentTime = (desiredPresentTime == -1) ? 0 : desiredPresentTime;
mFlinger->mScheduler->addLayerPresentTimeAndHDR(mSchedulerLayerHandle, presentTime,
mCurrentState.hdrMetadata.validTypes != 0);
}
@@ -384,11 +384,11 @@ bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) co
return true;
}
- return mDesiredPresentTime <= expectedPresentTime;
+ return mCurrentState.desiredPresentTime <= expectedPresentTime;
}
nsecs_t BufferStateLayer::getDesiredPresentTime() {
- return mDesiredPresentTime;
+ return getDrawingState().desiredPresentTime;
}
std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 6db91ef34e..cc670087ac 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -40,6 +40,8 @@ public:
// -----------------------------------------------------------------------
// Interface implementation for Layer
// -----------------------------------------------------------------------
+ const char* getType() const override { return "BufferStateLayer"; }
+
void onLayerDisplayed(const sp<Fence>& releaseFence) override;
void setTransformHint(uint32_t orientation) const override;
void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -159,8 +161,6 @@ private:
bool mReleasePreviousBuffer = false;
nsecs_t mCallbackHandleAcquireTime = -1;
- nsecs_t mDesiredPresentTime = -1;
-
// TODO(marissaw): support sticky transform for LEGACY camera mode
class HwcSlotGenerator : public ClientCache::ErasedRecipient {
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index b65d351263..2ad7591b86 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -108,6 +108,10 @@ std::shared_ptr<compositionengine::Layer> ColorLayer::getCompositionLayer() cons
return mCompositionLayer;
}
+bool ColorLayer::isOpaque(const Layer::State& s) const {
+ return (s.flags & layer_state_t::eLayerOpaque) != 0;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 015b939457..57c54c7e2c 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -30,7 +30,7 @@ public:
std::shared_ptr<compositionengine::Layer> getCompositionLayer() const override;
- virtual const char* getTypeId() const { return "ColorLayer"; }
+ const char* getType() const override { return "ColorLayer"; }
bool isVisible() const override;
bool setColor(const half3& color) override;
@@ -39,6 +39,8 @@ public:
void commitTransaction(const State& stateToCommit) override;
+ bool isOpaque(const Layer::State& s) const override;
+
protected:
/*
* compositionengine::LayerFE overrides
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index ae6bdbce60..580bde8624 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -119,6 +119,13 @@ cc_test {
//
// You can either "make dist tests" before flashing, or set this
// option to false temporarily.
- address: true,
+
+
+ // FIXME: ASAN build is broken for a while, but was not discovered
+ // since new PM silently suppressed ASAN. Temporarily turn off ASAN
+ // to unblock the compiler upgrade process.
+ // address: true,
+ // http://b/139747256
+ address: false,
},
}
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index a1607ffabb..f0fbb6104f 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -28,7 +28,7 @@ public:
explicit ContainerLayer(const LayerCreationArgs&);
~ContainerLayer() override;
- const char* getTypeId() const override { return "ContainerLayer"; }
+ const char* getType() const override { return "ContainerLayer"; }
bool isVisible() const override;
bool canReceiveInput() const override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index db4ae41bc8..5121835cae 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1217,7 +1217,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const {
info.mName = getName();
sp<Layer> parent = getParent();
info.mParentName = (parent == nullptr ? std::string("none") : parent->getName().string());
- info.mType = std::string(getTypeId());
+ info.mType = getType();
info.mTransparentRegion = ds.activeTransparentRegion_legacy;
info.mVisibleRegion = visibleRegion;
info.mSurfaceDamageRegion = surfaceDamageRegion;
@@ -1334,7 +1334,7 @@ void Layer::getFrameStats(FrameStats* outStats) const {
}
void Layer::dumpFrameEvents(std::string& result) {
- StringAppendF(&result, "- Layer %s (%s, %p)\n", getName().string(), getTypeId(), this);
+ StringAppendF(&result, "- Layer %s (%s, %p)\n", getName().string(), getType(), this);
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.checkFencesForCompletion();
mFrameEventHistory.dump(result);
@@ -1868,7 +1868,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
if (traceFlags & SurfaceTracing::TRACE_CRITICAL) {
layerInfo->set_id(sequence);
layerInfo->set_name(getName().c_str());
- layerInfo->set_type(String8(getTypeId()));
+ layerInfo->set_type(getType());
for (const auto& child : children) {
layerInfo->add_children(child->sequence);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2a1564a440..9107189d52 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -217,6 +217,7 @@ public:
// recent callback handle.
std::deque<sp<CallbackHandle>> callbackHandles;
bool colorSpaceAgnostic;
+ nsecs_t desiredPresentTime = -1;
};
explicit Layer(const LayerCreationArgs& args);
@@ -377,7 +378,9 @@ public:
// -----------------------------------------------------------------------
// Virtuals
- virtual const char* getTypeId() const = 0;
+
+ // Provide unique string for each class type in the Layer hierarchy
+ virtual const char* getType() const = 0;
/*
* isOpaque - true if this surface is opaque
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 27a0f6bbaf..05ba2345e0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -29,6 +29,7 @@
#include <gui/FrameTimestamps.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h>
+#include <gui/ITransactionCompletedListener.h>
#include <gui/LayerState.h>
#include <gui/OccupancyTracker.h>
#include <hardware/hwcomposer_defs.h>
@@ -1024,11 +1025,6 @@ private:
uint32_t mTexturePoolSize = 0;
std::vector<uint32_t> mTexturePool;
- struct IBinderHash {
- std::size_t operator()(const sp<IBinder>& strongPointer) const {
- return std::hash<IBinder*>{}(strongPointer.get());
- }
- };
struct TransactionState {
TransactionState(const Vector<ComposerState>& composerStates,
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
@@ -1053,7 +1049,7 @@ private:
const int64_t postTime;
bool privileged;
};
- std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IBinderHash> mTransactionQueues;
+ std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> mTransactionQueues;
/* ------------------------------------------------------------------------
* Feature prototyping
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index c519f8d647..1324f20e1c 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -24,7 +24,6 @@
#include <cinttypes>
#include <binder/IInterface.h>
-#include <gui/ITransactionCompletedListener.h>
#include <utils/RefBase.h>
namespace android {
@@ -58,7 +57,7 @@ TransactionCompletedThread::~TransactionCompletedThread() {
{
std::lock_guard lock(mMutex);
for (const auto& [listener, transactionStats] : mCompletedTransactions) {
- IInterface::asBinder(listener)->unlinkToDeath(mDeathRecipient);
+ listener->unlinkToDeath(mDeathRecipient);
}
}
}
@@ -85,7 +84,7 @@ status_t TransactionCompletedThread::startRegistration(const ListenerCallbacks&
auto& [listener, callbackIds] = listenerCallbacks;
if (mCompletedTransactions.count(listener) == 0) {
- status_t err = IInterface::asBinder(listener)->linkToDeath(mDeathRecipient);
+ status_t err = listener->linkToDeath(mDeathRecipient);
if (err != NO_ERROR) {
ALOGE("cannot add callback because linkToDeath failed, err: %d", err);
return err;
@@ -119,8 +118,7 @@ status_t TransactionCompletedThread::endRegistration(const ListenerCallbacks& li
}
bool TransactionCompletedThread::isRegisteringTransaction(
- const sp<ITransactionCompletedListener>& transactionListener,
- const std::vector<CallbackId>& callbackIds) {
+ const sp<IBinder>& transactionListener, const std::vector<CallbackId>& callbackIds) {
ListenerCallbacks listenerCallbacks(transactionListener, callbackIds);
auto itr = mRegisteringTransactions.find(listenerCallbacks);
@@ -201,8 +199,8 @@ status_t TransactionCompletedThread::registerUnpresentedCallbackHandle(
}
status_t TransactionCompletedThread::findTransactionStats(
- const sp<ITransactionCompletedListener>& listener,
- const std::vector<CallbackId>& callbackIds, TransactionStats** outTransactionStats) {
+ const sp<IBinder>& listener, const std::vector<CallbackId>& callbackIds,
+ TransactionStats** outTransactionStats) {
auto& transactionStatsDeque = mCompletedTransactions[listener];
// Search back to front because the most recent transactions are at the back of the deque
@@ -300,10 +298,16 @@ void TransactionCompletedThread::threadMain() {
// If the listener has completed transactions
if (!listenerStats.transactionStats.empty()) {
// If the listener is still alive
- if (IInterface::asBinder(listener)->isBinderAlive()) {
- // Send callback
- listenerStats.listener->onTransactionCompleted(listenerStats);
- IInterface::asBinder(listener)->unlinkToDeath(mDeathRecipient);
+ if (listener->isBinderAlive()) {
+ // Send callback. The listener stored in listenerStats
+ // comes from the cross-process setTransactionState call to
+ // SF. This MUST be an ITransactionCompletedListener. We
+ // keep it as an IBinder due to consistency reasons: if we
+ // interface_cast at the IPC boundary when reading a Parcel,
+ // we get pointers that compare unequal in the SF process.
+ interface_cast<ITransactionCompletedListener>(listenerStats.listener)
+ ->onTransactionCompleted(listenerStats);
+ listener->unlinkToDeath(mDeathRecipient);
}
completedTransactionsItr = mCompletedTransactions.erase(completedTransactionsItr);
} else {
@@ -335,7 +339,7 @@ void TransactionCompletedThread::threadMain() {
// -----------------------------------------------------------------------
-CallbackHandle::CallbackHandle(const sp<ITransactionCompletedListener>& transactionListener,
+CallbackHandle::CallbackHandle(const sp<IBinder>& transactionListener,
const std::vector<CallbackId>& ids, const sp<IBinder>& sc)
: listener(transactionListener), callbackIds(ids), surfaceControl(sc) {}
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index e255e5090e..a85ad1e63c 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -31,46 +31,12 @@
namespace android {
-struct ITransactionCompletedListenerHash {
- std::size_t operator()(const sp<ITransactionCompletedListener>& listener) const {
- return std::hash<IBinder*>{}((listener) ? IInterface::asBinder(listener).get() : nullptr);
- }
-};
-
-struct CallbackIdsHash {
- // CallbackId vectors have several properties that let us get away with this simple hash.
- // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is
- // empty we can still hash 0.
- // 2) CallbackId vectors for the same listener either are identical or contain none of the
- // same members. It is sufficient to just check the first CallbackId in the vectors. If
- // they match, they are the same. If they do not match, they are not the same.
- std::size_t operator()(const std::vector<CallbackId>& callbackIds) const {
- return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front());
- }
-};
-
-struct ListenerCallbacksHash {
- std::size_t HashCombine(size_t value1, size_t value2) const {
- return value1 ^ (value2 + 0x9e3779b9 + (value1 << 6) + (value1 >> 2));
- }
-
- std::size_t operator()(const ListenerCallbacks& listenerCallbacks) const {
- struct ITransactionCompletedListenerHash listenerHasher;
- struct CallbackIdsHash callbackIdsHasher;
-
- std::size_t listenerHash = listenerHasher(listenerCallbacks.transactionCompletedListener);
- std::size_t callbackIdsHash = callbackIdsHasher(listenerCallbacks.callbackIds);
-
- return HashCombine(listenerHash, callbackIdsHash);
- }
-};
-
class CallbackHandle : public RefBase {
public:
- CallbackHandle(const sp<ITransactionCompletedListener>& transactionListener,
- const std::vector<CallbackId>& ids, const sp<IBinder>& sc);
+ CallbackHandle(const sp<IBinder>& transactionListener, const std::vector<CallbackId>& ids,
+ const sp<IBinder>& sc);
- sp<ITransactionCompletedListener> listener;
+ sp<IBinder> listener;
std::vector<CallbackId> callbackIds;
wp<IBinder> surfaceControl;
@@ -114,10 +80,10 @@ public:
private:
void threadMain();
- bool isRegisteringTransaction(const sp<ITransactionCompletedListener>& transactionListener,
+ bool isRegisteringTransaction(const sp<IBinder>& transactionListener,
const std::vector<CallbackId>& callbackIds) REQUIRES(mMutex);
- status_t findTransactionStats(const sp<ITransactionCompletedListener>& listener,
+ status_t findTransactionStats(const sp<IBinder>& listener,
const std::vector<CallbackId>& callbackIds,
TransactionStats** outTransactionStats) REQUIRES(mMutex);
@@ -146,13 +112,12 @@ private:
GUARDED_BY(mMutex);
std::unordered_map<
- sp<ITransactionCompletedListener>,
+ sp<IBinder>,
std::unordered_map<std::vector<CallbackId>, uint32_t /*count*/, CallbackIdsHash>,
- ITransactionCompletedListenerHash>
+ IListenerHash>
mPendingTransactions GUARDED_BY(mMutex);
- std::unordered_map<sp<ITransactionCompletedListener>, std::deque<TransactionStats>,
- ITransactionCompletedListenerHash>
+ std::unordered_map<sp<IBinder>, std::deque<TransactionStats>, IListenerHash>
mCompletedTransactions GUARDED_BY(mMutex);
bool mRunning GUARDED_BY(mMutex) = false;
diff --git a/services/surfaceflinger/test.png b/services/surfaceflinger/test.png
deleted file mode 100644
index 773dcc3e72..0000000000
--- a/services/surfaceflinger/test.png
+++ /dev/null
Binary files differ
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index a2c0611b1e..644cd7e698 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -10,8 +10,10 @@ cc_test {
],
shared_libs: [
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.1-resources",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
"android.hardware.power@1.3",
"libbase",
"libbinder",
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 1604775da5..0e5faf4058 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -14,8 +14,10 @@ cc_library_shared {
shared_libs: [
"android.frameworks.vr.composer@1.0",
"android.hardware.graphics.composer@2.1",
+ "android.hardware.graphics.composer@2.1-resources",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
"libbase",
"libbufferhubqueue",
"libbinder",