diff options
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 Binary files differdeleted file mode 100644 index 773dcc3e72..0000000000 --- a/services/surfaceflinger/test.png +++ /dev/null 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", |