diff options
71 files changed, 2456 insertions, 612 deletions
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl index 37ff4428a1..347856ddcb 100644 --- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl +++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl @@ -61,7 +61,6 @@ interface IDumpstate { // Default mode. const int BUGREPORT_MODE_DEFAULT = 6; - // TODO(b/111441001): Should the args be for the consuming application rather than triggering? /* * Starts a bugreport in the background. * diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp index 71b710b0d3..1d4a2f0e5e 100644 --- a/cmds/installd/tests/installd_dexopt_test.cpp +++ b/cmds/installd/tests/installd_dexopt_test.cpp @@ -576,7 +576,7 @@ TEST_F(DexoptTest, DexoptSecondaryStorageValidationError) { CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_DE, /*binder_ok*/ false, /*compile_ok*/ false, &status); EXPECT_STREQ(status.toString8().c_str(), - "Status(-8): '-1: Dexoptanalyzer path validation failed'"); + "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'"); } TEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) { @@ -585,7 +585,7 @@ TEST_F(DexoptTest, DexoptSecondaryAppOwnershipValidationError) { CompileSecondaryDex("/data/data/random.app/secondary.jar", DEXOPT_STORAGE_CE, /*binder_ok*/ false, /*compile_ok*/ false, &status); EXPECT_STREQ(status.toString8().c_str(), - "Status(-8): '-1: Dexoptanalyzer path validation failed'"); + "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer path validation failed'"); } TEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) { @@ -593,7 +593,8 @@ TEST_F(DexoptTest, DexoptSecondaryAcessViaDifferentUidError) { binder::Status status; CompileSecondaryDex(secondary_dex_ce_, DEXOPT_STORAGE_CE, /*binder_ok*/ false, /*compile_ok*/ false, &status, kSystemUid); - EXPECT_STREQ(status.toString8().c_str(), "Status(-8): '-1: Dexoptanalyzer open zip failed'"); + EXPECT_STREQ(status.toString8().c_str(), + "Status(-8, EX_SERVICE_SPECIFIC): '-1: Dexoptanalyzer open zip failed'"); } TEST_F(DexoptTest, DexoptPrimaryPublic) { @@ -615,7 +616,7 @@ TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) { DEX2OAT_FROM_SCRATCH, &status); EXPECT_STREQ(status.toString8().c_str(), - "Status(-8): \'256: Dex2oat invocation for " + "Status(-8, EX_SERVICE_SPECIFIC): \'256: Dex2oat invocation for " "/data/app/com.installd.test.dexopt/base.jar failed: unspecified dex2oat error'"); } diff --git a/cmds/servicemanager/binder.h b/cmds/servicemanager/binder.h index 70be3b4687..a9ccc74130 100644 --- a/cmds/servicemanager/binder.h +++ b/cmds/servicemanager/binder.h @@ -4,10 +4,9 @@ #ifndef _BINDER_H_ #define _BINDER_H_ +#include <linux/android/binder.h> #include <sys/ioctl.h> -#include "binder_kernel.h" - struct binder_state; struct binder_io diff --git a/cmds/servicemanager/binder_kernel.h b/cmds/servicemanager/binder_kernel.h deleted file mode 100644 index 19fd773887..0000000000 --- a/cmds/servicemanager/binder_kernel.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 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_BINDER_KERNEL_H -#define ANDROID_BINDER_KERNEL_H - -#include <linux/android/binder.h> - -/** - * This file exists because the uapi kernel headers in bionic are built - * from upstream kernel headers only, and not all of the hwbinder kernel changes - * have made it upstream yet. Therefore, the modifications to the - * binder header are added locally in this file. - */ - -enum { - FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000, -}; - -#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object) - -struct binder_transaction_data_secctx { - struct binder_transaction_data transaction_data; - binder_uintptr_t secctx; -}; - -enum { - BR_TRANSACTION_SEC_CTX = _IOR('r', 2, - struct binder_transaction_data_secctx), -}; - - -#endif // ANDROID_BINDER_KERNEL_H diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h index cd12fcd255..4365a3c4e3 100644 --- a/include/input/IInputFlinger.h +++ b/include/input/IInputFlinger.h @@ -22,7 +22,6 @@ #include <binder/IInterface.h> -#include <utils/Vector.h> #include <input/InputWindow.h> #include <input/ISetInputWindowsListener.h> @@ -36,7 +35,7 @@ class IInputFlinger : public IInterface { public: DECLARE_META_INTERFACE(InputFlinger) - virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles, + virtual void setInputWindows(const std::vector<InputWindowInfo>& inputHandles, const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0; virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0; virtual void registerInputChannel(const sp<InputChannel>& channel) = 0; diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h index 48ac88d50e..b6efc82fd4 100644 --- a/include/input/InputDevice.h +++ b/include/input/InputDevice.h @@ -19,6 +19,7 @@ #include <input/Input.h> #include <input/KeyCharacterMap.h> +#include <vector> namespace android { @@ -121,7 +122,7 @@ public: inline void setButtonUnderPad(bool hasButton) { mHasButtonUnderPad = hasButton; } inline bool hasButtonUnderPad() const { return mHasButtonUnderPad; } - inline const Vector<MotionRange>& getMotionRanges() const { + inline const std::vector<MotionRange>& getMotionRanges() const { return mMotionRanges; } @@ -139,7 +140,7 @@ private: bool mHasVibrator; bool mHasButtonUnderPad; - Vector<MotionRange> mMotionRanges; + std::vector<MotionRange> mMotionRanges; }; /* Types of input device configuration files. */ diff --git a/include/input/KeyLayoutMap.h b/include/input/KeyLayoutMap.h index 73815fe8b4..26f35012e2 100644 --- a/include/input/KeyLayoutMap.h +++ b/include/input/KeyLayoutMap.h @@ -66,7 +66,7 @@ public: status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode, uint32_t* outFlags) const; - status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const; + status_t findScanCodesForKey(int32_t keyCode, std::vector<int32_t>* outScanCodes) const; status_t findScanCodeForLed(int32_t ledCode, int32_t* outScanCode) const; status_t findUsageCodeForLed(int32_t ledCode, int32_t* outUsageCode) const; diff --git a/include/input/VirtualKeyMap.h b/include/input/VirtualKeyMap.h index 4f7cfb6b75..6e8e2c9cf4 100644 --- a/include/input/VirtualKeyMap.h +++ b/include/input/VirtualKeyMap.h @@ -24,6 +24,7 @@ #include <utils/KeyedVector.h> #include <utils/Tokenizer.h> #include <utils/Unicode.h> +#include <vector> namespace android { @@ -51,7 +52,7 @@ public: static std::unique_ptr<VirtualKeyMap> load(const std::string& filename); - inline const Vector<VirtualKeyDefinition>& getVirtualKeys() const { + inline const std::vector<VirtualKeyDefinition>& getVirtualKeys() const { return mVirtualKeys; } @@ -70,7 +71,7 @@ private: bool parseNextIntField(int32_t* outValue); }; - Vector<VirtualKeyDefinition> mVirtualKeys; + std::vector<VirtualKeyDefinition> mVirtualKeys; VirtualKeyMap(); }; diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp index a3f87557ab..8b33a56484 100644 --- a/libs/binder/Status.cpp +++ b/libs/binder/Status.cpp @@ -63,6 +63,26 @@ Status Status::fromStatusT(status_t status) { return ret; } +std::string Status::exceptionToString(int32_t exceptionCode) { + switch (exceptionCode) { + #define EXCEPTION_TO_CASE(EXCEPTION) case EXCEPTION: return #EXCEPTION; + EXCEPTION_TO_CASE(EX_NONE) + EXCEPTION_TO_CASE(EX_SECURITY) + EXCEPTION_TO_CASE(EX_BAD_PARCELABLE) + EXCEPTION_TO_CASE(EX_ILLEGAL_ARGUMENT) + EXCEPTION_TO_CASE(EX_NULL_POINTER) + EXCEPTION_TO_CASE(EX_ILLEGAL_STATE) + EXCEPTION_TO_CASE(EX_NETWORK_MAIN_THREAD) + EXCEPTION_TO_CASE(EX_UNSUPPORTED_OPERATION) + EXCEPTION_TO_CASE(EX_SERVICE_SPECIFIC) + EXCEPTION_TO_CASE(EX_PARCELABLE) + EXCEPTION_TO_CASE(EX_HAS_REPLY_HEADER) + EXCEPTION_TO_CASE(EX_TRANSACTION_FAILED) + #undef EXCEPTION_TO_CASE + default: return std::to_string(exceptionCode); + } +} + Status::Status(int32_t exceptionCode, int32_t errorCode) : mException(exceptionCode), mErrorCode(errorCode) {} @@ -184,7 +204,7 @@ String8 Status::toString8() const { if (mException == EX_NONE) { ret.append("No error"); } else { - ret.appendFormat("Status(%d): '", mException); + ret.appendFormat("Status(%d, %s): '", mException, exceptionToString(mException).c_str()); if (mException == EX_SERVICE_SPECIFIC || mException == EX_TRANSACTION_FAILED) { ret.appendFormat("%d: ", mErrorCode); diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h index 1674516ca2..aa44285b6e 100644 --- a/libs/binder/include/binder/IBinder.h +++ b/libs/binder/include/binder/IBinder.h @@ -143,6 +143,9 @@ public: * dies. The @a cookie is optional. If non-NULL, you can * supply a NULL @a recipient, and the recipient previously * added with that cookie will be unlinked. + * + * If the binder is dead, this will return DEAD_OBJECT. Deleting + * the object will also unlink all death recipients. */ // NOLINTNEXTLINE(google-default-arguments) virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient, diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index afdfe4f6d3..e5219a5590 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -20,6 +20,8 @@ #include <string> #include <vector> +#include <linux/android/binder.h> + #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Errors.h> @@ -28,7 +30,6 @@ #include <utils/Vector.h> #include <utils/Flattenable.h> -#include <binder/binder_kernel.h> #include <binder/IInterface.h> #include <binder/Parcelable.h> #include <binder/Map.h> diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h index c3738f8b29..7d889b6b14 100644 --- a/libs/binder/include/binder/Status.h +++ b/libs/binder/include/binder/Status.h @@ -22,6 +22,7 @@ #include <binder/Parcel.h> #include <utils/String8.h> +#include <string> namespace android { namespace binder { @@ -97,6 +98,8 @@ public: static Status fromStatusT(status_t status); + static std::string exceptionToString(status_t exceptionCode); + Status() = default; ~Status() = default; diff --git a/libs/binder/include/binder/binder_kernel.h b/libs/binder/include/binder/binder_kernel.h deleted file mode 100644 index c7f6b4b4e6..0000000000 --- a/libs/binder/include/binder/binder_kernel.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2016 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_BINDER_KERNEL_H -#define ANDROID_BINDER_KERNEL_H - -#include <linux/android/binder.h> - -/** - * This file exists because the uapi kernel headers in bionic are built - * from upstream kernel headers only, and not all of the hwbinder kernel changes - * have made it upstream yet. Therefore, the modifications to the - * binder header are added locally in this file. - */ - -enum { - FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000, -}; - -#define BINDER_SET_CONTEXT_MGR_EXT _IOW('b', 13, struct flat_binder_object) - -struct binder_transaction_data_secctx { - struct binder_transaction_data transaction_data; - binder_uintptr_t secctx; -}; - -enum { - BR_TRANSACTION_SEC_CTX = _IOR('r', 2, - struct binder_transaction_data_secctx), -}; - -#endif // ANDROID_BINDER_KERNEL_H diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index bdbc0d3b8b..bd6886d1ee 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -269,6 +269,18 @@ void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinde CHECK(who == mWho); mOnDied(mCookie); + + sp<AIBinder_DeathRecipient> recipient = mParentRecipient.promote(); + sp<IBinder> strongWho = who.promote(); + + // otherwise this will be cleaned up later with pruneDeadTransferEntriesLocked + if (recipient != nullptr && strongWho != nullptr) { + status_t result = recipient->unlinkToDeath(strongWho, mCookie); + if (result != ::android::DEAD_OBJECT) { + LOG(WARNING) << "Unlinking to dead binder resulted in: " << result; + } + } + mWho = nullptr; } @@ -277,24 +289,34 @@ AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinde CHECK(onDied != nullptr); } -binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* cookie) { +void AIBinder_DeathRecipient::pruneDeadTransferEntriesLocked() { + mDeathRecipients.erase(std::remove_if(mDeathRecipients.begin(), mDeathRecipients.end(), + [](const sp<TransferDeathRecipient>& tdr) { + return tdr->getWho() == nullptr; + }), + mDeathRecipients.end()); +} + +binder_status_t AIBinder_DeathRecipient::linkToDeath(sp<IBinder> binder, void* cookie) { CHECK(binder != nullptr); std::lock_guard<std::mutex> l(mDeathRecipientsMutex); sp<TransferDeathRecipient> recipient = - new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied); + new TransferDeathRecipient(binder, cookie, this, mOnDied); - status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); + status_t status = binder->linkToDeath(recipient, cookie, 0 /*flags*/); if (status != STATUS_OK) { return PruneStatusT(status); } mDeathRecipients.push_back(recipient); + + pruneDeadTransferEntriesLocked(); return STATUS_OK; } -binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) { +binder_status_t AIBinder_DeathRecipient::unlinkToDeath(sp<IBinder> binder, void* cookie) { CHECK(binder != nullptr); std::lock_guard<std::mutex> l(mDeathRecipientsMutex); @@ -302,10 +324,10 @@ binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* c for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) { sp<TransferDeathRecipient> recipient = *it; - if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) { + if (recipient->getCookie() == cookie && recipient->getWho() == binder) { mDeathRecipients.erase(it.base() - 1); - status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); + status_t status = binder->unlinkToDeath(recipient, cookie, 0 /*flags*/); if (status != ::android::OK) { LOG(ERROR) << __func__ << ": removed reference to death recipient but unlink failed."; @@ -390,7 +412,7 @@ binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* } // returns binder_status_t - return recipient->linkToDeath(binder, cookie); + return recipient->linkToDeath(binder->getBinder(), cookie); } binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, @@ -401,7 +423,7 @@ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient } // returns binder_status_t - return recipient->unlinkToDeath(binder, cookie); + return recipient->unlinkToDeath(binder->getBinder(), cookie); } uid_t AIBinder_getCallingUid() { @@ -555,9 +577,15 @@ AIBinder_DeathRecipient* AIBinder_DeathRecipient_new( LOG(ERROR) << __func__ << ": requires non-null onBinderDied parameter."; return nullptr; } - return new AIBinder_DeathRecipient(onBinderDied); + auto ret = new AIBinder_DeathRecipient(onBinderDied); + ret->incStrong(nullptr); + return ret; } void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) { - delete recipient; + if (recipient == nullptr) { + return; + } + + recipient->decStrong(nullptr); } diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h index 202d6d2e6a..5cb68c291b 100644 --- a/libs/binder/ndk/ibinder_internal.h +++ b/libs/binder/ndk/ibinder_internal.h @@ -128,13 +128,14 @@ struct AIBinder_Class { // // When the AIBinder_DeathRecipient is dropped, so are the actual underlying death recipients. When // the IBinder dies, only a wp to it is kept. -struct AIBinder_DeathRecipient { +struct AIBinder_DeathRecipient : ::android::RefBase { // One of these is created for every linkToDeath. This is to be able to recover data when a // binderDied receipt only gives us information about the IBinder. struct TransferDeathRecipient : ::android::IBinder::DeathRecipient { TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie, + const ::android::wp<AIBinder_DeathRecipient>& parentRecipient, const AIBinder_DeathRecipient_onBinderDied onDied) - : mWho(who), mCookie(cookie), mOnDied(onDied) {} + : mWho(who), mCookie(cookie), mParentRecipient(parentRecipient), mOnDied(onDied) {} void binderDied(const ::android::wp<::android::IBinder>& who) override; @@ -144,14 +145,24 @@ struct AIBinder_DeathRecipient { private: ::android::wp<::android::IBinder> mWho; void* mCookie; + + ::android::wp<AIBinder_DeathRecipient> mParentRecipient; + + // This is kept separately from AIBinder_DeathRecipient in case the death recipient is + // deleted while the death notification is fired const AIBinder_DeathRecipient_onBinderDied mOnDied; }; explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied); - binder_status_t linkToDeath(AIBinder* binder, void* cookie); - binder_status_t unlinkToDeath(AIBinder* binder, void* cookie); + binder_status_t linkToDeath(::android::sp<::android::IBinder>, void* cookie); + binder_status_t unlinkToDeath(::android::sp<::android::IBinder> binder, void* cookie); private: + // When the user of this API deletes a Bp object but not the death recipient, the + // TransferDeathRecipient object can't be cleaned up. This is called whenever a new + // TransferDeathRecipient is linked, and it ensures that mDeathRecipients can't grow unbounded. + void pruneDeadTransferEntriesLocked(); + std::mutex mDeathRecipientsMutex; std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients; AIBinder_DeathRecipient_onBinderDied mOnDied; diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index bddc10de42..80d12541be 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -301,6 +301,11 @@ binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* * may return a binder transaction failure and in case the death recipient cannot be found, it * returns STATUS_NAME_NOT_FOUND. * + * This only ever needs to be called when the AIBinder_DeathRecipient remains for use with other + * AIBinder objects. If the death recipient is deleted, all binders will automatically be unlinked. + * If the binder dies, it will automatically unlink. If the binder is deleted, it will be + * automatically unlinked. + * * \param binder the binder object to remove a previously linked death recipient from. * \param recipient the callback to remove. * \param cookie the cookie used to link to death. diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp index bff601ec26..8467734c75 100644 --- a/libs/binder/ndk/test/main_client.cpp +++ b/libs/binder/ndk/test/main_client.cpp @@ -86,12 +86,15 @@ TEST(NdkBinder, DeathRecipient) { // the binder driver should return this if the service dies during the transaction EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die()); + foo = nullptr; + AIBinder_decStrong(binder); + binder = nullptr; + std::unique_lock<std::mutex> lock(deathMutex); EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; })); EXPECT_TRUE(deathRecieved); AIBinder_DeathRecipient_delete(recipient); - AIBinder_decStrong(binder); } TEST(NdkBinder, RetrieveNonNdkService) { diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 8b663bc8ec..4c2e6532ff 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -31,44 +31,7 @@ cc_library_shared { "-Werror", ], cppflags: [ - "-Weverything", - - // The static constructors and destructors in this library have not been noted to - // introduce significant overheads - "-Wno-exit-time-destructors", - "-Wno-global-constructors", - - // We only care about compiling as C++14 - "-Wno-c++98-compat-pedantic", - - // We don't need to enumerate every case in a switch as long as a default case - // is present - "-Wno-switch-enum", - - // Allow calling variadic macros without a __VA_ARGS__ list - "-Wno-gnu-zero-variadic-macro-arguments", - - // Don't warn about struct padding - "-Wno-padded", - - // We are aware of the risks inherent in comparing floats for equality - "-Wno-float-equal", - - // Pure abstract classes trigger this warning - "-Wno-weak-vtables", - - // Allow four-character integer literals - "-Wno-four-char-constants", - - // Allow documentation warnings - "-Wno-documentation", - - // Allow implicit instantiation for templated class function - "-Wno-undefined-func-template", - - // Allow explicitly marking struct as packed even when unnecessary - "-Wno-packed", - + "-Wextra", "-DDEBUG_ONLY_CODE=0", ], @@ -121,30 +84,38 @@ cc_library_shared { "view/Surface.cpp", "bufferqueue/1.0/B2HProducerListener.cpp", "bufferqueue/1.0/H2BGraphicBufferProducer.cpp", + "bufferqueue/1.0/H2BProducerListener.cpp", + "bufferqueue/2.0/B2HGraphicBufferProducer.cpp", + "bufferqueue/2.0/B2HProducerListener.cpp", + "bufferqueue/2.0/H2BGraphicBufferProducer.cpp", + "bufferqueue/2.0/H2BProducerListener.cpp", + "bufferqueue/2.0/types.cpp", ], shared_libs: [ "android.frameworks.bufferhub@1.0", + "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + "android.hidl.token@1.0-utils", "libbase", - "libsync", "libbinder", - "libhwbinder", "libbufferhub", "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui. - "libpdx_default_transport", "libcutils", "libEGL", "libGLESv2", - "libui", - "libutils", - "libnativewindow", - "liblog", - "libinput", "libhidlbase", "libhidltransport", - "android.hidl.token@1.0-utils", - "android.hardware.graphics.bufferqueue@1.0", + "libhwbinder", + "libinput", + "liblog", + "libnativewindow", + "libpdx_default_transport", + "libsync", + "libui", + "libutils", "libvndksupport", ], @@ -163,16 +134,16 @@ cc_library_shared { "android.frameworks.bufferhub@1.0", "libbufferhub", "libbufferhubqueue", - "libpdx_default_transport", "libinput", + "libpdx_default_transport", ], }, }, header_libs: [ "libdvr_headers", - "libnativebase_headers", "libgui_headers", + "libnativebase_headers", "libpdx_headers", ], @@ -181,9 +152,11 @@ cc_library_shared { "libEGL", "libnativewindow", "libui", - "android.hidl.token@1.0-utils", "android.hardware.graphics.bufferqueue@1.0", + "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common@1.1", + "android.hardware.graphics.common@1.2", + "android.hidl.token@1.0-utils", ], export_header_lib_headers: [ diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 8907de4b5d..9dde15dd0e 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -30,16 +30,21 @@ #ifndef NO_BUFFERHUB #include <gui/BufferHubProducer.h> #endif + +#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> #include <gui/BufferQueueDefs.h> #include <gui/IGraphicBufferProducer.h> #include <gui/IProducerListener.h> -#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> - namespace android { // ---------------------------------------------------------------------------- -using ::android::hardware::graphics::bufferqueue::V1_0::utils:: +using H2BGraphicBufferProducerV1_0 = + ::android::hardware::graphics::bufferqueue::V1_0::utils:: + H2BGraphicBufferProducer; +using H2BGraphicBufferProducerV2_0 = + ::android::hardware::graphics::bufferqueue::V2_0::utils:: H2BGraphicBufferProducer; enum { @@ -534,7 +539,9 @@ public: BpGraphicBufferProducer::~BpGraphicBufferProducer() {} class HpGraphicBufferProducer : public HpInterface< - BpGraphicBufferProducer, H2BGraphicBufferProducer> { + BpGraphicBufferProducer, + H2BGraphicBufferProducerV1_0, + H2BGraphicBufferProducerV2_0> { public: explicit HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {} diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp index 62abfa81c4..936063a5bd 100644 --- a/libs/gui/IProducerListener.cpp +++ b/libs/gui/IProducerListener.cpp @@ -15,7 +15,8 @@ */ #include <binder/Parcel.h> - +#include <gui/bufferqueue/1.0/H2BProducerListener.h> +#include <gui/bufferqueue/2.0/H2BProducerListener.h> #include <gui/IProducerListener.h> namespace android { @@ -61,7 +62,24 @@ public: // translation unit (see clang warning -Wweak-vtables) BpProducerListener::~BpProducerListener() {} -IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener") +class HpProducerListener : public HpInterface< + BpProducerListener, + hardware::graphics::bufferqueue::V1_0::utils::H2BProducerListener, + hardware::graphics::bufferqueue::V2_0::utils::H2BProducerListener> { +public: + explicit HpProducerListener(const sp<IBinder>& base) : PBase{base} {} + + virtual void onBufferReleased() override { + mBase->onBufferReleased(); + } + + virtual bool needsReleaseNotify() override { + return mBase->needsReleaseNotify(); + } +}; + +IMPLEMENT_HYBRID_META_INTERFACE(ProducerListener, + "android.gui.IProducerListener") status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { diff --git a/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp new file mode 100644 index 0000000000..2712f42c89 --- /dev/null +++ b/libs/gui/bufferqueue/1.0/H2BProducerListener.cpp @@ -0,0 +1,59 @@ +/* + * 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_NDEBUG 0 +#define LOG_TAG "H2BProducerListener@1.0" + +#include <android-base/logging.h> + +#include <gui/bufferqueue/1.0/H2BProducerListener.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using ::android::hardware::Return; + +H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base) + : CBase{base} { +} + +void H2BProducerListener::onBufferReleased() { + if (!mBase->onBufferReleased().isOk()) { + LOG(ERROR) << "onBufferReleased: transaction failed."; + } +} + +bool H2BProducerListener::needsReleaseNotify() { + Return<bool> transResult = mBase->needsReleaseNotify(); + if (!transResult.isOk()) { + LOG(ERROR) << "needsReleaseNotify: transaction failed."; + return false; + } + return static_cast<bool>(transResult); +} + +} // namespace utils +} // namespace V1_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp new file mode 100644 index 0000000000..e0395939e9 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/B2HGraphicBufferProducer.cpp @@ -0,0 +1,331 @@ +/* + * 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_NDEBUG 0 +#define LOG_TAG "H2BGraphicBufferProducer@2.0" + +#include <android-base/logging.h> + +#include <android/hardware/graphics/bufferqueue/2.0/types.h> +#include <android/hardware/graphics/common/1.2/types.h> +#include <gui/bufferqueue/2.0/H2BProducerListener.h> +#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <vndk/hardware_buffer.h> + +namespace android { + +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// B2HGraphicBufferProducer +// ======================== + +B2HGraphicBufferProducer::B2HGraphicBufferProducer( + sp<BGraphicBufferProducer> const& base) + : mBase{base} { +} + +Return<HStatus> B2HGraphicBufferProducer::setMaxDequeuedBufferCount( + int32_t maxDequeuedBuffers) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setMaxDequeuedBufferCount( + static_cast<int>(maxDequeuedBuffers)), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::requestBuffer( + int32_t slot, + requestBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + HStatus hStatus{}; + HardwareBuffer hBuffer{}; + uint32_t hGenerationNumber{}; + bool converted = + b2h(mBase->requestBuffer( + static_cast<int>(slot), &bBuffer), + &hStatus) && + b2h(bBuffer, &hBuffer, &hGenerationNumber); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + hBuffer, hGenerationNumber); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::setAsyncMode(bool async) { + HStatus hStatus{}; + bool converted = b2h(mBase->setAsyncMode(async), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::dequeueBuffer( + DequeueBufferInput const& input, + dequeueBuffer_cb _hidl_cb) { + int bSlot{}; + sp<BFence> bFence; + HStatus hStatus{}; + DequeueBufferOutput hOutput{}; + HFenceWrapper hFenceWrapper; + bool converted = + b2h(mBase->dequeueBuffer( + &bSlot, + &bFence, + input.width, + input.height, + static_cast<PixelFormat>(input.format), + input.usage, + &hOutput.bufferAge, + nullptr /* outTimestamps */), + &hStatus, + &hOutput.bufferNeedsReallocation, + &hOutput.releaseAllBuffers) && + b2h(bFence, &hFenceWrapper); + hOutput.fence = hFenceWrapper.getHandle(); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(bSlot), + hOutput); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::detachBuffer(int32_t slot) { + HStatus hStatus{}; + bool converted = b2h( + mBase->detachBuffer(static_cast<int>(slot)), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::detachNextBuffer( + detachNextBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + sp<BFence> bFence; + HStatus hStatus{}; + HardwareBuffer hBuffer{}; + HFenceWrapper hFenceWrapper; + bool converted = + b2h(mBase->detachNextBuffer(&bBuffer, &bFence), &hStatus) && + b2h(bBuffer, &hBuffer) && + b2h(bFence, &hFenceWrapper); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + hBuffer, + hFenceWrapper.getHandle()); + return {}; +} + +Return<void> B2HGraphicBufferProducer::attachBuffer( + HardwareBuffer const& hBuffer, + uint32_t generationNumber, + attachBuffer_cb _hidl_cb) { + sp<GraphicBuffer> bBuffer; + if (!h2b(hBuffer, &bBuffer) || !bBuffer) { + _hidl_cb(HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(SlotIndex::INVALID), + false); + return {}; + } + bBuffer->setGenerationNumber(generationNumber); + + int bSlot{}; + HStatus hStatus{}; + bool releaseAllBuffers{}; + bool converted = b2h( + mBase->attachBuffer(&bSlot, bBuffer), &hStatus, + nullptr /* bufferNeedsReallocation */, + &releaseAllBuffers); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + static_cast<int32_t>(bSlot), + releaseAllBuffers); + return {}; +} + +Return<void> B2HGraphicBufferProducer::queueBuffer( + int32_t slot, + QueueBufferInput const& hInput, + queueBuffer_cb _hidl_cb) { + using HOutput = QueueBufferOutput; + using BInput = BGraphicBufferProducer::QueueBufferInput; + using BOutput = BGraphicBufferProducer::QueueBufferOutput; + + BInput bInput{ + hInput.timestamp, + hInput.isAutoTimestamp, + static_cast<android_dataspace>(hInput.dataSpace), + {}, /* crop */ + 0 /* scalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE */, + static_cast<uint32_t>(hInput.transform), + {}, /* fence */ + static_cast<uint32_t>(hInput.stickyTransform), + false /* getFrameTimestamps */}; + + // Convert crop. + if (!h2b(hInput.crop, &bInput.crop)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + // Convert surfaceDamage. + if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + // Convert fence. + if (!h2b(hInput.fence, &bInput.fence)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + + BOutput bOutput{}; + HStatus hStatus{}; + bool converted = b2h( + mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput), + &hStatus); + + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + HOutput{bOutput.width, + bOutput.height, + static_cast<int32_t>(bOutput.transformHint), + bOutput.numPendingBuffers, + bOutput.nextFrameNumber, + bOutput.bufferReplaced}); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::cancelBuffer( + int32_t slot, + hidl_handle const& fence) { + sp<BFence> bFence; + if (!h2b(fence.getNativeHandle(), &bFence)) { + return {HStatus::UNKNOWN_ERROR}; + } + HStatus hStatus{}; + bool converted = b2h( + mBase->cancelBuffer(static_cast<int>(slot), bFence), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<void> B2HGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) { + int value{}; + int result = mBase->query(static_cast<int>(what), &value); + _hidl_cb(static_cast<int32_t>(result), static_cast<int32_t>(value)); + return {}; +} + +Return<void> B2HGraphicBufferProducer::connect( + sp<HProducerListener> const& hListener, + HConnectionType hConnectionType, + bool producerControlledByApp, + connect_cb _hidl_cb) { + using BOutput = BGraphicBufferProducer::QueueBufferOutput; + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + sp<BProducerListener> bListener = new H2BProducerListener(hListener); + if (!bListener) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + int bConnectionType; + if (!h2b(hConnectionType, &bConnectionType)) { + _hidl_cb(HStatus::UNKNOWN_ERROR, HOutput{}); + return {}; + } + BOutput bOutput{}; + HStatus hStatus{}; + bool converted = b2h( + mBase->connect(bListener, + bConnectionType, + producerControlledByApp, + &bOutput), + &hStatus); + _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, + HOutput{bOutput.width, + bOutput.height, + static_cast<int32_t>(bOutput.transformHint), + bOutput.numPendingBuffers, + bOutput.nextFrameNumber, + bOutput.bufferReplaced}); + return {}; +} + +Return<HStatus> B2HGraphicBufferProducer::disconnect( + HConnectionType hConnectionType) { + int bConnectionType; + if (!h2b(hConnectionType, &bConnectionType)) { + return {HStatus::UNKNOWN_ERROR}; + } + HStatus hStatus{}; + bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::allocateBuffers( + uint32_t width, uint32_t height, + uint32_t format, uint64_t usage) { + mBase->allocateBuffers( + width, height, static_cast<PixelFormat>(format), usage); + return {HStatus::OK}; +} + +Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) { + HStatus hStatus{}; + bool converted = b2h(mBase->allowAllocation(allow), &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber( + uint32_t generationNumber) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setGenerationNumber(generationNumber), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout( + int64_t timeoutNs) { + HStatus hStatus{}; + bool converted = b2h( + mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)), + &hStatus); + return {converted ? hStatus : HStatus::UNKNOWN_ERROR}; +} + +Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() { + uint64_t outId{}; + HStatus hStatus{}; + bool converted = b2h(mBase->getUniqueId(&outId), &hStatus); + return {converted ? outId : 0}; +} + +Return<void> B2HGraphicBufferProducer::getConsumerName( + getConsumerName_cb _hidl_cb) { + _hidl_cb(hidl_string{mBase->getConsumerName().c_str()}); + return {}; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp new file mode 100644 index 0000000000..c4c96eba50 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/B2HProducerListener.cpp @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#include <gui/bufferqueue/2.0/B2HProducerListener.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// B2HProducerListener +B2HProducerListener::B2HProducerListener(sp<BProducerListener> const& base) + : mBase{base}, + mNeedsReleaseNotify{base ? base->needsReleaseNotify() : false} { +} + +Return<void> B2HProducerListener::onBuffersReleased(uint32_t count) { + if (mNeedsReleaseNotify) { + for (; count > 0; --count) { + mBase->onBufferReleased(); + } + } + return {}; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp new file mode 100644 index 0000000000..1023ef108a --- /dev/null +++ b/libs/gui/bufferqueue/2.0/H2BGraphicBufferProducer.cpp @@ -0,0 +1,514 @@ +/* + * 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_NDEBUG 0 +#define LOG_TAG "H2BGraphicBufferProducer@2.0" + +#include <android-base/logging.h> + +#include <android/hardware/graphics/common/1.2/types.h> +#include <gui/bufferqueue/2.0/B2HProducerListener.h> +#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <ui/Region.h> +#include <vndk/hardware_buffer.h> + +namespace android { + +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// H2BGraphicBufferProducer +// ======================== + +status_t H2BGraphicBufferProducer::requestBuffer(int slot, + sp<GraphicBuffer>* bBuffer) { + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->requestBuffer(slot, + [&converted, &bStatus, bBuffer]( + HStatus hStatus, + HardwareBuffer const& hBuffer, + uint32_t generationNumber) { + converted = + h2b(hStatus, &bStatus) && + h2b(hBuffer, bBuffer); + if (*bBuffer) { + (*bBuffer)->setGenerationNumber(generationNumber); + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "requestBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "requestBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount( + int maxDequeuedBuffers) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setMaxDequeuedBufferCount( + static_cast<int32_t>(maxDequeuedBuffers)); + if (!transResult.isOk()) { + LOG(ERROR) << "setMaxDequeuedBufferCount: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setMaxDequeuedBufferCount: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setAsyncMode(bool async) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setAsyncMode(async); + if (!transResult.isOk()) { + LOG(ERROR) << "setAsyncMode: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setAsyncMode: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::dequeueBuffer( + int* slot, sp<BFence>* fence, + uint32_t w, uint32_t h, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, FrameEventHistoryDelta* /* outTimestamps */) { + + using HInput = HGraphicBufferProducer::DequeueBufferInput; + HInput input{w, h, static_cast<uint32_t>(format), usage}; + + using HOutput = HGraphicBufferProducer::DequeueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->dequeueBuffer(input, + [&converted, &bStatus, slot, fence, outBufferAge] ( + HStatus hStatus, int32_t hSlot, HOutput const& hOutput) { + converted = h2b(hStatus, &bStatus); + if (!converted || bStatus != OK) { + return; + } + *slot = hSlot; + *outBufferAge = hOutput.bufferAge; + bStatus = + (hOutput.bufferNeedsReallocation ? + BUFFER_NEEDS_REALLOCATION : 0) | + (hOutput.releaseAllBuffers ? + RELEASE_ALL_BUFFERS : 0); + converted = h2b(hOutput.fence, fence); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "dequeueBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "dequeueBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::detachBuffer(int slot) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->detachBuffer( + static_cast<int32_t>(slot)); + if (!transResult.isOk()) { + LOG(ERROR) << "detachBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "detachBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::detachNextBuffer( + sp<GraphicBuffer>* outBuffer, sp<BFence>* outFence) { + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->detachNextBuffer( + [&converted, &bStatus, outBuffer, outFence] ( + HStatus hStatus, + HardwareBuffer const& hBuffer, + hidl_handle const& hFence) { + converted = h2b(hStatus, &bStatus) && + h2b(hBuffer, outBuffer) && + h2b(hFence, outFence); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "detachNextBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "detachNextBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::attachBuffer( + int* outSlot, sp<GraphicBuffer> const& buffer) { + HardwareBuffer hBuffer{}; + uint32_t hGenerationNumber{}; + if (!b2h(buffer, &hBuffer, &hGenerationNumber)) { + LOG(ERROR) << "attachBuffer: invalid input buffer."; + return BAD_VALUE; + } + + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->attachBuffer(hBuffer, hGenerationNumber, + [&converted, &bStatus, outSlot]( + HStatus hStatus, int32_t hSlot, bool releaseAllBuffers) { + converted = h2b(hStatus, &bStatus); + *outSlot = static_cast<int>(hSlot); + if (converted && releaseAllBuffers && bStatus == OK) { + bStatus = IGraphicBufferProducer::RELEASE_ALL_BUFFERS; + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "attachBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "attachBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::queueBuffer( + int slot, + QueueBufferInput const& input, + QueueBufferOutput* output) { + HRect hCrop{}; + (void)b2h(input.crop, &hCrop); + + using HInput = HGraphicBufferProducer::QueueBufferInput; + HInput hInput{ + input.timestamp, + static_cast<bool>(input.isAutoTimestamp), + static_cast<int32_t>(input.dataSpace), + {}, // crop + static_cast<int32_t>(input.transform), + static_cast<int32_t>(input.stickyTransform), + {}, // fence + {} // surfaceDamage + }; + + // Convert crop. + if (!b2h(input.crop, &hInput.crop)) { + LOG(ERROR) << "queueBuffer: corrupted input crop rectangle."; + return UNKNOWN_ERROR; + } + + // Convert surfaceDamage. + size_t numRects; + Rect const* rectArray = input.surfaceDamage.getArray(&numRects); + hInput.surfaceDamage.resize(numRects); + for (size_t i = 0; i < numRects; ++i) { + if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) { + LOG(ERROR) << "queueBuffer: corrupted input surface damage."; + return UNKNOWN_ERROR; + } + } + + // Convert fence. + HFenceWrapper hFenceWrapper; + if (!b2h(input.fence, &hFenceWrapper)) { + LOG(ERROR) << "queueBuffer: corrupted input fence."; + return UNKNOWN_ERROR; + } + hInput.fence = hFenceWrapper.getHandle(); + + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->queueBuffer( + static_cast<int32_t>(slot), + hInput, + [&converted, &bStatus, output]( + HStatus hStatus, + HOutput const& hOutput) { + converted = h2b(hStatus, &bStatus); + output->width = hOutput.width; + output->height = hOutput.height; + output->transformHint = + static_cast<uint32_t>(hOutput.transformHint); + output->numPendingBuffers = hOutput.numPendingBuffers; + output->nextFrameNumber = hOutput.nextFrameNumber; + output->bufferReplaced = hOutput.bufferReplaced; + }); + + if (!transResult.isOk()) { + LOG(ERROR) << "queueBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "queueBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::cancelBuffer(int slot, sp<BFence> const& fence) { + HFenceWrapper hFenceWrapper; + if (!b2h(fence, &hFenceWrapper)) { + LOG(ERROR) << "cancelBuffer: corrupted input fence."; + return UNKNOWN_ERROR; + } + status_t bStatus{}; + Return<HStatus> transResult = mBase->cancelBuffer( + static_cast<int32_t>(slot), + hFenceWrapper.getHandle()); + if (!transResult.isOk()) { + LOG(ERROR) << "cancelBuffer: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "cancelBuffer: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +int H2BGraphicBufferProducer::query(int what, int* value) { + int result{}; + Return<void> transResult = mBase->query( + static_cast<int32_t>(what), + [&result, value](int32_t r, int32_t v) { + result = static_cast<int>(r); + *value = static_cast<int>(v); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "query: transaction failed."; + return FAILED_TRANSACTION; + } + return result; +} + +status_t H2BGraphicBufferProducer::connect( + sp<IProducerListener> const& listener, int api, + bool producerControlledByApp, QueueBufferOutput* output) { + HConnectionType hConnectionType; + if (!b2h(api, &hConnectionType)) { + LOG(ERROR) << "connect: corrupted input connection type."; + return UNKNOWN_ERROR; + } + sp<HProducerListener> hListener = nullptr; + if (listener && listener->needsReleaseNotify()) { + hListener = new B2HProducerListener(listener); + if (!hListener) { + LOG(ERROR) << "connect: failed to wrap listener."; + return UNKNOWN_ERROR; + } + } + + using HOutput = HGraphicBufferProducer::QueueBufferOutput; + bool converted{}; + status_t bStatus{}; + Return<void> transResult = mBase->connect( + hListener, + hConnectionType, + producerControlledByApp, + [&converted, &bStatus, output]( + HStatus hStatus, + HOutput hOutput) { + converted = h2b(hStatus, &bStatus); + output->width = hOutput.width; + output->height = hOutput.height; + output->transformHint = + static_cast<uint32_t>(hOutput.transformHint); + output->numPendingBuffers = hOutput.numPendingBuffers; + output->nextFrameNumber = hOutput.nextFrameNumber; + output->bufferReplaced = hOutput.bufferReplaced; + }); + if (!transResult.isOk()) { + LOG(ERROR) << "connect: transaction failed."; + return FAILED_TRANSACTION; + } + if (!converted) { + LOG(ERROR) << "connect: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; + +} + +status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) { + HConnectionType hConnectionType; + if (mode == DisconnectMode::AllLocal) { + hConnectionType = HConnectionType::CURRENTLY_CONNECTED; + } else if (!b2h(api, &hConnectionType)) { + LOG(ERROR) << "connect: corrupted input connection type."; + return UNKNOWN_ERROR; + } + + status_t bStatus{}; + Return<HStatus> transResult = mBase->disconnect(hConnectionType); + if (!transResult.isOk()) { + LOG(ERROR) << "disconnect: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "disconnect: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setSidebandStream( + sp<NativeHandle> const& stream) { + if (stream) { + LOG(INFO) << "setSidebandStream: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +void H2BGraphicBufferProducer::allocateBuffers( + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->allocateBuffers( + width, height, static_cast<uint32_t>(format), usage); + if (!transResult.isOk()) { + LOG(ERROR) << "allocateBuffer: transaction failed."; + return; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "allocateBuffer: corrupted transaction."; + return; + } +} + +status_t H2BGraphicBufferProducer::allowAllocation(bool allow) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->allowAllocation(allow); + if (!transResult.isOk()) { + LOG(ERROR) << "allowAllocation: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "allowAllocation: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::setGenerationNumber( + uint32_t generationNumber) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setGenerationNumber(generationNumber); + if (!transResult.isOk()) { + LOG(ERROR) << "setGenerationNumber: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setGenerationNumber: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +String8 H2BGraphicBufferProducer::getConsumerName() const { + String8 bName; + Return<void> transResult = mBase->getConsumerName( + [&bName](hidl_string const& name) { + bName = name.c_str(); + }); + return bName; +} + +status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) { + if (sharedBufferMode) { + LOG(INFO) << "setSharedBufferMode: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) { + if (autoRefresh) { + LOG(INFO) << "setAutoRefresh: not supported."; + return INVALID_OPERATION; + } + return OK; +} + +status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) { + status_t bStatus{}; + Return<HStatus> transResult = mBase->setDequeueTimeout( + static_cast<int64_t>(timeout)); + if (!transResult.isOk()) { + LOG(ERROR) << "setDequeueTimeout: transaction failed."; + return FAILED_TRANSACTION; + } + if (!h2b(static_cast<HStatus>(transResult), &bStatus)) { + LOG(ERROR) << "setDequeueTimeout: corrupted transaction."; + return FAILED_TRANSACTION; + } + return bStatus; +} + +status_t H2BGraphicBufferProducer::getLastQueuedBuffer( + sp<GraphicBuffer>*, + sp<BFence>*, + float[16]) { + LOG(INFO) << "getLastQueuedBuffer: not supported."; + return INVALID_OPERATION; +} + +void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) { + LOG(INFO) << "getFrameTimestamps: not supported."; +} + +status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const { + Return<uint64_t> transResult = mBase->getUniqueId(); + if (!transResult.isOk()) { + LOG(ERROR) << "getUniqueId: transaction failed."; + return FAILED_TRANSACTION; + } + *outId = static_cast<uint64_t>(transResult); + return OK; +} + +status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t*) const { + LOG(INFO) << "getConsumerUsage: not supported."; + return INVALID_OPERATION; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android diff --git a/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp new file mode 100644 index 0000000000..b81a357d63 --- /dev/null +++ b/libs/gui/bufferqueue/2.0/H2BProducerListener.cpp @@ -0,0 +1,57 @@ +/* + * 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_NDEBUG 0 +#define LOG_TAG "H2BProducerListener@2.0" + +#include <android-base/logging.h> + +#include <gui/bufferqueue/2.0/H2BProducerListener.h> +#include <hidl/Status.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::hardware::Return; + +H2BProducerListener::H2BProducerListener(sp<HProducerListener> const& base) + : CBase{base} { +} + +void H2BProducerListener::onBufferReleased() { + if (mBase) { + Return<void> transResult = mBase->onBuffersReleased(1); + if (!transResult.isOk()) { + LOG(ERROR) << "onBuffersReleased: transaction failed."; + } + } +} + +bool H2BProducerListener::needsReleaseNotify() { + return static_cast<bool>(mBase); +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/bufferqueue/2.0/types.cpp b/libs/gui/bufferqueue/2.0/types.cpp new file mode 100644 index 0000000000..a11051739f --- /dev/null +++ b/libs/gui/bufferqueue/2.0/types.cpp @@ -0,0 +1,301 @@ +/* + * 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. + */ + +#include <cutils/native_handle.h> +#include <gui/BufferQueueCore.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <system/window.h> +#include <vndk/hardware_buffer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// Status +// ====== + +bool b2h(status_t from, HStatus* to, + bool* bufferNeedsReallocation, bool* releaseAllBuffers) { + switch (from) { + case OK: + *to = HStatus::OK; break; + case NO_MEMORY: + *to = HStatus::NO_MEMORY; break; + case NO_INIT: + *to = HStatus::NO_INIT; break; + case BAD_VALUE: + *to = HStatus::BAD_VALUE; break; + case DEAD_OBJECT: + *to = HStatus::DEAD_OBJECT; break; + case INVALID_OPERATION: + *to = HStatus::INVALID_OPERATION; break; + case TIMED_OUT: + *to = HStatus::TIMED_OUT; break; + case WOULD_BLOCK: + *to = HStatus::WOULD_BLOCK; break; + case UNKNOWN_ERROR: + *to = HStatus::UNKNOWN_ERROR; break; + default: + using BGBP = ::android::IGraphicBufferProducer; + status_t mask = + (bufferNeedsReallocation ? BGBP::BUFFER_NEEDS_REALLOCATION : 0) + | (releaseAllBuffers ? BGBP::RELEASE_ALL_BUFFERS : 0); + if (from & ~mask) { + *to = static_cast<HStatus>(from); + } else { + *to = HStatus::OK; + if (bufferNeedsReallocation) { + *bufferNeedsReallocation = from & BGBP::BUFFER_NEEDS_REALLOCATION; + } + if (releaseAllBuffers) { + *releaseAllBuffers = from & BGBP::RELEASE_ALL_BUFFERS; + } + } + } + return true; +} + +bool h2b(HStatus from, status_t* to) { + switch (from) { + case HStatus::OK: + *to = OK; break; + case HStatus::NO_MEMORY: + *to = NO_MEMORY; break; + case HStatus::NO_INIT: + *to = NO_INIT; break; + case HStatus::BAD_VALUE: + *to = BAD_VALUE; break; + case HStatus::DEAD_OBJECT: + *to = DEAD_OBJECT; break; + case HStatus::INVALID_OPERATION: + *to = INVALID_OPERATION; break; + case HStatus::TIMED_OUT: + *to = TIMED_OUT; break; + case HStatus::WOULD_BLOCK: + *to = WOULD_BLOCK; break; + case HStatus::UNKNOWN_ERROR: + *to = UNKNOWN_ERROR; break; + default: + *to = static_cast<status_t>(from); + } + return true; +} + +// Fence +// ===== + +HFenceWrapper::HFenceWrapper(native_handle_t* h) : mHandle{h} { +} + +HFenceWrapper::~HFenceWrapper() { + native_handle_delete(mHandle); +} + +HFenceWrapper& HFenceWrapper::set(native_handle_t* h) { + native_handle_delete(mHandle); + mHandle = h; + return *this; +} + +HFenceWrapper& HFenceWrapper::operator=(native_handle_t* h) { + return set(h); +} + +hidl_handle HFenceWrapper::getHandle() const { + return hidl_handle{mHandle}; +} + +HFenceWrapper::operator hidl_handle() const { + return getHandle(); +} + +bool b2h(sp<BFence> const& from, HFenceWrapper* to) { + if (!from) { + to->set(nullptr); + return true; + } + int fenceFd = from->get(); + if (fenceFd == -1) { + to->set(nullptr); + return true; + } + native_handle_t* nh = native_handle_create(1, 0); + if (!nh) { + return false; + } + nh->data[0] = fenceFd; + to->set(nh); + return true; +} + +bool h2b(native_handle_t const* from, sp<BFence>* to) { + if (!from || from->numFds == 0) { + *to = new ::android::Fence(); + return true; + } + if (from->numFds != 1 || from->numInts != 0) { + return false; + } + *to = new BFence(dup(from->data[0])); + return true; +} + +// ConnectionType +// ============== + +bool b2h(int from, HConnectionType* to) { + *to = static_cast<HConnectionType>(from); + switch (from) { + case BufferQueueCore::CURRENTLY_CONNECTED_API: + *to = HConnectionType::CURRENTLY_CONNECTED; break; + case NATIVE_WINDOW_API_EGL: + *to = HConnectionType::EGL; break; + case NATIVE_WINDOW_API_CPU: + *to = HConnectionType::CPU; break; + case NATIVE_WINDOW_API_MEDIA: + *to = HConnectionType::MEDIA; break; + case NATIVE_WINDOW_API_CAMERA: + *to = HConnectionType::CAMERA; break; + } + return true; +} + +bool h2b(HConnectionType from, int* to) { + *to = static_cast<int>(from); + switch (from) { + case HConnectionType::CURRENTLY_CONNECTED: + *to = BufferQueueCore::CURRENTLY_CONNECTED_API; break; + case HConnectionType::EGL: + *to = NATIVE_WINDOW_API_EGL; break; + case HConnectionType::CPU: + *to = NATIVE_WINDOW_API_CPU; break; + case HConnectionType::MEDIA: + *to = NATIVE_WINDOW_API_MEDIA; break; + case HConnectionType::CAMERA: + *to = NATIVE_WINDOW_API_CAMERA; break; + } + return true; +} + +// Rect +// ==== + +bool b2h(BRect const& from, HRect* to) { + BRect* dst = reinterpret_cast<BRect*>(to->data()); + dst->left = from.left; + dst->top = from.top; + dst->right = from.right; + dst->bottom = from.bottom; + return true; +} + +bool h2b(HRect const& from, BRect* to) { + BRect const* src = reinterpret_cast<BRect const*>(from.data()); + to->left = src->left; + to->top = src->top; + to->right = src->right; + to->bottom = src->bottom; + return true; +} + +// Region +// ====== + +bool b2h(BRegion const& from, HRegion* to) { + size_t numRects; + BRect const* rectArray = from.getArray(&numRects); + to->resize(numRects); + for (size_t i = 0; i < numRects; ++i) { + if (!b2h(rectArray[i], &(*to)[i])) { + return false; + } + } + return true; +} + +bool h2b(HRegion const& from, BRegion* to) { + if (from.size() > 0) { + BRect bRect; + if (!h2b(from[0], &bRect)) { + return false; + } + to->set(bRect); + for (size_t i = 1; i < from.size(); ++i) { + if (!h2b(from[i], &bRect)) { + return false; + } + to->addRectUnchecked( + static_cast<int>(bRect.left), + static_cast<int>(bRect.top), + static_cast<int>(bRect.right), + static_cast<int>(bRect.bottom)); + } + } else { + to->clear(); + } + return true; +} + +// GraphicBuffer +// ============= + +// The handle is not cloned. Its lifetime is tied to the original GraphicBuffer. +bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to, + uint32_t* toGenerationNumber) { + if (!from) { + return false; + } + AHardwareBuffer* hwBuffer = from->toAHardwareBuffer(); + to->nativeHandle.setTo( + const_cast<native_handle_t*>( + AHardwareBuffer_getNativeHandle(hwBuffer)), + false); + AHardwareBuffer_describe( + hwBuffer, + reinterpret_cast<AHardwareBuffer_Desc*>(to->description.data())); + if (toGenerationNumber) { + *toGenerationNumber = from->getGenerationNumber(); + } + return true; +} + +// The handle is cloned. +bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to) { + AHardwareBuffer_Desc const* desc = + reinterpret_cast<AHardwareBuffer_Desc const*>( + from.description.data()); + native_handle_t const* handle = from.nativeHandle; + AHardwareBuffer* hwBuffer; + if (AHardwareBuffer_createFromHandle( + desc, handle, AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, + &hwBuffer) != OK) { + return false; + } + *to = GraphicBuffer::fromAHardwareBuffer(hwBuffer); + return true; +} + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index 8ff8d81cf6..2f538adebc 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -35,6 +35,7 @@ #include <hidl/HybridInterface.h> #include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h> +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> namespace android { // ---------------------------------------------------------------------------- @@ -42,8 +43,6 @@ namespace android { class IProducerListener; class NativeHandle; class Surface; -typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer - HGraphicBufferProducer; /* * This class defines the Binder IPC interface for the producer side of @@ -62,7 +61,16 @@ typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer class IGraphicBufferProducer : public IInterface { public: - DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer) + using HGraphicBufferProducerV1_0 = + ::android::hardware::graphics::bufferqueue::V1_0:: + IGraphicBufferProducer; + using HGraphicBufferProducerV2_0 = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; + + DECLARE_HYBRID_META_INTERFACE(GraphicBufferProducer, + HGraphicBufferProducerV1_0, + HGraphicBufferProducerV2_0) enum { // A flag returned by dequeueBuffer when the client needs to call @@ -366,7 +374,6 @@ public: const HdrMetadata& getHdrMetadata() const { return hdrMetadata; } void setHdrMetadata(const HdrMetadata& metadata) { hdrMetadata = metadata; } - private: int64_t timestamp{0}; int isAutoTimestamp{0}; android_dataspace dataSpace{HAL_DATASPACE_UNKNOWN}; diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h index e808bd3bc3..a13d8e4945 100644 --- a/libs/gui/include/gui/IProducerListener.h +++ b/libs/gui/include/gui/IProducerListener.h @@ -17,8 +17,10 @@ #ifndef ANDROID_GUI_IPRODUCERLISTENER_H #define ANDROID_GUI_IPRODUCERLISTENER_H +#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> #include <binder/IInterface.h> - +#include <hidl/HybridInterface.h> #include <utils/RefBase.h> namespace android { @@ -47,7 +49,14 @@ public: class IProducerListener : public ProducerListener, public IInterface { public: - DECLARE_META_INTERFACE(ProducerListener) + using HProducerListener1 = + ::android::hardware::graphics::bufferqueue::V1_0::IProducerListener; + using HProducerListener2 = + ::android::hardware::graphics::bufferqueue::V2_0::IProducerListener; + DECLARE_HYBRID_META_INTERFACE( + ProducerListener, + HProducerListener1, + HProducerListener2) }; class BnProducerListener : public BnInterface<IProducerListener> diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h new file mode 100644 index 0000000000..211fdd5351 --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/1.0/H2BProducerListener.h @@ -0,0 +1,52 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H + +#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V1_0 { +namespace utils { + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V1_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +class H2BProducerListener + : public H2BConverter<HProducerListener, BnProducerListener> { +public: + H2BProducerListener(sp<HProducerListener> const& base); + virtual void onBufferReleased() override; + virtual bool needsReleaseNotify() override; +}; + +} // namespace utils +} // namespace V1_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V1_0_H2BPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h new file mode 100644 index 0000000000..1c58167752 --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/B2HGraphicBufferProducer.h @@ -0,0 +1,121 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H + +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> +#include <gui/IGraphicBufferProducer.h> +#include <gui/bufferqueue/2.0/types.h> +#include <hidl/HidlSupport.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using HGraphicBufferProducer = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; +using BGraphicBufferProducer = + ::android:: + IGraphicBufferProducer; +using HProducerListener = + ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using ::android::hardware::Return; +using ::android::hardware::hidl_handle; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; + +using ::android::hardware::graphics::common::V1_2::HardwareBuffer; + +class B2HGraphicBufferProducer : public HGraphicBufferProducer { +public: + B2HGraphicBufferProducer(sp<BGraphicBufferProducer> const& base); + + virtual Return<HStatus> setMaxDequeuedBufferCount( + int32_t maxDequeuedBuffers) override; + + virtual Return<void> requestBuffer( + int32_t slot, + requestBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> setAsyncMode(bool async) override; + + virtual Return<void> dequeueBuffer( + DequeueBufferInput const& input, + dequeueBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> detachBuffer(int32_t slot) override; + + virtual Return<void> detachNextBuffer( + detachNextBuffer_cb _hidl_cb) override; + + virtual Return<void> attachBuffer( + HardwareBuffer const& buffer, + uint32_t generationNumber, + attachBuffer_cb _hidl_cb) override; + + virtual Return<void> queueBuffer( + int32_t slot, + QueueBufferInput const& input, + queueBuffer_cb _hidl_cb) override; + + virtual Return<HStatus> cancelBuffer( + int32_t slot, + hidl_handle const& fence) override; + + virtual Return<void> query(int32_t what, query_cb _hidl_cb) override; + + virtual Return<void> connect( + sp<HProducerListener> const& listener, + HConnectionType api, + bool producerControlledByApp, + connect_cb _hidl_cb) override; + + virtual Return<HStatus> disconnect(HConnectionType api) override; + + virtual Return<HStatus> allocateBuffers( + uint32_t width, uint32_t height, + uint32_t format, uint64_t usage) override; + + virtual Return<HStatus> allowAllocation(bool allow) override; + + virtual Return<HStatus> setGenerationNumber(uint32_t generationNumber) override; + + virtual Return<HStatus> setDequeueTimeout(int64_t timeoutNs) override; + + virtual Return<uint64_t> getUniqueId() override; + + virtual Return<void> getConsumerName(getConsumerName_cb _hidl_cb) override; + +protected: + sp<BGraphicBufferProducer> mBase; +}; + + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h new file mode 100644 index 0000000000..b48a4736ad --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/B2HProducerListener.h @@ -0,0 +1,57 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H + +#include <android/hidl/base/1.0/IBase.h> +#include <binder/IBinder.h> +#include <gui/IProducerListener.h> +#include <hidl/Status.h> + +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::hardware::Return; + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +struct B2HProducerListener : public HProducerListener { + explicit B2HProducerListener(sp<BProducerListener> const& base); + Return<void> onBuffersReleased(uint32_t count) override; +protected: + sp<BProducerListener> mBase; + bool mNeedsReleaseNotify; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_B2HPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h new file mode 100644 index 0000000000..7dd16172cf --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/H2BGraphicBufferProducer.h @@ -0,0 +1,107 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H + +#include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> +#include <ui/Fence.h> + +#include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using ::android::BnGraphicBufferProducer; +using ::android::IProducerListener; +using Fence = ::android::Fence; + +using HGraphicBufferProducer = + ::android::hardware::graphics::bufferqueue::V2_0:: + IGraphicBufferProducer; +using HProducerListener = + ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; +using BGraphicBufferProducer = + ::android::IGraphicBufferProducer; + +struct H2BGraphicBufferProducer + : public ::android::H2BConverter<HGraphicBufferProducer, + BnGraphicBufferProducer> { + explicit H2BGraphicBufferProducer( + sp<HGraphicBufferProducer> const& base) : CBase(base) {} + + virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override; + virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override; + virtual status_t setAsyncMode(bool async) override; + virtual status_t dequeueBuffer( + int* slot, sp<Fence>* fence, + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage, + uint64_t* outBufferAge, + FrameEventHistoryDelta* outTimestamps) override; + virtual status_t detachBuffer(int slot) override; + virtual status_t detachNextBuffer( + sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence) override; + virtual status_t attachBuffer( + int* outSlot, + sp<GraphicBuffer> const& buffer) override; + virtual status_t queueBuffer( + int slot, + QueueBufferInput const& input, + QueueBufferOutput* output) override; + virtual status_t cancelBuffer(int slot, sp<Fence> const& fence) override; + virtual int query(int what, int* value) override; + virtual status_t connect( + sp<IProducerListener> const& listener, + int api, + bool producerControlledByApp, + QueueBufferOutput* output) override; + virtual status_t disconnect( + int api, + DisconnectMode mode = DisconnectMode::Api) override; + virtual status_t setSidebandStream(sp<NativeHandle> const& stream) override; + virtual void allocateBuffers( + uint32_t width, uint32_t height, + PixelFormat format, uint64_t usage) override; + virtual status_t allowAllocation(bool allow) override; + virtual status_t setGenerationNumber(uint32_t generationNumber) override; + virtual String8 getConsumerName() const override; + virtual status_t setSharedBufferMode(bool sharedBufferMode) override; + virtual status_t setAutoRefresh(bool autoRefresh) override; + virtual status_t setDequeueTimeout(nsecs_t timeout) override; + virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, + sp<Fence>* outFence, float outTransformMatrix[16]) override; + virtual void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override; + virtual status_t getUniqueId(uint64_t* outId) const override; + virtual status_t getConsumerUsage(uint64_t* outUsage) const override; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BGRAPHICBUFFERPRODUCER_H diff --git a/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h new file mode 100644 index 0000000000..898920bf8a --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/H2BProducerListener.h @@ -0,0 +1,52 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H + +#include <android/hardware/graphics/bufferqueue/2.0/IProducerListener.h> +#include <gui/IProducerListener.h> +#include <hidl/HybridInterface.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +using HProducerListener = ::android::hardware::graphics::bufferqueue::V2_0:: + IProducerListener; + +using BProducerListener = ::android::IProducerListener; + +class H2BProducerListener + : public H2BConverter<HProducerListener, BnProducerListener> { +public: + H2BProducerListener(sp<HProducerListener> const& base); + virtual void onBufferReleased() override; + virtual bool needsReleaseNotify() override; +}; + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_H2BPRODUCERLISTENER_H + diff --git a/libs/gui/include/gui/bufferqueue/2.0/types.h b/libs/gui/include/gui/bufferqueue/2.0/types.h new file mode 100644 index 0000000000..62176ce2ef --- /dev/null +++ b/libs/gui/include/gui/bufferqueue/2.0/types.h @@ -0,0 +1,129 @@ +/* + * 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_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H +#define ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H + +#include <android/hardware/graphics/bufferqueue/2.0/types.h> +#include <android/hardware/graphics/common/1.2/types.h> +#include <hidl/HidlSupport.h> +#include <ui/Fence.h> +#include <ui/GraphicBuffer.h> + +namespace android { +namespace hardware { +namespace graphics { +namespace bufferqueue { +namespace V2_0 { +namespace utils { + +// Status +// ====== + +using HStatus = ::android::hardware::graphics::bufferqueue::V2_0:: + Status; + +// A status_t value may have flags encoded. These flags are decoded into boolean +// values if their corresponding output pointers are not null. +bool b2h(status_t from, HStatus* to, + bool* bufferNeedsReallocation = nullptr, + bool* releaseAllBuffers = nullptr); +// Simple 1-to-1 mapping. If BUFFER_NEEDS_REALLOCATION or RELEASE_ALL_BUFFERS +// needs to be added, it must be done manually afterwards. +bool h2b(HStatus from, status_t* to); + +// Fence +// ===== + +using BFence = ::android::Fence; +// This class manages the lifetime of a copied handle. Its destructor calls +// native_handle_delete() but not native_handle_close(). +struct HFenceWrapper { + HFenceWrapper() = default; + // Sets mHandle to a new value. + HFenceWrapper(native_handle_t* h); + // Deletes mHandle without closing. + ~HFenceWrapper(); + // Deletes mHandle without closing, then sets mHandle to a new value. + HFenceWrapper& set(native_handle_t* h); + HFenceWrapper& operator=(native_handle_t* h); + // Returns a non-owning hidl_handle pointing to mHandle. + hidl_handle getHandle() const; + operator hidl_handle() const; +protected: + native_handle_t* mHandle{nullptr}; +}; + +// Does not clone the fd---only copy the fd. The returned HFenceWrapper should +// not outlive the input Fence object. +bool b2h(sp<BFence> const& from, HFenceWrapper* to); +// Clones the fd and puts it in a new Fence object. +bool h2b(native_handle_t const* from, sp<BFence>* to); + +// ConnectionType +// ============== + +using HConnectionType = ::android::hardware::graphics::bufferqueue::V2_0:: + ConnectionType; + +bool b2h(int from, HConnectionType* to); +bool h2b(HConnectionType from, int* to); + +// Rect +// ==== + +using BRect = ::android::Rect; +using HRect = ::android::hardware::graphics::common::V1_2::Rect; + +bool b2h(BRect const& from, HRect* to); +bool h2b(HRect const& from, BRect* to); + +// Region +// ====== + +using BRegion = ::android::Region; +using HRegion = ::android::hardware::hidl_vec<HRect>; + +bool b2h(BRegion const& from, HRegion* to); +bool h2b(HRegion const& from, BRegion* to); + +// GraphicBuffer +// ============= + +using HardwareBuffer = ::android::hardware::graphics::common::V1_2:: + HardwareBuffer; +using HardwareBufferDescription = ::android::hardware::graphics::common::V1_2:: + HardwareBufferDescription; + +// Does not clone the handle. The returned HardwareBuffer should not outlive the +// input GraphicBuffer. Note that HardwareBuffer does not carry the generation +// number, so this function needs another output argument. +bool b2h(sp<GraphicBuffer> const& from, HardwareBuffer* to, + uint32_t* toGenerationNumber = nullptr); +// Clones the handle and creates a new GraphicBuffer from the cloned handle. +// Note that the generation number of the GraphicBuffer has to be set manually +// afterwards because HardwareBuffer does not have such information. +bool h2b(HardwareBuffer const& from, sp<GraphicBuffer>* to); + +} // namespace utils +} // namespace V2_0 +} // namespace bufferqueue +} // namespace graphics +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_GRAPHICS_BUFFERQUEUE_V2_0_TYPES_H + diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp index 4ce5a10e5c..d6a73bfd27 100644 --- a/libs/input/IInputFlinger.cpp +++ b/libs/input/IInputFlinger.cpp @@ -30,7 +30,7 @@ public: explicit BpInputFlinger(const sp<IBinder>& impl) : BpInterface<IInputFlinger>(impl) { } - virtual void setInputWindows(const Vector<InputWindowInfo>& inputInfo, + virtual void setInputWindows(const std::vector<InputWindowInfo>& inputInfo, const sp<ISetInputWindowsListener>& setInputWindowsListener) { Parcel data, reply; data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); @@ -81,10 +81,9 @@ status_t BnInputFlinger::onTransact( if (count > data.dataSize()) { return BAD_VALUE; } - Vector<InputWindowInfo> handles; - handles.setCapacity(count); + std::vector<InputWindowInfo> handles; for (size_t i = 0; i < count; i++) { - handles.add(InputWindowInfo(data)); + handles.push_back(InputWindowInfo::read(data)); } const sp<ISetInputWindowsListener> setInputWindowsListener = ISetInputWindowsListener::asInterface(data.readStrongBinder()); diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp index dab6eac2f4..4db9e06d8d 100644 --- a/libs/input/InputDevice.cpp +++ b/libs/input/InputDevice.cpp @@ -186,7 +186,7 @@ const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( int32_t axis, uint32_t source) const { size_t numRanges = mMotionRanges.size(); for (size_t i = 0; i < numRanges; i++) { - const MotionRange& range = mMotionRanges.itemAt(i); + const MotionRange& range = mMotionRanges[i]; if (range.axis == axis && range.source == source) { return ⦥ } @@ -201,11 +201,11 @@ void InputDeviceInfo::addSource(uint32_t source) { void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, float flat, float fuzz, float resolution) { MotionRange range = { axis, source, min, max, flat, fuzz, resolution }; - mMotionRanges.add(range); + mMotionRanges.push_back(range); } void InputDeviceInfo::addMotionRange(const MotionRange& range) { - mMotionRanges.add(range); + mMotionRanges.push_back(range); } } // namespace android diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp index 88cb0dbdb4..efca68d171 100644 --- a/libs/input/KeyLayoutMap.cpp +++ b/libs/input/KeyLayoutMap.cpp @@ -120,11 +120,12 @@ const KeyLayoutMap::Key* KeyLayoutMap::getKey(int32_t scanCode, int32_t usageCod return nullptr; } -status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const { +status_t KeyLayoutMap::findScanCodesForKey( + int32_t keyCode, std::vector<int32_t>* outScanCodes) const { const size_t N = mKeysByScanCode.size(); for (size_t i=0; i<N; i++) { if (mKeysByScanCode.valueAt(i).keyCode == keyCode) { - outScanCodes->add(mKeysByScanCode.keyAt(i)); + outScanCodes->push_back(mKeysByScanCode.keyAt(i)); } } return NO_ERROR; diff --git a/libs/input/VirtualKeyMap.cpp b/libs/input/VirtualKeyMap.cpp index 624f152996..865366bcb2 100644 --- a/libs/input/VirtualKeyMap.cpp +++ b/libs/input/VirtualKeyMap.cpp @@ -112,7 +112,7 @@ status_t VirtualKeyMap::Parser::parse() { "width=%d, height=%d", defn.scanCode, defn.centerX, defn.centerY, defn.width, defn.height); #endif - mMap->mVirtualKeys.push(defn); + mMap->mVirtualKeys.push_back(defn); } while (consumeFieldDelimiterAndSkipWhitespace()); if (!mTokenizer->isEol()) { diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp index 994e953e76..bf80481c44 100644 --- a/libs/nativewindow/AHardwareBuffer.cpp +++ b/libs/nativewindow/AHardwareBuffer.cpp @@ -93,8 +93,57 @@ void AHardwareBuffer_describe(const AHardwareBuffer* buffer, outDesc->rfu1 = 0; } +int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage, + int32_t fence, const ARect* rect, void** outVirtualAddress, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) { + if (!buffer) return BAD_VALUE; + + if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK | + AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) { + ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only " + "AHARDWAREBUFFER_USAGE_CPU_* flags are allowed"); + return BAD_VALUE; + } + + usage = AHardwareBuffer_convertToGrallocUsageBits(usage); + GraphicBuffer* gbuffer = AHardwareBuffer_to_GraphicBuffer(buffer); + + //Mapper implementations before 3.0 will not return bytes per pixel or + //bytes per stride information. + if (gbuffer->getBufferMapperVersion() == GraphicBufferMapper::Version::GRALLOC_2) { + ALOGE("Mapper versions before 3.0 cannot retrieve bytes per pixel and bytes per stride info"); + return INVALID_OPERATION; + } + + if (gbuffer->getLayerCount() > 1) { + ALOGE("Buffer with multiple layers passed to AHardwareBuffer_lock; " + "only buffers with one layer are allowed"); + return INVALID_OPERATION; + } + + Rect bounds; + if (!rect) { + bounds.set(Rect(gbuffer->getWidth(), gbuffer->getHeight())); + } else { + bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom)); + } + int result = gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, outBytesPerPixel, outBytesPerStride); + + // if hardware returns -1 for bytes per pixel or bytes per stride, we fail + // and unlock the buffer + if (*outBytesPerPixel == -1 || *outBytesPerStride == -1) { + gbuffer->unlock(); + return INVALID_OPERATION; + } + + return result; +} + int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage, - int32_t fence, const ARect* rect, void** outVirtualAddress) { + int32_t fence, const ARect* rect, void** outVirtualAddress) { + int32_t bytesPerPixel; + int32_t bytesPerStride; + if (!buffer) return BAD_VALUE; if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK | @@ -119,7 +168,7 @@ int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage, } else { bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom)); } - return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence); + return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence, &bytesPerPixel, &bytesPerStride); } int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage, @@ -636,11 +685,11 @@ uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage) { } const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) { - return reinterpret_cast<const GraphicBuffer*>(buffer); + return GraphicBuffer::fromAHardwareBuffer(buffer); } GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(AHardwareBuffer* buffer) { - return reinterpret_cast<GraphicBuffer*>(buffer); + return GraphicBuffer::fromAHardwareBuffer(buffer); } const ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(const AHardwareBuffer* buffer) { @@ -652,7 +701,7 @@ ANativeWindowBuffer* AHardwareBuffer_to_ANativeWindowBuffer(AHardwareBuffer* buf } AHardwareBuffer* AHardwareBuffer_from_GraphicBuffer(GraphicBuffer* buffer) { - return reinterpret_cast<AHardwareBuffer*>(buffer); + return buffer->toAHardwareBuffer(); } } // namespace android diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp index d8478848cb..27ab482676 100644 --- a/libs/nativewindow/Android.bp +++ b/libs/nativewindow/Android.bp @@ -24,7 +24,7 @@ ndk_headers { cc_library_headers { name: "libnativewindow_headers", export_include_dirs: ["include"], - vendor_available: false, + vendor_available: true, } ndk_library { diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h index 02c7c1b934..165b75a218 100644 --- a/libs/nativewindow/include/android/hardware_buffer.h +++ b/libs/nativewindow/include/android/hardware_buffer.h @@ -422,6 +422,18 @@ int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage, int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26); /** + * Lock an AHardwareBuffer for direct CPU access. + * + * This function is the same as the above lock function, but passes back + * additional information about the bytes per pixel and the bytes per stride + * of the locked buffer. If the bytes per pixel or bytes per stride are unknown + * or variable, or if the underlying mapper implementation does not support returning + * additional information, then this call will fail with INVALID_OPERATION + */ +int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage, + int32_t fence, const ARect* rect, void** outVirtualAddress, + int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29); +/** * Lock a potentially multi-planar AHardwareBuffer for direct CPU access. * * This function is similar to AHardwareBuffer_lock, but can lock multi-planar diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index a796e97e29..23a05f3dca 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -7,6 +7,7 @@ LIBNATIVEWINDOW { AHardwareBuffer_getNativeHandle; # vndk AHardwareBuffer_isSupported; # introduced=29 AHardwareBuffer_lock; + AHardwareBuffer_lockAndGetInfo; # introduced=29 AHardwareBuffer_recvHandleFromUnixSocket; AHardwareBuffer_release; AHardwareBuffer_sendHandleToUnixSocket; diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 4ca1781be1..e521b613a0 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -124,7 +124,6 @@ cc_library_shared { exclude_header_libs: [ "libbufferhub_headers", "libdvr_headers", - "libnativewindow_headers", ], exclude_shared_libs: [ "android.frameworks.bufferhub@1.0", @@ -152,6 +151,7 @@ cc_library_shared { export_header_lib_headers: [ "libbase_headers", "libnativebase_headers", + "libnativewindow_headers", "libhardware_headers", "libui_headers", ], diff --git a/libs/ui/ColorSpace.cpp b/libs/ui/ColorSpace.cpp index 5b4bf2353e..7a14af1c9d 100644 --- a/libs/ui/ColorSpace.cpp +++ b/libs/ui/ColorSpace.cpp @@ -351,13 +351,12 @@ const ColorSpace ColorSpace::ACEScg() { }; } -std::unique_ptr<float3> ColorSpace::createLUT(uint32_t size, - const ColorSpace& src, const ColorSpace& dst) { - +std::unique_ptr<float3[]> ColorSpace::createLUT(uint32_t size, const ColorSpace& src, + const ColorSpace& dst) { size = clamp(size, 2u, 256u); float m = 1.0f / float(size - 1); - std::unique_ptr<float3> lut(new float3[size * size * size]); + std::unique_ptr<float3[]> lut(new float3[size * size * size]); float3* data = lut.get(); ColorSpaceConnector connector(src, dst); diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 79958ece9e..f800627ef7 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -49,6 +49,22 @@ sp<GraphicBuffer> GraphicBuffer::from(ANativeWindowBuffer* anwb) { return static_cast<GraphicBuffer *>(anwb); } +GraphicBuffer* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer* buffer) { + return reinterpret_cast<GraphicBuffer*>(buffer); +} + +GraphicBuffer const* GraphicBuffer::fromAHardwareBuffer(AHardwareBuffer const* buffer) { + return reinterpret_cast<GraphicBuffer const*>(buffer); +} + +AHardwareBuffer* GraphicBuffer::toAHardwareBuffer() { + return reinterpret_cast<AHardwareBuffer*>(this); +} + +AHardwareBuffer const* GraphicBuffer::toAHardwareBuffer() const { + return reinterpret_cast<AHardwareBuffer const*>(this); +} + GraphicBuffer::GraphicBuffer() : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0) diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index 06981c39a5..25b7247b1b 100644 --- a/libs/ui/GraphicBufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -53,6 +53,9 @@ GraphicBufferMapper::GraphicBufferMapper() { mMapper = std::make_unique<const Gralloc3Mapper>(); if (!mMapper->isLoaded()) { mMapper = std::make_unique<const Gralloc2Mapper>(); + mMapperVersion = Version::GRALLOC_2; + } else { + mMapperVersion = Version::GRALLOC_3; } if (!mMapper->isLoaded()) { diff --git a/libs/ui/include/ui/ColorSpace.h b/libs/ui/include/ui/ColorSpace.h index 8ccf6d36e5..241ec106c0 100644 --- a/libs/ui/include/ui/ColorSpace.h +++ b/libs/ui/include/ui/ColorSpace.h @@ -250,8 +250,8 @@ public: // axis is thus already flipped // The source color space must define its values in the domain [0..1] // The generated LUT transforms from gamma space to gamma space - static std::unique_ptr<float3> createLUT(uint32_t size, - const ColorSpace& src, const ColorSpace& dst); + static std::unique_ptr<float3[]> createLUT(uint32_t size, const ColorSpace& src, + const ColorSpace& dst); private: static constexpr mat3 computeXYZMatrix( diff --git a/libs/ui/include/ui/Fence.h b/libs/ui/include/ui/Fence.h index ec67fa972c..6efecd3c0e 100644 --- a/libs/ui/include/ui/Fence.h +++ b/libs/ui/include/ui/Fence.h @@ -99,6 +99,12 @@ public: // be returned and errno will indicate the problem. int dup() const; + // Return the underlying file descriptor without giving up ownership. The + // returned file descriptor is only valid for as long as the owning Fence + // object lives. (If the situation is unclear, dup() is always a safer + // option.) + int get() const { return mFenceFd.get(); } + // getSignalTime returns the system monotonic clock time at which the // fence transitioned to the signaled state. If the fence is not signaled // then SIGNAL_TIME_PENDING is returned. If the fence is invalid or if an diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h index 4d4ee68194..1c88777961 100644 --- a/libs/ui/include/ui/GraphicBuffer.h +++ b/libs/ui/include/ui/GraphicBuffer.h @@ -22,7 +22,9 @@ #include <string> +#include <android/hardware_buffer.h> #include <ui/ANativeObjectBase.h> +#include <ui/GraphicBufferMapper.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <utils/Flattenable.h> @@ -78,6 +80,10 @@ public: static sp<GraphicBuffer> from(ANativeWindowBuffer *); + static GraphicBuffer* fromAHardwareBuffer(AHardwareBuffer*); + static GraphicBuffer const* fromAHardwareBuffer(AHardwareBuffer const*); + AHardwareBuffer* toAHardwareBuffer(); + AHardwareBuffer const* toAHardwareBuffer() const; // Create a GraphicBuffer to be unflatten'ed into or be reallocated. GraphicBuffer(); @@ -209,6 +215,10 @@ public: status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); + GraphicBufferMapper::Version getBufferMapperVersion() const { + return mBufferMapper.getMapperVersion(); + } + #ifndef LIBUI_IN_VNDK // Returns whether this GraphicBuffer is backed by BufferHubBuffer. bool isBufferHubBuffer() const; diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h index 77c99ccd07..24614549be 100644 --- a/libs/ui/include/ui/GraphicBufferMapper.h +++ b/libs/ui/include/ui/GraphicBufferMapper.h @@ -41,6 +41,10 @@ class Rect; class GraphicBufferMapper : public Singleton<GraphicBufferMapper> { public: + enum Version { + GRALLOC_2, + GRALLOC_3, + }; static void preloadHal(); static inline GraphicBufferMapper& get() { return getInstance(); } @@ -85,12 +89,16 @@ public: return reinterpret_cast<const GrallocMapper&>(*mMapper); } + Version getMapperVersion() const { return mMapperVersion; } + private: friend class Singleton<GraphicBufferMapper>; GraphicBufferMapper(); std::unique_ptr<const GrallocMapper> mMapper; + + Version mMapperVersion; }; // --------------------------------------------------------------------------- diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp index 4da1473904..0544ec16c5 100644 --- a/services/inputflinger/EventHub.cpp +++ b/services/inputflinger/EventHub.cpp @@ -415,14 +415,14 @@ int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { Device* device = getDeviceLocked(deviceId); if (device && device->hasValidFd() && device->keyMap.haveKeyLayout()) { - Vector<int32_t> scanCodes; + std::vector<int32_t> scanCodes; device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes); if (scanCodes.size() != 0) { uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; memset(keyState, 0, sizeof(keyState)); if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { for (size_t i = 0; i < scanCodes.size(); i++) { - int32_t sc = scanCodes.itemAt(i); + int32_t sc = scanCodes[i]; if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) { return AKEY_STATE_DOWN; } @@ -478,7 +478,7 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, Device* device = getDeviceLocked(deviceId); if (device && device->keyMap.haveKeyLayout()) { - Vector<int32_t> scanCodes; + std::vector<int32_t> scanCodes; for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) { scanCodes.clear(); @@ -609,13 +609,15 @@ void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) { } void EventHub::getVirtualKeyDefinitions(int32_t deviceId, - Vector<VirtualKeyDefinition>& outVirtualKeys) const { + std::vector<VirtualKeyDefinition>& outVirtualKeys) const { outVirtualKeys.clear(); AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); if (device && device->virtualKeyMap) { - outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys()); + const std::vector<VirtualKeyDefinition> virtualKeys = + device->virtualKeyMap->getVirtualKeys(); + outVirtualKeys.insert(outVirtualKeys.end(), virtualKeys.begin(), virtualKeys.end()); } } @@ -1680,11 +1682,11 @@ bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { return false; } - Vector<int32_t> scanCodes; + std::vector<int32_t> scanCodes; device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes); const size_t N = scanCodes.size(); for (size_t i=0; i<N && i<=KEY_MAX; i++) { - int32_t sc = scanCodes.itemAt(i); + int32_t sc = scanCodes[i]; if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) { return true; } diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h index 44f7b3715a..63a20ef3e2 100644 --- a/services/inputflinger/EventHub.h +++ b/services/inputflinger/EventHub.h @@ -228,7 +228,7 @@ public: virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0; virtual void getVirtualKeyDefinitions(int32_t deviceId, - Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0; + std::vector<VirtualKeyDefinition>& outVirtualKeys) const = 0; virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0; virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0; @@ -304,7 +304,7 @@ public: virtual void setLedState(int32_t deviceId, int32_t led, bool on); virtual void getVirtualKeyDefinitions(int32_t deviceId, - Vector<VirtualKeyDefinition>& outVirtualKeys) const; + std::vector<VirtualKeyDefinition>& outVirtualKeys) const; virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const; virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map); diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index bcb1ec5fb8..131762060d 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -524,10 +524,8 @@ void InputDispatcher::addRecentEventLocked(EventEntry* entry) { sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y, bool addOutsideTargets, bool addPortalWindows) { // Traverse windows from front to back to find touched window. - const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i); + const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); + for (const sp<InputWindowHandle>& windowHandle : windowHandles) { const InputWindowInfo* windowInfo = windowHandle->getInfo(); if (windowInfo->displayId == displayId) { int32_t flags = windowInfo->layoutParamsFlags; @@ -859,7 +857,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry, } // Identify targets. - Vector<InputTarget> inputTargets; + std::vector<InputTarget> inputTargets; int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime); if (injectionResult == INPUT_EVENT_INJECTION_PENDING) { @@ -910,7 +908,7 @@ bool InputDispatcher::dispatchMotionLocked( bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER; // Identify targets. - Vector<InputTarget> inputTargets; + std::vector<InputTarget> inputTargets; bool conflictingPointerActions = false; int32_t injectionResult; @@ -946,11 +944,11 @@ bool InputDispatcher::dispatchMotionLocked( ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(entry->displayId); if (stateIndex >= 0) { const TouchState& state = mTouchStatesByDisplay.valueAt(stateIndex); - if (!state.portalWindows.isEmpty()) { + if (!state.portalWindows.empty()) { // The event has gone through these portal windows, so we add monitoring targets of // the corresponding displays as well. for (size_t i = 0; i < state.portalWindows.size(); i++) { - const InputWindowInfo* windowInfo = state.portalWindows.itemAt(i)->getInfo(); + const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo(); addMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId, -windowInfo->frameLeft, -windowInfo->frameTop); } @@ -1004,7 +1002,7 @@ void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionE } void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, - EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) { + EventEntry* eventEntry, const std::vector<InputTarget>& inputTargets) { #if DEBUG_DISPATCH_CYCLE ALOGD("dispatchEventToCurrentInputTargets"); #endif @@ -1013,9 +1011,7 @@ void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, pokeUserActivityLocked(eventEntry); - for (size_t i = 0; i < inputTargets.size(); i++) { - const InputTarget& inputTarget = inputTargets.itemAt(i); - + for (const InputTarget& inputTarget : inputTargets) { ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel); if (connectionIndex >= 0) { sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex); @@ -1181,7 +1177,7 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry* entry) { } int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, - const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { + const EventEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) { int32_t injectionResult; std::string reason; @@ -1244,7 +1240,7 @@ Unresponsive: } int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, - const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime, + const MotionEntry* entry, std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) { enum InjectionPermission { INJECTION_PERMISSION_UNKNOWN, @@ -1460,8 +1456,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // is at least one touched foreground window. { bool haveForegroundWindow = false; - for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { - const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; + for (const TouchedWindow& touchedWindow : mTempTouchState.windows) { if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) { haveForegroundWindow = true; if (! checkInjectionPermission(touchedWindow.windowHandle, @@ -1491,8 +1486,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, sp<InputWindowHandle> foregroundWindowHandle = mTempTouchState.getFirstForegroundWindowHandle(); const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid; - for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { - const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; + for (const TouchedWindow& touchedWindow : mTempTouchState.windows) { if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) { sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle; if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) { @@ -1504,8 +1498,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, } // Ensure all touched foreground windows are ready for new input. - for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { - const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; + for (const TouchedWindow& touchedWindow : mTempTouchState.windows) { if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) { // Check whether the window is ready for more input. std::string reason = checkWindowReadyForMoreInputLocked(currentTime, @@ -1528,10 +1521,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, sp<InputWindowHandle> foregroundWindowHandle = mTempTouchState.getFirstForegroundWindowHandle(); if (foregroundWindowHandle->getInfo()->hasWallpaper) { - const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i); + const std::vector<sp<InputWindowHandle>> windowHandles = + getWindowHandlesLocked(displayId); + for (const sp<InputWindowHandle>& windowHandle : windowHandles) { const InputWindowInfo* info = windowHandle->getInfo(); if (info->displayId == displayId && windowHandle->getInfo()->layoutParamsType @@ -1549,8 +1541,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // Success! Output targets. injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; - for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { - const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i); + for (const TouchedWindow& touchedWindow : mTempTouchState.windows) { addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, touchedWindow.pointerIds, inputTargets); } @@ -1613,11 +1604,11 @@ Failed: uint32_t pointerId = entry->pointerProperties[pointerIndex].id; for (size_t i = 0; i < mTempTouchState.windows.size(); ) { - TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i); + TouchedWindow& touchedWindow = mTempTouchState.windows[i]; if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) { touchedWindow.pointerIds.clearBit(pointerId); if (touchedWindow.pointerIds.isEmpty()) { - mTempTouchState.windows.removeAt(i); + mTempTouchState.windows.erase(mTempTouchState.windows.begin() + i); continue; } } @@ -1664,17 +1655,15 @@ Unresponsive: } void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, - int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) { + int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) { sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken()); if (inputChannel == nullptr) { ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str()); return; } - inputTargets.push(); - const InputWindowInfo* windowInfo = windowHandle->getInfo(); - InputTarget& target = inputTargets.editTop(); + InputTarget target; target.inputChannel = inputChannel; target.flags = targetFlags; target.xOffset = - windowInfo->frameLeft; @@ -1683,26 +1672,26 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH target.windowXScale = windowInfo->windowXScale; target.windowYScale = windowInfo->windowYScale; target.pointerIds = pointerIds; + inputTargets.push_back(target); } -void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets, +void InputDispatcher::addMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId, float xOffset, float yOffset) { - std::unordered_map<int32_t, Vector<sp<InputChannel>>>::const_iterator it = + std::unordered_map<int32_t, std::vector<sp<InputChannel>>>::const_iterator it = mMonitoringChannelsByDisplay.find(displayId); if (it != mMonitoringChannelsByDisplay.end()) { - const Vector<sp<InputChannel>>& monitoringChannels = it->second; + const std::vector<sp<InputChannel>>& monitoringChannels = it->second; const size_t numChannels = monitoringChannels.size(); for (size_t i = 0; i < numChannels; i++) { - inputTargets.push(); - - InputTarget& target = inputTargets.editTop(); + InputTarget target; target.inputChannel = monitoringChannels[i]; target.flags = InputTarget::FLAG_DISPATCH_AS_IS; target.xOffset = xOffset; target.yOffset = yOffset; target.pointerIds.clear(); target.globalScaleFactor = 1.0f; + inputTargets.push_back(target); } } else { // If there is no monitor channel registered or all monitor channel unregistered, @@ -1735,10 +1724,8 @@ bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& wind bool InputDispatcher::isWindowObscuredAtPointLocked( const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const { int32_t displayId = windowHandle->getInfo()->displayId; - const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i); + const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); + for (const sp<InputWindowHandle>& otherHandle : windowHandles) { if (otherHandle == windowHandle) { break; } @@ -1756,11 +1743,9 @@ bool InputDispatcher::isWindowObscuredAtPointLocked( bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const { int32_t displayId = windowHandle->getInfo()->displayId; - const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); + const std::vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId); const InputWindowInfo* windowInfo = windowHandle->getInfo(); - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - sp<InputWindowHandle> otherHandle = windowHandles.itemAt(i); + for (const sp<InputWindowHandle>& otherHandle : windowHandles) { if (otherHandle == windowHandle) { break; } @@ -2333,7 +2318,7 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked ( void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked ( const CancelationOptions& options) { for (auto& it : mMonitoringChannelsByDisplay) { - const Vector<sp<InputChannel>>& monitoringChannels = it.second; + const std::vector<sp<InputChannel>>& monitoringChannels = it.second; const size_t numChannels = monitoringChannels.size(); for (size_t i = 0; i < numChannels; i++) { synthesizeCancelationEventsForInputChannelLocked(monitoringChannels[i], options); @@ -2358,11 +2343,11 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( nsecs_t currentTime = now(); - Vector<EventEntry*> cancelationEvents; + std::vector<EventEntry*> cancelationEvents; connection->inputState.synthesizeCancelationEvents(currentTime, cancelationEvents, options); - if (!cancelationEvents.isEmpty()) { + if (!cancelationEvents.empty()) { #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync " "with reality: %s, mode=%d.", @@ -2370,7 +2355,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( options.reason, options.mode); #endif for (size_t i = 0; i < cancelationEvents.size(); i++) { - EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i); + EventEntry* cancelationEventEntry = cancelationEvents[i]; switch (cancelationEventEntry->type) { case EventEntry::TYPE_KEY: logOutboundKeyDetails("cancel - ", @@ -3011,24 +2996,23 @@ void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) { } } -Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t displayId) const { - std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>>::const_iterator it = +std::vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked( + int32_t displayId) const { + std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>::const_iterator it = mWindowHandlesByDisplay.find(displayId); if(it != mWindowHandlesByDisplay.end()) { return it->second; } // Return an empty one if nothing found. - return Vector<sp<InputWindowHandle>>(); + return std::vector<sp<InputWindowHandle>>(); } sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked( const sp<IBinder>& windowHandleToken) const { for (auto& it : mWindowHandlesByDisplay) { - const Vector<sp<InputWindowHandle>> windowHandles = it.second; - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i); + const std::vector<sp<InputWindowHandle>> windowHandles = it.second; + for (const sp<InputWindowHandle>& windowHandle : windowHandles) { if (windowHandle->getToken() == windowHandleToken) { return windowHandle; } @@ -3039,11 +3023,9 @@ sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked( bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const { for (auto& it : mWindowHandlesByDisplay) { - const Vector<sp<InputWindowHandle>> windowHandles = it.second; - size_t numWindows = windowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - if (windowHandles.itemAt(i)->getToken() - == windowHandle->getToken()) { + const std::vector<sp<InputWindowHandle>> windowHandles = it.second; + for (const sp<InputWindowHandle>& handle : windowHandles) { + if (handle->getToken() == windowHandle->getToken()) { if (windowHandle->getInfo()->displayId != it.first) { ALOGE("Found window %s in display %" PRId32 ", but it should belong to display %" PRId32, @@ -3072,7 +3054,7 @@ sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token * For focused handle, check if need to change and send a cancel event to previous one. * For removed handle, check if need to send a cancel event if already in touch. */ -void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles, +void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) { #if DEBUG_FOCUS ALOGD("setInputWindows displayId=%" PRId32, displayId); @@ -3081,28 +3063,27 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input std::scoped_lock _l(mLock); // Copy old handles for release if they are no longer present. - const Vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId); + const std::vector<sp<InputWindowHandle>> oldWindowHandles = + getWindowHandlesLocked(displayId); sp<InputWindowHandle> newFocusedWindowHandle = nullptr; bool foundHoveredWindow = false; - if (inputWindowHandles.isEmpty()) { + if (inputWindowHandles.empty()) { // Remove all handles on a display if there are no windows left. mWindowHandlesByDisplay.erase(displayId); } else { // Since we compare the pointer of input window handles across window updates, we need // to make sure the handle object for the same window stays unchanged across updates. - const Vector<sp<InputWindowHandle>>& oldHandles = mWindowHandlesByDisplay[displayId]; + const std::vector<sp<InputWindowHandle>>& oldHandles = + mWindowHandlesByDisplay[displayId]; std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens; - for (size_t i = 0; i < oldHandles.size(); i++) { - const sp<InputWindowHandle>& handle = oldHandles.itemAt(i); + for (const sp<InputWindowHandle>& handle : oldHandles) { oldHandlesByTokens[handle->getToken()] = handle; } - const size_t numWindows = inputWindowHandles.size(); - Vector<sp<InputWindowHandle>> newHandles; - for (size_t i = 0; i < numWindows; i++) { - const sp<InputWindowHandle>& handle = inputWindowHandles.itemAt(i); + std::vector<sp<InputWindowHandle>> newHandles; + for (const sp<InputWindowHandle>& handle : inputWindowHandles) { if (!handle->updateInfo() || (getInputChannelLocked(handle->getToken()) == nullptr && handle->getInfo()->portalToDisplayId == ADISPLAY_ID_NONE)) { ALOGE("Window handle %s has no registered input channel", @@ -3127,8 +3108,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input } } - for (size_t i = 0; i < newHandles.size(); i++) { - const sp<InputWindowHandle>& windowHandle = newHandles.itemAt(i); + for (const sp<InputWindowHandle>& windowHandle : newHandles) { // Set newFocusedWindowHandle to the top most focused window instead of the last one if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus && windowHandle->getInfo()->visible) { @@ -3184,7 +3164,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input if (stateIndex >= 0) { TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex); for (size_t i = 0; i < state.windows.size(); ) { - TouchedWindow& touchedWindow = state.windows.editItemAt(i); + TouchedWindow& touchedWindow = state.windows[i]; if (!hasWindowHandleLocked(touchedWindow.windowHandle)) { #if DEBUG_FOCUS ALOGD("Touched window was removed: %s in display %" PRId32, @@ -3198,7 +3178,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input synthesizeCancelationEventsForInputChannelLocked( touchedInputChannel, options); } - state.windows.removeAt(i); + state.windows.erase(state.windows.begin() + i); } else { ++i; } @@ -3209,9 +3189,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& input // This ensures that unused input channels are released promptly. // Otherwise, they might stick around until the window handle is destroyed // which might not happen until the next GC. - size_t numWindows = oldWindowHandles.size(); - for (size_t i = 0; i < numWindows; i++) { - const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i); + for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) { if (!hasWindowHandleLocked(oldWindowHandle)) { #if DEBUG_FOCUS ALOGD("Window went away: %s", oldWindowHandle->getName().c_str()); @@ -3415,7 +3393,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< int32_t oldTargetFlags = touchedWindow.targetFlags; BitSet32 pointerIds = touchedWindow.pointerIds; - state.windows.removeAt(i); + state.windows.erase(state.windows.begin() + i); int32_t newTargetFlags = oldTargetFlags & (InputTarget::FLAG_FOREGROUND @@ -3531,7 +3509,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n", state.displayId, toString(state.down), toString(state.split), state.deviceId, state.source); - if (!state.windows.isEmpty()) { + if (!state.windows.empty()) { dump += INDENT3 "Windows:\n"; for (size_t i = 0; i < state.windows.size(); i++) { const TouchedWindow& touchedWindow = state.windows[i]; @@ -3543,10 +3521,10 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { } else { dump += INDENT3 "Windows: <none>\n"; } - if (!state.portalWindows.isEmpty()) { + if (!state.portalWindows.empty()) { dump += INDENT3 "Portal windows:\n"; for (size_t i = 0; i < state.portalWindows.size(); i++) { - const sp<InputWindowHandle> portalWindowHandle = state.portalWindows.itemAt(i); + const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i]; dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i, portalWindowHandle->getName().c_str()); } @@ -3558,12 +3536,12 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { if (!mWindowHandlesByDisplay.empty()) { for (auto& it : mWindowHandlesByDisplay) { - const Vector<sp<InputWindowHandle>> windowHandles = it.second; + const std::vector<sp<InputWindowHandle>> windowHandles = it.second; dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first); - if (!windowHandles.isEmpty()) { + if (!windowHandles.empty()) { dump += INDENT2 "Windows:\n"; for (size_t i = 0; i < windowHandles.size(); i++) { - const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i); + const sp<InputWindowHandle>& windowHandle = windowHandles[i]; const InputWindowInfo* windowInfo = windowHandle->getInfo(); dump += StringPrintf(INDENT3 "%zu: name='%s', displayId=%d, " @@ -3600,7 +3578,7 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) { if (!mMonitoringChannelsByDisplay.empty()) { for (auto& it : mMonitoringChannelsByDisplay) { - const Vector<sp<InputChannel>>& monitoringChannels = it.second; + const std::vector<sp<InputChannel>>& monitoringChannels = it.second; dump += StringPrintf(INDENT "MonitoringChannels in display %" PRId32 ":\n", it.first); const size_t numChannels = monitoringChannels.size(); for (size_t i = 0; i < numChannels; i++) { @@ -3754,9 +3732,9 @@ status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChan // Store monitor channel by displayId. if (monitor) { - Vector<sp<InputChannel>>& monitoringChannels = + std::vector<sp<InputChannel>>& monitoringChannels = mMonitoringChannelsByDisplay[displayId]; - monitoringChannels.push(inputChannel); + monitoringChannels.push_back(inputChannel); } mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this); @@ -3817,11 +3795,11 @@ status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& i void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) { for (auto it = mMonitoringChannelsByDisplay.begin(); it != mMonitoringChannelsByDisplay.end(); ) { - Vector<sp<InputChannel>>& monitoringChannels = it->second; + std::vector<sp<InputChannel>>& monitoringChannels = it->second; const size_t numChannels = monitoringChannels.size(); for (size_t i = 0; i < numChannels; i++) { if (monitoringChannels[i] == inputChannel) { - monitoringChannels.removeAt(i); + monitoringChannels.erase(monitoringChannels.begin() + i); break; } } @@ -4495,13 +4473,12 @@ InputDispatcher::InputState::~InputState() { } bool InputDispatcher::InputState::isNeutral() const { - return mKeyMementos.isEmpty() && mMotionMementos.isEmpty(); + return mKeyMementos.empty() && mMotionMementos.empty(); } bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const { - for (size_t i = 0; i < mMotionMementos.size(); i++) { - const MotionMemento& memento = mMotionMementos.itemAt(i); + for (const MotionMemento& memento : mMotionMementos) { if (memento.deviceId == deviceId && memento.source == source && memento.displayId == displayId @@ -4527,7 +4504,7 @@ bool InputDispatcher::InputState::trackKey(const KeyEntry* entry, } ssize_t index = findKeyMemento(entry); if (index >= 0) { - mKeyMementos.removeAt(index); + mKeyMementos.erase(mKeyMementos.begin() + index); return true; } /* FIXME: We can't just drop the key up event because that prevents creating @@ -4552,7 +4529,7 @@ bool InputDispatcher::InputState::trackKey(const KeyEntry* entry, case AKEY_EVENT_ACTION_DOWN: { ssize_t index = findKeyMemento(entry); if (index >= 0) { - mKeyMementos.removeAt(index); + mKeyMementos.erase(mKeyMementos.begin() + index); } addKeyMemento(entry, flags); return true; @@ -4571,7 +4548,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, case AMOTION_EVENT_ACTION_CANCEL: { ssize_t index = findMotionMemento(entry, false /*hovering*/); if (index >= 0) { - mMotionMementos.removeAt(index); + mMotionMementos.erase(mMotionMementos.begin() + index); return true; } #if DEBUG_OUTBOUND_EVENT_DETAILS @@ -4585,7 +4562,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, case AMOTION_EVENT_ACTION_DOWN: { ssize_t index = findMotionMemento(entry, false /*hovering*/); if (index >= 0) { - mMotionMementos.removeAt(index); + mMotionMementos.erase(mMotionMementos.begin() + index); } addMotionMemento(entry, flags, false /*hovering*/); return true; @@ -4610,9 +4587,9 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, // anything generating fallback events (e.g. DPad keys for joystick movements). if (index >= 0) { if (entry->pointerCoords[0].isEmpty()) { - mMotionMementos.removeAt(index); + mMotionMementos.erase(mMotionMementos.begin() + index); } else { - MotionMemento& memento = mMotionMementos.editItemAt(index); + MotionMemento& memento = mMotionMementos[index]; memento.setPointers(entry); } } else if (!entry->pointerCoords[0].isEmpty()) { @@ -4623,7 +4600,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, return true; } if (index >= 0) { - MotionMemento& memento = mMotionMementos.editItemAt(index); + MotionMemento& memento = mMotionMementos[index]; memento.setPointers(entry); return true; } @@ -4638,7 +4615,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, case AMOTION_EVENT_ACTION_HOVER_EXIT: { ssize_t index = findMotionMemento(entry, true /*hovering*/); if (index >= 0) { - mMotionMementos.removeAt(index); + mMotionMementos.erase(mMotionMementos.begin() + index); return true; } #if DEBUG_OUTBOUND_EVENT_DETAILS @@ -4653,7 +4630,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, case AMOTION_EVENT_ACTION_HOVER_MOVE: { ssize_t index = findMotionMemento(entry, true /*hovering*/); if (index >= 0) { - mMotionMementos.removeAt(index); + mMotionMementos.erase(mMotionMementos.begin() + index); } addMotionMemento(entry, flags, true /*hovering*/); return true; @@ -4666,7 +4643,7 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const { for (size_t i = 0; i < mKeyMementos.size(); i++) { - const KeyMemento& memento = mKeyMementos.itemAt(i); + const KeyMemento& memento = mKeyMementos[i]; if (memento.deviceId == entry->deviceId && memento.source == entry->source && memento.displayId == entry->displayId @@ -4681,7 +4658,7 @@ ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry, bool hovering) const { for (size_t i = 0; i < mMotionMementos.size(); i++) { - const MotionMemento& memento = mMotionMementos.itemAt(i); + const MotionMemento& memento = mMotionMementos[i]; if (memento.deviceId == entry->deviceId && memento.source == entry->source && memento.displayId == entry->displayId @@ -4693,8 +4670,7 @@ ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry, } void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) { - mKeyMementos.push(); - KeyMemento& memento = mKeyMementos.editTop(); + KeyMemento memento; memento.deviceId = entry->deviceId; memento.source = entry->source; memento.displayId = entry->displayId; @@ -4704,12 +4680,12 @@ void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t f memento.flags = flags; memento.downTime = entry->downTime; memento.policyFlags = entry->policyFlags; + mKeyMementos.push_back(memento); } void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering) { - mMotionMementos.push(); - MotionMemento& memento = mMotionMementos.editTop(); + MotionMemento memento; memento.deviceId = entry->deviceId; memento.source = entry->source; memento.displayId = entry->displayId; @@ -4720,6 +4696,7 @@ void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, memento.setPointers(entry); memento.hovering = hovering; memento.policyFlags = entry->policyFlags; + mMotionMementos.push_back(memento); } void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) { @@ -4731,23 +4708,21 @@ void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* } void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime, - Vector<EventEntry*>& outEvents, const CancelationOptions& options) { - for (size_t i = 0; i < mKeyMementos.size(); i++) { - const KeyMemento& memento = mKeyMementos.itemAt(i); + std::vector<EventEntry*>& outEvents, const CancelationOptions& options) { + for (KeyMemento& memento : mKeyMementos) { if (shouldCancelKey(memento, options)) { - outEvents.push(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, + outEvents.push_back(new KeyEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED, memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime)); } } - for (size_t i = 0; i < mMotionMementos.size(); i++) { - const MotionMemento& memento = mMotionMementos.itemAt(i); + for (const MotionMemento& memento : mMotionMementos) { if (shouldCancelMotion(memento, options)) { const int32_t action = memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL; - outEvents.push(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, + outEvents.push_back(new MotionEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, currentTime, memento.deviceId, memento.source, memento.displayId, memento.policyFlags, action, 0 /*actionButton*/, memento.flags, AMETA_NONE, 0 /*buttonState*/, MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE, @@ -4766,19 +4741,19 @@ void InputDispatcher::InputState::clear() { void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const { for (size_t i = 0; i < mMotionMementos.size(); i++) { - const MotionMemento& memento = mMotionMementos.itemAt(i); + const MotionMemento& memento = mMotionMementos[i]; if (memento.source & AINPUT_SOURCE_CLASS_POINTER) { for (size_t j = 0; j < other.mMotionMementos.size(); ) { - const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j); + const MotionMemento& otherMemento = other.mMotionMementos[j]; if (memento.deviceId == otherMemento.deviceId && memento.source == otherMemento.source && memento.displayId == otherMemento.displayId) { - other.mMotionMementos.removeAt(j); + other.mMotionMementos.erase(other.mMotionMementos.begin() + j); } else { j += 1; } } - other.mMotionMementos.push(memento); + other.mMotionMementos.push_back(memento); } } } @@ -4940,7 +4915,7 @@ void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& } for (size_t i = 0; i < windows.size(); i++) { - TouchedWindow& touchedWindow = windows.editItemAt(i); + TouchedWindow& touchedWindow = windows[i]; if (touchedWindow.windowHandle == windowHandle) { touchedWindow.targetFlags |= targetFlags; if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { @@ -4951,19 +4926,17 @@ void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& } } - windows.push(); - - TouchedWindow& touchedWindow = windows.editTop(); + TouchedWindow touchedWindow; touchedWindow.windowHandle = windowHandle; touchedWindow.targetFlags = targetFlags; touchedWindow.pointerIds = pointerIds; + windows.push_back(touchedWindow); } void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& windowHandle) { size_t numWindows = portalWindows.size(); for (size_t i = 0; i < numWindows; i++) { - sp<InputWindowHandle> portalWindowHandle = portalWindows.itemAt(i); - if (portalWindowHandle == windowHandle) { + if (portalWindows[i] == windowHandle) { return; } } @@ -4972,8 +4945,8 @@ void InputDispatcher::TouchState::addPortalWindow(const sp<InputWindowHandle>& w void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) { for (size_t i = 0; i < windows.size(); i++) { - if (windows.itemAt(i).windowHandle == windowHandle) { - windows.removeAt(i); + if (windows[i].windowHandle == windowHandle) { + windows.erase(windows.begin() + i); return; } } @@ -4981,8 +4954,8 @@ void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& wind void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) { for (size_t i = 0; i < windows.size(); i++) { - if (windows.itemAt(i).windowHandle->getToken() == token) { - windows.removeAt(i); + if (windows[i].windowHandle->getToken() == token) { + windows.erase(windows.begin() + i); return; } } @@ -4990,21 +4963,21 @@ void InputDispatcher::TouchState::removeWindowByToken(const sp<IBinder>& token) void InputDispatcher::TouchState::filterNonAsIsTouchWindows() { for (size_t i = 0 ; i < windows.size(); ) { - TouchedWindow& window = windows.editItemAt(i); + TouchedWindow& window = windows[i]; if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) { window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK; window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS; i += 1; } else { - windows.removeAt(i); + windows.erase(windows.begin() + i); } } } sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const { for (size_t i = 0; i < windows.size(); i++) { - const TouchedWindow& window = windows.itemAt(i); + const TouchedWindow& window = windows[i]; if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { return window.windowHandle; } @@ -5015,8 +4988,7 @@ sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandl bool InputDispatcher::TouchState::isSlippery() const { // Must have exactly one foreground window. bool haveSlipperyForegroundWindow = false; - for (size_t i = 0; i < windows.size(); i++) { - const TouchedWindow& window = windows.itemAt(i); + for (const TouchedWindow& window : windows) { if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { if (haveSlipperyForegroundWindow || !(window.windowHandle->getInfo()->layoutParamsFlags diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h index 24ae32fcf5..4d2c2167ac 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -23,8 +23,6 @@ #include <input/InputTransport.h> #include <input/InputWindow.h> #include <input/ISetInputWindowsListener.h> -#include <utils/KeyedVector.h> -#include <utils/Vector.h> #include <utils/threads.h> #include <utils/Timers.h> #include <utils/RefBase.h> @@ -315,7 +313,7 @@ public: * * This method may be called on any thread (usually by the input manager). */ - virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles, + virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0; @@ -407,7 +405,7 @@ public: int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, uint32_t policyFlags); - virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles, + virtual void setInputWindows(const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr); virtual void setFocusedApplication(int32_t displayId, @@ -762,7 +760,7 @@ private: // Synthesizes cancelation events for the current state and resets the tracked state. void synthesizeCancelationEvents(nsecs_t currentTime, - Vector<EventEntry*>& outEvents, const CancelationOptions& options); + std::vector<EventEntry*>& outEvents, const CancelationOptions& options); // Clears the current state. void clear(); @@ -815,8 +813,8 @@ private: void setPointers(const MotionEntry* entry); }; - Vector<KeyMemento> mKeyMementos; - Vector<MotionMemento> mMotionMementos; + std::vector<KeyMemento> mKeyMementos; + std::vector<MotionMemento> mMotionMementos; KeyedVector<int32_t, int32_t> mFallbackKeys; ssize_t findKeyMemento(const KeyEntry* entry) const; @@ -941,7 +939,7 @@ private: ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel) REQUIRES(mLock); // Input channels that will receive a copy of all input events sent to the provided display. - std::unordered_map<int32_t, Vector<sp<InputChannel>>> mMonitoringChannelsByDisplay + std::unordered_map<int32_t, std::vector<sp<InputChannel>>> mMonitoringChannelsByDisplay GUARDED_BY(mLock); // Event injection and synchronization. @@ -998,10 +996,11 @@ private: bool mDispatchFrozen GUARDED_BY(mLock); bool mInputFilterEnabled GUARDED_BY(mLock); - std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay + std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay GUARDED_BY(mLock); // Get window handles by display, return an empty vector if not found. - Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const REQUIRES(mLock); + std::vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const + REQUIRES(mLock); sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const REQUIRES(mLock); sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const REQUIRES(mLock); @@ -1023,12 +1022,12 @@ private: int32_t deviceId; // id of the device that is currently down, others are rejected uint32_t source; // source of the device that is current down, others are rejected int32_t displayId; // id to the display that currently has a touch, others are rejected - Vector<TouchedWindow> windows; + std::vector<TouchedWindow> windows; // This collects the portal windows that the touch has gone through. Each portal window // targets a display (embedded display for most cases). With this info, we can add the // monitoring channels of the displays touched. - Vector<sp<InputWindowHandle>> portalWindows; + std::vector<sp<InputWindowHandle>> portalWindows; TouchState(); ~TouchState(); @@ -1069,7 +1068,7 @@ private: nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock); void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry, - const Vector<InputTarget>& inputTargets) REQUIRES(mLock); + const std::vector<InputTarget>& inputTargets) REQUIRES(mLock); void logOutboundKeyDetails(const char* prefix, const KeyEntry* entry); void logOutboundMotionDetails(const char* prefix, const MotionEntry* entry); @@ -1105,15 +1104,15 @@ private: int32_t getTargetDisplayId(const EventEntry* entry); int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry, - Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) REQUIRES(mLock); + std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) REQUIRES(mLock); int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry, - Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime, + std::vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) REQUIRES(mLock); void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, - int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) + int32_t targetFlags, BitSet32 pointerIds, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); - void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets, int32_t displayId, + void addMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId, float xOffset = 0, float yOffset = 0) REQUIRES(mLock); void pokeUserActivityLocked(const EventEntry* eventEntry) REQUIRES(mLock); diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp index a403f31493..423b69cff3 100644 --- a/services/inputflinger/InputListener.cpp +++ b/services/inputflinger/InputListener.cpp @@ -229,23 +229,23 @@ QueuedInputListener::~QueuedInputListener() { void QueuedInputListener::notifyConfigurationChanged( const NotifyConfigurationChangedArgs* args) { - mArgsQueue.push(new NotifyConfigurationChangedArgs(*args)); + mArgsQueue.push_back(new NotifyConfigurationChangedArgs(*args)); } void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) { - mArgsQueue.push(new NotifyKeyArgs(*args)); + mArgsQueue.push_back(new NotifyKeyArgs(*args)); } void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) { - mArgsQueue.push(new NotifyMotionArgs(*args)); + mArgsQueue.push_back(new NotifyMotionArgs(*args)); } void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) { - mArgsQueue.push(new NotifySwitchArgs(*args)); + mArgsQueue.push_back(new NotifySwitchArgs(*args)); } void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) { - mArgsQueue.push(new NotifyDeviceResetArgs(*args)); + mArgsQueue.push_back(new NotifyDeviceResetArgs(*args)); } void QueuedInputListener::flush() { diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp index b0157a166f..3996cca646 100644 --- a/services/inputflinger/InputManager.cpp +++ b/services/inputflinger/InputManager.cpp @@ -103,14 +103,14 @@ public: } }; -void InputManager::setInputWindows(const Vector<InputWindowInfo>& infos, +void InputManager::setInputWindows(const std::vector<InputWindowInfo>& infos, const sp<ISetInputWindowsListener>& setInputWindowsListener) { - std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> handlesPerDisplay; + std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> handlesPerDisplay; - Vector<sp<InputWindowHandle>> handles; + std::vector<sp<InputWindowHandle>> handles; for (const auto& info : infos) { - handlesPerDisplay.emplace(info.displayId, Vector<sp<InputWindowHandle>>()); - handlesPerDisplay[info.displayId].add(new BinderWindowHandle(info)); + handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>()); + handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info)); } for (auto const& i : handlesPerDisplay) { mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener); diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h index ff9a0800da..e568df54df 100644 --- a/services/inputflinger/InputManager.h +++ b/services/inputflinger/InputManager.h @@ -94,7 +94,7 @@ public: virtual sp<InputClassifierInterface> getClassifier(); virtual sp<InputDispatcherInterface> getDispatcher(); - virtual void setInputWindows(const Vector<InputWindowInfo>& handles, + virtual void setInputWindows(const std::vector<InputWindowInfo>& handles, const sp<ISetInputWindowsListener>& setInputWindowsListener); virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken); diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index 21ba029854..0cc37a016b 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -287,7 +287,7 @@ void InputReader::loopOnce() { int32_t oldGeneration; int32_t timeoutMillis; bool inputDevicesChanged = false; - Vector<InputDeviceInfo> inputDevices; + std::vector<InputDeviceInfo> inputDevices; { // acquire lock AutoMutex _l(mLock); @@ -590,12 +590,13 @@ void InputReader::notifyExternalStylusPresenceChanged() { refreshConfigurationLocked(InputReaderConfiguration::CHANGE_EXTERNAL_STYLUS_PRESENCE); } -void InputReader::getExternalStylusDevicesLocked(Vector<InputDeviceInfo>& outDevices) { +void InputReader::getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices) { for (size_t i = 0; i < mDevices.size(); i++) { InputDevice* device = mDevices.valueAt(i); if (device->getClasses() & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS && !device->isIgnored()) { - outDevices.push(); - device->getDeviceInfo(&outDevices.editTop()); + InputDeviceInfo info; + device->getDeviceInfo(&info); + outDevices.push_back(info); } } } @@ -643,20 +644,21 @@ int32_t InputReader::bumpGenerationLocked() { return ++mGeneration; } -void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) { +void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) { AutoMutex _l(mLock); getInputDevicesLocked(outInputDevices); } -void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) { +void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) { outInputDevices.clear(); size_t numDevices = mDevices.size(); for (size_t i = 0; i < numDevices; i++) { InputDevice* device = mDevices.valueAt(i); if (!device->isIgnored()) { - outInputDevices.push(); - device->getDeviceInfo(&outInputDevices.editTop()); + InputDeviceInfo info; + device->getDeviceInfo(&info); + outInputDevices.push_back(info); } } } @@ -951,7 +953,7 @@ int32_t InputReader::ContextImpl::bumpGeneration() { return mReader->bumpGenerationLocked(); } -void InputReader::ContextImpl::getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) { +void InputReader::ContextImpl::getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) { // lock is already held by whatever called refreshConfigurationLocked mReader->getExternalStylusDevicesLocked(outDevices); } @@ -1031,11 +1033,11 @@ void InputDevice::dump(std::string& dump) { dump += StringPrintf(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); dump += StringPrintf(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); - const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); - if (!ranges.isEmpty()) { + const std::vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); + if (!ranges.empty()) { dump += INDENT2 "Motion Ranges:\n"; for (size_t i = 0; i < ranges.size(); i++) { - const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); + const InputDeviceInfo::MotionRange& range = ranges[i]; const char* label = getAxisLabel(range.axis); char name[32]; if (label) { @@ -1059,7 +1061,7 @@ void InputDevice::dump(std::string& dump) { } void InputDevice::addMapper(InputMapper* mapper) { - mMappers.add(mapper); + mMappers.push_back(mapper); } void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) { @@ -1110,9 +1112,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config } } - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->configure(when, config, changes); mSources |= mapper->getSources(); } @@ -1120,9 +1120,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config } void InputDevice::reset(nsecs_t when) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->reset(when); } @@ -1137,7 +1135,6 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { // have side-effects that must be interleaved. For example, joystick movement events and // gamepad button presses are handled by different mappers but they should be dispatched // in the order received. - size_t numMappers = mMappers.size(); for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) { #if DEBUG_RAW_EVENTS ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64, @@ -1161,8 +1158,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { mDropUntilNextSync = true; reset(rawEvent->when); } else { - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->process(rawEvent); } } @@ -1171,17 +1167,13 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { } void InputDevice::timeoutExpired(nsecs_t when) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->timeoutExpired(when); } } void InputDevice::updateExternalStylusState(const StylusState& state) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->updateExternalStylusState(state); } } @@ -1189,9 +1181,7 @@ void InputDevice::updateExternalStylusState(const StylusState& state) { void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal, mHasMic); - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->populateDeviceInfo(outDeviceInfo); } } @@ -1210,9 +1200,7 @@ int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) { int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) { int32_t result = AKEY_STATE_UNKNOWN; - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { if (sourcesMatchMask(mapper->getSources(), sourceMask)) { // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that // value. Otherwise, return AKEY_STATE_UP as long as one mapper reports it. @@ -1230,9 +1218,7 @@ int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc ge bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { bool result = false; - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { if (sourcesMatchMask(mapper->getSources(), sourceMask)) { result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); } @@ -1242,50 +1228,39 @@ bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->vibrate(pattern, patternSize, repeat, token); } } void InputDevice::cancelVibrate(int32_t token) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->cancelVibrate(token); } } void InputDevice::cancelTouch(nsecs_t when) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->cancelTouch(when); } } int32_t InputDevice::getMetaState() { int32_t result = 0; - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { result |= mapper->getMetaState(); } return result; } void InputDevice::updateMetaState(int32_t keyCode) { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - mMappers[i]->updateMetaState(keyCode); + for (InputMapper* mapper : mMappers) { + mapper->updateMetaState(keyCode); } } void InputDevice::fadePointer() { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { mapper->fadePointer(); } } @@ -1300,9 +1275,7 @@ void InputDevice::notifyReset(nsecs_t when) { } std::optional<int32_t> InputDevice::getAssociatedDisplay() { - size_t numMappers = mMappers.size(); - for (size_t i = 0; i < numMappers; i++) { - InputMapper* mapper = mMappers[i]; + for (InputMapper* mapper : mMappers) { std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplay(); if (associatedDisplayId) { return associatedDisplayId; @@ -2405,7 +2378,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, ssize_t keyDownIndex = findKeyDown(scanCode); if (keyDownIndex >= 0) { // key repeat, be sure to use same keycode as before in case of rotation - keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode; + keyCode = mKeyDowns[keyDownIndex].keyCode; } else { // key down if ((policyFlags & POLICY_FLAG_VIRTUAL) @@ -2417,10 +2390,10 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, mDevice->cancelTouch(when); } - mKeyDowns.push(); - KeyDown& keyDown = mKeyDowns.editTop(); + KeyDown keyDown; keyDown.keyCode = keyCode; keyDown.scanCode = scanCode; + mKeyDowns.push_back(keyDown); } mDownTime = when; @@ -2429,8 +2402,8 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, ssize_t keyDownIndex = findKeyDown(scanCode); if (keyDownIndex >= 0) { // key up, be sure to use same keycode as before in case of rotation - keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode; - mKeyDowns.removeAt(size_t(keyDownIndex)); + keyCode = mKeyDowns[keyDownIndex].keyCode; + mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex); } else { // key was not actually down ALOGI("Dropping key up from device %s because the key was not down. " @@ -3316,9 +3289,9 @@ void TouchInputMapper::configure(nsecs_t when, } void TouchInputMapper::resolveExternalStylusPresence() { - Vector<InputDeviceInfo> devices; + std::vector<InputDeviceInfo> devices; mContext->getExternalStylusDevices(devices); - mExternalStylusConnected = !devices.isEmpty(); + mExternalStylusConnected = !devices.empty(); if (!mExternalStylusConnected) { resetExternalStylus(); @@ -3967,7 +3940,7 @@ void TouchInputMapper::dumpSurface(std::string& dump) { } void TouchInputMapper::configureVirtualKeys() { - Vector<VirtualKeyDefinition> virtualKeyDefinitions; + std::vector<VirtualKeyDefinition> virtualKeyDefinitions; getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); mVirtualKeys.clear(); @@ -3976,19 +3949,13 @@ void TouchInputMapper::configureVirtualKeys() { return; } - mVirtualKeys.setCapacity(virtualKeyDefinitions.size()); - int32_t touchScreenLeft = mRawPointerAxes.x.minValue; int32_t touchScreenTop = mRawPointerAxes.y.minValue; int32_t touchScreenWidth = mRawPointerAxes.getRawWidth(); int32_t touchScreenHeight = mRawPointerAxes.getRawHeight(); - for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { - const VirtualKeyDefinition& virtualKeyDefinition = - virtualKeyDefinitions[i]; - - mVirtualKeys.add(); - VirtualKey& virtualKey = mVirtualKeys.editTop(); + for (const VirtualKeyDefinition& virtualKeyDefinition : virtualKeyDefinitions) { + VirtualKey virtualKey; virtualKey.scanCode = virtualKeyDefinition.scanCode; int32_t keyCode; @@ -3998,8 +3965,7 @@ void TouchInputMapper::configureVirtualKeys() { &keyCode, &dummyKeyMetaState, &flags)) { ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode); - mVirtualKeys.pop(); // drop the key - continue; + continue; // drop the key } virtualKey.keyCode = keyCode; @@ -4017,15 +3983,16 @@ void TouchInputMapper::configureVirtualKeys() { * touchScreenHeight / mSurfaceHeight + touchScreenTop; virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mSurfaceHeight + touchScreenTop; + mVirtualKeys.push_back(virtualKey); } } void TouchInputMapper::dumpVirtualKeys(std::string& dump) { - if (!mVirtualKeys.isEmpty()) { + if (!mVirtualKeys.empty()) { dump += INDENT3 "Virtual Keys:\n"; for (size_t i = 0; i < mVirtualKeys.size(); i++) { - const VirtualKey& virtualKey = mVirtualKeys.itemAt(i); + const VirtualKey& virtualKey = mVirtualKeys[i]; dump += StringPrintf(INDENT4 "%zu: scanCode=%d, keyCode=%d, " "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", i, virtualKey.scanCode, virtualKey.keyCode, @@ -4364,12 +4331,13 @@ void TouchInputMapper::process(const RawEvent* rawEvent) { } void TouchInputMapper::sync(nsecs_t when) { - const RawState* last = mRawStatesPending.isEmpty() ? - &mCurrentRawState : &mRawStatesPending.top(); + const RawState* last = mRawStatesPending.empty() ? + &mCurrentRawState : &mRawStatesPending.back(); // Push a new state. - mRawStatesPending.push(); - RawState* next = &mRawStatesPending.editTop(); + mRawStatesPending.emplace_back(); + + RawState* next = &mRawStatesPending.back(); next->clear(); next->when = when; @@ -4436,7 +4404,7 @@ void TouchInputMapper::processRawTouches(bool timeout) { cookAndDispatch(mCurrentRawState.when); } if (count != 0) { - mRawStatesPending.removeItemsAt(0, count); + mRawStatesPending.erase(mRawStatesPending.begin(), mRawStatesPending.begin() + count); } if (mExternalStylusDataPending) { @@ -6623,12 +6591,9 @@ bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) { && scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight; } -const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit( - int32_t x, int32_t y) { - size_t numVirtualKeys = mVirtualKeys.size(); - for (size_t i = 0; i < numVirtualKeys; i++) { - const VirtualKey& virtualKey = mVirtualKeys[i]; +const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) { + for (const VirtualKey& virtualKey: mVirtualKeys) { #if DEBUG_VIRTUAL_KEYS ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " "left=%d, top=%d, right=%d, bottom=%d", @@ -6838,9 +6803,7 @@ int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) return AKEY_STATE_VIRTUAL; } - size_t numVirtualKeys = mVirtualKeys.size(); - for (size_t i = 0; i < numVirtualKeys; i++) { - const VirtualKey& virtualKey = mVirtualKeys[i]; + for (const VirtualKey& virtualKey : mVirtualKeys) { if (virtualKey.keyCode == keyCode) { return AKEY_STATE_UP; } @@ -6854,9 +6817,7 @@ int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode return AKEY_STATE_VIRTUAL; } - size_t numVirtualKeys = mVirtualKeys.size(); - for (size_t i = 0; i < numVirtualKeys; i++) { - const VirtualKey& virtualKey = mVirtualKeys[i]; + for (const VirtualKey& virtualKey : mVirtualKeys) { if (virtualKey.scanCode == scanCode) { return AKEY_STATE_UP; } @@ -6867,10 +6828,7 @@ int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { - size_t numVirtualKeys = mVirtualKeys.size(); - for (size_t i = 0; i < numVirtualKeys; i++) { - const VirtualKey& virtualKey = mVirtualKeys[i]; - + for (const VirtualKey& virtualKey : mVirtualKeys) { for (size_t i = 0; i < numCodes; i++) { if (virtualKey.keyCode == keyCodes[i]) { outFlags[i] = 1; diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h index fed55ac0e6..9777779e7d 100644 --- a/services/inputflinger/InputReader.h +++ b/services/inputflinger/InputReader.h @@ -90,7 +90,7 @@ public: virtual void requestTimeoutAtTime(nsecs_t when) = 0; virtual int32_t bumpGeneration() = 0; - virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) = 0; + virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) = 0; virtual void dispatchExternalStylusState(const StylusState& outState) = 0; virtual InputReaderPolicyInterface* getPolicy() = 0; @@ -124,7 +124,7 @@ public: virtual void loopOnce(); - virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices); + virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices); virtual bool isInputDeviceEnabled(int32_t deviceId); @@ -166,7 +166,7 @@ protected: virtual void fadePointer(); virtual void requestTimeoutAtTime(nsecs_t when); virtual int32_t bumpGeneration(); - virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices); + virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices); virtual void dispatchExternalStylusState(const StylusState& outState); virtual InputReaderPolicyInterface* getPolicy(); virtual InputListenerInterface* getListener(); @@ -211,7 +211,7 @@ private: int32_t getGlobalMetaStateLocked(); void notifyExternalStylusPresenceChanged(); - void getExternalStylusDevicesLocked(Vector<InputDeviceInfo>& outDevices); + void getExternalStylusDevicesLocked(std::vector<InputDeviceInfo>& outDevices); void dispatchExternalStylusState(const StylusState& state); void fadePointerLocked(); @@ -219,7 +219,7 @@ private: int32_t mGeneration; int32_t bumpGenerationLocked(); - void getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices); + void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices); nsecs_t mDisableVirtualKeysTimeout; void disableVirtualKeysUntilLocked(nsecs_t time); @@ -266,7 +266,7 @@ public: inline void setMic(bool hasMic) { mHasMic = hasMic; } inline bool hasMic() const { return mHasMic; } - inline bool isIgnored() { return mMappers.isEmpty(); } + inline bool isIgnored() { return mMappers.empty(); } bool isEnabled(); void setEnabled(bool enabled, nsecs_t when); @@ -331,7 +331,7 @@ private: std::string mAlias; uint32_t mClasses; - Vector<InputMapper*> mMappers; + std::vector<InputMapper*> mMappers; uint32_t mSources; bool mIsExternal; @@ -877,7 +877,7 @@ private: uint32_t mSource; int32_t mKeyboardType; - Vector<KeyDown> mKeyDowns; // keys that are down + std::vector<KeyDown> mKeyDowns; // keys that are down int32_t mMetaState; nsecs_t mDownTime; // time of most recent key down @@ -1235,7 +1235,7 @@ protected: } }; - Vector<RawState> mRawStatesPending; + std::vector<RawState> mRawStatesPending; RawState mCurrentRawState; CookedState mCurrentCookedState; RawState mLastRawState; @@ -1262,7 +1262,7 @@ protected: // The pointer controller, or null if the device is not a pointer. sp<PointerControllerInterface> mPointerController; - Vector<VirtualKey> mVirtualKeys; + std::vector<VirtualKey> mVirtualKeys; virtual void configureParameters(); virtual void dumpParameters(std::string& dump); diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h index a00b5fbc13..d8b352cbc6 100644 --- a/services/inputflinger/host/InputFlinger.h +++ b/services/inputflinger/host/InputFlinger.h @@ -40,7 +40,8 @@ public: InputFlinger() ANDROID_API; virtual status_t dump(int fd, const Vector<String16>& args); - void setInputWindows(const Vector<InputWindowInfo>&, const sp<ISetInputWindowsListener>&) {} + void setInputWindows(const std::vector<InputWindowInfo>&, + const sp<ISetInputWindowsListener>&) {} void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {} void registerInputChannel(const sp<InputChannel>&) {} void unregisterInputChannel(const sp<InputChannel>&) {} diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h index cd8caf7530..b51dcb6cad 100644 --- a/services/inputflinger/include/InputListener.h +++ b/services/inputflinger/include/InputListener.h @@ -221,7 +221,7 @@ public: private: sp<InputListenerInterface> mInnerListener; - Vector<NotifyArgs*> mArgsQueue; + std::vector<NotifyArgs*> mArgsQueue; }; } // namespace android diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h index fe1d4d0bf7..8ad5dd0785 100644 --- a/services/inputflinger/include/InputReaderBase.h +++ b/services/inputflinger/include/InputReaderBase.h @@ -74,7 +74,7 @@ public: * * This method may be called on any thread (usually by the input manager). */ - virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0; + virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) = 0; /* Query current input state. */ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask, @@ -333,7 +333,7 @@ public: /* Notifies the input reader policy that some input devices have changed * and provides information about all current input devices. */ - virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0; + virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) = 0; /* Gets the keyboard layout for a particular input device. */ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay( diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 3b6fe52a5a..d63ff8c2d6 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -571,8 +571,8 @@ TEST_F(InputDispatcherTest, SetInputWindow_SingleWindowTouch) { sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.add(window); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(window); mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, @@ -591,9 +591,9 @@ TEST_F(InputDispatcherTest, SetInputWindow_MultiWindowsTouch) { sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second", ADISPLAY_ID_DEFAULT); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.add(windowTop); - inputWindowHandles.add(windowSecond); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(windowTop); + inputWindowHandles.push_back(windowSecond); mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher, @@ -617,9 +617,9 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusedWindow) { // Expect one focus window exist in display. windowSecond->setFocus(); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.add(windowTop); - inputWindowHandles.add(windowSecond); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(windowTop); + inputWindowHandles.push_back(windowSecond); mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) @@ -643,9 +643,9 @@ TEST_F(InputDispatcherTest, SetInputWindow_FocusPriority) { // Display has two focused windows. Add them to inputWindowsHandles in z-order (top most first) windowTop->setFocus(); windowSecond->setFocus(); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.add(windowTop); - inputWindowHandles.add(windowSecond); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(windowTop); + inputWindowHandles.push_back(windowSecond); mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher)) @@ -669,9 +669,9 @@ TEST_F(InputDispatcherTest, SetInputWindow_InputWindowInfo) { windowTop->setFocus(); windowSecond->setFocus(); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.add(windowTop); - inputWindowHandles.add(windowSecond); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(windowTop); + inputWindowHandles.push_back(windowSecond); // Release channel for window is no longer valid. windowTop->releaseChannel(); mDispatcher->setInputWindows(inputWindowHandles, ADISPLAY_ID_DEFAULT); @@ -695,8 +695,8 @@ public: application1 = new FakeApplicationHandle(); windowInPrimary = new FakeWindowHandle(application1, mDispatcher, "D_1", ADISPLAY_ID_DEFAULT); - Vector<sp<InputWindowHandle>> inputWindowHandles; - inputWindowHandles.push(windowInPrimary); + std::vector<sp<InputWindowHandle>> inputWindowHandles; + inputWindowHandles.push_back(windowInPrimary); // Set focus window for primary display, but focused display would be second one. mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1); windowInPrimary->setFocus(); @@ -706,8 +706,8 @@ public: windowInSecondary = new FakeWindowHandle(application2, mDispatcher, "D_2", SECOND_DISPLAY_ID); // Set focus to second display window. - Vector<sp<InputWindowHandle>> inputWindowHandles_Second; - inputWindowHandles_Second.push(windowInSecondary); + std::vector<sp<InputWindowHandle>> inputWindowHandles_Second; + inputWindowHandles_Second.push_back(windowInSecondary); // Set focus display to second one. mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID); // Set focus window for second display. @@ -762,7 +762,7 @@ TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, ADISPLAY_ID_NONE); // Remove secondary display. - Vector<sp<InputWindowHandle>> noWindows; + std::vector<sp<InputWindowHandle>> noWindows; mDispatcher->setInputWindows(noWindows, SECOND_DISPLAY_ID); // Expect old focus should receive a cancel event. diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 80a55f1a65..d35302885d 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -158,7 +158,7 @@ private: class FakeInputReaderPolicy : public InputReaderPolicyInterface { InputReaderConfiguration mConfig; KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers; - Vector<InputDeviceInfo> mInputDevices; + std::vector<InputDeviceInfo> mInputDevices; std::vector<DisplayViewport> mViewports; TouchAffineTransformation transform; @@ -226,7 +226,7 @@ public: return &mConfig; } - const Vector<InputDeviceInfo>& getInputDevices() const { + const std::vector<InputDeviceInfo>& getInputDevices() const { return mInputDevices; } @@ -280,7 +280,7 @@ private: return mPointerControllers.valueFor(deviceId); } - virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) { + virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) { mInputDevices = inputDevices; } @@ -314,7 +314,7 @@ class FakeEventHub : public EventHubInterface { KeyedVector<int32_t, KeyInfo> keysByScanCode; KeyedVector<int32_t, KeyInfo> keysByUsageCode; KeyedVector<int32_t, bool> leds; - Vector<VirtualKeyDefinition> virtualKeys; + std::vector<VirtualKeyDefinition> virtualKeys; bool enabled; status_t enable() { @@ -482,7 +482,7 @@ public: void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) { Device* device = getDevice(deviceId); - device->virtualKeys.push(definition); + device->virtualKeys.push_back(definition); } void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type, @@ -728,12 +728,12 @@ private: } virtual void getVirtualKeyDefinitions(int32_t deviceId, - Vector<VirtualKeyDefinition>& outVirtualKeys) const { + std::vector<VirtualKeyDefinition>& outVirtualKeys) const { outVirtualKeys.clear(); Device* device = getDevice(deviceId); if (device) { - outVirtualKeys.appendVector(device->virtualKeys); + outVirtualKeys = device->virtualKeys; } } @@ -842,7 +842,7 @@ private: return ++mGeneration; } - virtual void getExternalStylusDevices(Vector<InputDeviceInfo>& outDevices) { + virtual void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) { } @@ -865,7 +865,7 @@ class FakeInputMapper : public InputMapper { KeyedVector<int32_t, int32_t> mKeyCodeStates; KeyedVector<int32_t, int32_t> mScanCodeStates; KeyedVector<int32_t, int32_t> mSwitchStates; - Vector<int32_t> mSupportedKeyCodes; + std::vector<int32_t> mSupportedKeyCodes; RawEvent mLastEvent; bool mConfigureWasCalled; @@ -925,7 +925,7 @@ public: } void addSupportedKeyCode(int32_t keyCode) { - mSupportedKeyCodes.add(keyCode); + mSupportedKeyCodes.push_back(keyCode); } private: @@ -1309,7 +1309,7 @@ TEST_F(InputReaderTest, GetInputDevices) { 0, nullptr)); // no classes so device will be ignored - Vector<InputDeviceInfo> inputDevices; + std::vector<InputDeviceInfo> inputDevices; mReader->getInputDevices(inputDevices); ASSERT_EQ(1U, inputDevices.size()); @@ -4436,7 +4436,7 @@ TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType); - // airbrush + // air-brush processKey(mapper, BTN_TOOL_PENCIL, 0); processKey(mapper, BTN_TOOL_AIRBRUSH, 1); processSync(mapper); @@ -5943,7 +5943,7 @@ TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) { ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action); ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType); - // airbrush + // air-brush processKey(mapper, BTN_TOOL_PENCIL, 0); processKey(mapper, BTN_TOOL_AIRBRUSH, 1); processSync(mapper); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 512a0b4f10..07fe03ee4d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1788,9 +1788,13 @@ half4 Layer::getColor() const { } Layer::RoundedCornerState Layer::getRoundedCornerState() const { + return getRoundedCornerStateInternal(mSourceBounds); +} + +Layer::RoundedCornerState Layer::getRoundedCornerStateInternal(const FloatRect bounds) const { const auto& p = mDrawingParent.promote(); if (p != nullptr) { - RoundedCornerState parentState = p->getRoundedCornerState(); + RoundedCornerState parentState = p->getRoundedCornerStateInternal(bounds); if (parentState.radius > 0) { ui::Transform t = getActiveTransform(getDrawingState()); t = t.inverse(); @@ -1804,7 +1808,9 @@ Layer::RoundedCornerState Layer::getRoundedCornerState() const { } } const float radius = getDrawingState().cornerRadius; - return radius > 0 ? RoundedCornerState(getBounds(), radius) : RoundedCornerState(); + return radius > 0 + ? RoundedCornerState(bounds.intersect(getCrop(getDrawingState()).toFloatRect()), radius) + : RoundedCornerState(); } void Layer::commitChildList() { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 89063da251..b7cfc1687a 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -907,6 +907,8 @@ private: */ Rect getCroppedBufferSize(const Layer::State& s) const; + RoundedCornerState getRoundedCornerStateInternal(const FloatRect bounds) const; + // Cached properties computed from drawing state // Effective transform taking into account parent transforms and any parent scaling. ui::Transform mEffectiveTransform; diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp index 5296da9652..6599f9e340 100644 --- a/services/surfaceflinger/Scheduler/DispSync.cpp +++ b/services/surfaceflinger/Scheduler/DispSync.cpp @@ -789,31 +789,6 @@ void DispSync::dump(std::string& result) const { StringAppendF(&result, "current monotonic time: %" PRId64 "\n", now); } -// TODO(b/113612090): Figure out how much of this is still relevant. -// We need to determine the time when a buffer acquired now will be -// displayed. This can be calculated: -// time when previous buffer's actual-present fence was signaled -// + current display refresh rate * HWC latency -// + a little extra padding -// -// Buffer producers are expected to set their desired presentation time -// based on choreographer time stamps, which (coming from vsync events) -// will be slightly later then the actual-present timing. If we get a -// desired-present time that is unintentionally a hair after the next -// vsync, we'll hold the frame when we really want to display it. We -// need to take the offset between actual-present and reported-vsync -// into account. -// -// If the system is configured without a DispSync phase offset for the app, -// we also want to throw in a bit of padding to avoid edge cases where we -// just barely miss. We want to do it here, not in every app. A major -// source of trouble is the app's use of the display's ideal refresh time -// (via Display.getRefreshRate()), which could be off of the actual refresh -// by a few percent, with the error multiplied by the number of frames -// between now and when the buffer should be displayed. -// -// If the refresh reported to the app has a phase offset, we shouldn't need -// to tweak anything here. nsecs_t DispSync::expectedPresentTime() { // The HWC doesn't currently have a way to report additional latency. // Assume that whatever we submit now will appear right after the flip. diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index d5e33490a5..67e6de9ce2 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -135,7 +135,7 @@ class EventThread : public android::EventThread, private VSyncSource::Callback { public: using InterceptVSyncsCallback = std::function<void(nsecs_t)>; - // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete. + // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete. EventThread(VSyncSource*, InterceptVSyncsCallback, const char* threadName); EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback, const char* threadName); ~EventThread(); @@ -169,7 +169,7 @@ private: using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>; - // TODO(b/113612090): Once the Scheduler is complete this constructor will become obsolete. + // TODO(b/128863962): Once the Scheduler is complete this constructor will become obsolete. EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc, InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName); @@ -186,10 +186,7 @@ private: // Implements VSyncSource::Callback void onVSyncEvent(nsecs_t timestamp) override; - // Acquires mutex and requests next vsync. - void requestNextVsyncInternal(const sp<EventThreadConnection>& connection) EXCLUDES(mMutex); - - // TODO(b/113612090): Once the Scheduler is complete this pointer will become obsolete. + // TODO(b/128863962): Once the Scheduler is complete this pointer will become obsolete. VSyncSource* mVSyncSource GUARDED_BY(mMutex) = nullptr; std::unique_ptr<VSyncSource> mVSyncSourceUnique GUARDED_BY(mMutex) = nullptr; diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h index 56a00c082d..245a8ace88 100644 --- a/services/surfaceflinger/Scheduler/MessageQueue.h +++ b/services/surfaceflinger/Scheduler/MessageQueue.h @@ -85,7 +85,7 @@ public: virtual ~MessageQueue(); virtual void init(const sp<SurfaceFlinger>& flinger) = 0; - // TODO(akrulec): Remove this function once everything is migrated to Scheduler. + // TODO(b/128863962): Remove this function once everything is migrated to Scheduler. virtual void setEventThread(EventThread* events, ResyncCallback resyncCallback) = 0; virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0; virtual void waitMessage() = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 08a728a2c3..77c8d109f9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1245,7 +1245,7 @@ status_t SurfaceFlinger::enableVSyncInjections(bool enable) { auto resyncCallback = mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this)); - // TODO(akrulec): Part of the Injector should be refactored, so that it + // TODO(b/128863962): Part of the Injector should be refactored, so that it // can be passed to Scheduler. if (enable) { ALOGV("VSync Injections enabled"); @@ -2906,13 +2906,13 @@ void SurfaceFlinger::updateInputFlinger() { } void SurfaceFlinger::updateInputWindowInfo() { - Vector<InputWindowInfo> inputHandles; + std::vector<InputWindowInfo> inputHandles; mDrawingState.traverseInReverseZOrder([&](Layer* layer) { if (layer->hasInput()) { // When calculating the screen bounds we ignore the transparent region since it may // result in an unwanted offset. - inputHandles.add(layer->fillInputInfo()); + inputHandles.push_back(layer->fillInputInfo()); } }); diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp index 4342dc983d..b7e55f4822 100644 --- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp +++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp @@ -27,6 +27,7 @@ using namespace std::chrono_literals; using testing::_; +using testing::AtLeast; namespace android { namespace scheduler { @@ -75,7 +76,7 @@ TEST_F(RefreshRateStatsTest, canCreateAndDestroyTest) { init(configs); // There is one default config, so the refresh rates should have one item. - ASSERT_EQ(1, mRefreshRateStats->getTotalTimes().size()); + EXPECT_EQ(1, mRefreshRateStats->getTotalTimes().size()); } TEST_F(RefreshRateStatsTest, oneConfigTest) { @@ -88,13 +89,14 @@ TEST_F(RefreshRateStatsTest, oneConfigTest) { init(configs); - EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(4); - EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(2); + EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1)); + EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1)); std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(2, times.size()); - ASSERT_EQ(0, times["ScreenOff"]); - ASSERT_EQ(0, times["90fps"]); + EXPECT_EQ(2, times.size()); + EXPECT_NE(0u, times.count("ScreenOff")); + EXPECT_EQ(1u, times.count("90fps")); + EXPECT_EQ(0, times["90fps"]); // Setting up tests on mobile harness can be flaky with time passing, so testing for // exact time changes can result in flaxy numbers. To avoid that remember old // numbers to make sure the correct values are increasing in the next test. @@ -104,31 +106,31 @@ TEST_F(RefreshRateStatsTest, oneConfigTest) { // Screen is off by default. std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(0, times["90fps"]); - screenOff = times["ScreenOff"]; + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(0, times["90fps"]); mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL); + screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(screenOff, times["ScreenOff"]); - ASSERT_LT(ninety, times["90fps"]); - ninety = times["90fps"]; + EXPECT_EQ(screenOff, times["ScreenOff"]); + EXPECT_LT(ninety, times["90fps"]); mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE); + ninety = mRefreshRateStats->getTotalTimes()["90fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); - screenOff = times["ScreenOff"]; + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_90); + screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config // does not update refresh rates that come from the config. - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); } TEST_F(RefreshRateStatsTest, twoConfigsTest) { @@ -145,15 +147,17 @@ TEST_F(RefreshRateStatsTest, twoConfigsTest) { init(configs); - EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(6); - EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(4); - EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(4); + EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1)); + EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1)); + EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1)); std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(3, times.size()); - ASSERT_EQ(0, times["ScreenOff"]); - ASSERT_EQ(0, times["60fps"]); - ASSERT_EQ(0, times["90fps"]); + EXPECT_EQ(3, times.size()); + EXPECT_NE(0u, times.count("ScreenOff")); + EXPECT_EQ(1u, times.count("60fps")); + EXPECT_EQ(0, times["60fps"]); + EXPECT_EQ(1u, times.count("90fps")); + EXPECT_EQ(0, times["90fps"]); // Setting up tests on mobile harness can be flaky with time passing, so testing for // exact time changes can result in flaxy numbers. To avoid that remember old // numbers to make sure the correct values are increasing in the next test. @@ -164,61 +168,61 @@ TEST_F(RefreshRateStatsTest, twoConfigsTest) { // Screen is off by default. std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(sixty, times["60fps"]); - ASSERT_EQ(ninety, times["90fps"]); - screenOff = times["ScreenOff"]; + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(sixty, times["60fps"]); + EXPECT_EQ(ninety, times["90fps"]); mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL); + screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(screenOff, times["ScreenOff"]); - ASSERT_EQ(sixty, times["60fps"]); - ASSERT_LT(ninety, times["90fps"]); - ninety = times["90fps"]; + EXPECT_EQ(screenOff, times["ScreenOff"]); + EXPECT_EQ(sixty, times["60fps"]); + EXPECT_LT(ninety, times["90fps"]); // When power mode is normal, time for configs updates. mRefreshRateStats->setConfigMode(CONFIG_ID_60); + ninety = mRefreshRateStats->getTotalTimes()["90fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); - ASSERT_LT(sixty, times["60fps"]); - sixty = times["60fps"]; + EXPECT_EQ(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); + EXPECT_LT(sixty, times["60fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_90); + sixty = mRefreshRateStats->getTotalTimes()["60fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(screenOff, times["ScreenOff"]); - ASSERT_LT(ninety, times["90fps"]); - ASSERT_EQ(sixty, times["60fps"]); - ninety = times["90fps"]; + EXPECT_EQ(screenOff, times["ScreenOff"]); + EXPECT_LT(ninety, times["90fps"]); + EXPECT_EQ(sixty, times["60fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_60); + ninety = mRefreshRateStats->getTotalTimes()["90fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_EQ(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); - ASSERT_LT(sixty, times["60fps"]); - sixty = times["60fps"]; + EXPECT_EQ(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); + EXPECT_LT(sixty, times["60fps"]); // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config // does not update refresh rates that come from the config. mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE); mRefreshRateStats->setConfigMode(CONFIG_ID_90); + sixty = mRefreshRateStats->getTotalTimes()["60fps"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); - ASSERT_EQ(sixty, times["60fps"]); - screenOff = times["ScreenOff"]; + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); + EXPECT_EQ(sixty, times["60fps"]); mRefreshRateStats->setConfigMode(CONFIG_ID_60); + screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"]; std::this_thread::sleep_for(std::chrono::milliseconds(2)); times = mRefreshRateStats->getTotalTimes(); - ASSERT_LT(screenOff, times["ScreenOff"]); - ASSERT_EQ(ninety, times["90fps"]); - ASSERT_EQ(sixty, times["60fps"]); + EXPECT_LT(screenOff, times["ScreenOff"]); + EXPECT_EQ(ninety, times["90fps"]); + EXPECT_EQ(sixty, times["60fps"]); } } // namespace } // namespace scheduler |