diff options
38 files changed, 558 insertions, 223 deletions
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp index 0f7c48964f..ac101ecb29 100644 --- a/cmds/installd/Android.bp +++ b/cmds/installd/Android.bp @@ -25,6 +25,7 @@ cc_defaults { "CrateManager.cpp", "InstalldNativeService.cpp", "QuotaUtils.cpp", + "SysTrace.cpp", "dexopt.cpp", "execv_helper.cpp", "globals.cpp", @@ -173,7 +174,7 @@ cc_binary { // Needs to be wherever installd is as it's execed by // installd. - required: ["migrate_legacy_obb_data.sh"], + required: ["migrate_legacy_obb_data"], } // OTA chroot tool @@ -299,6 +300,6 @@ sh_binary { // Script to migrate legacy obb data. sh_binary { - name: "migrate_legacy_obb_data.sh", + name: "migrate_legacy_obb_data", src: "migrate_legacy_obb_data.sh", } diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 8f163b94d6..2c8adc7126 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -16,8 +16,6 @@ #include "InstalldNativeService.h" -#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER - #include <errno.h> #include <fts.h> #include <inttypes.h> @@ -75,6 +73,7 @@ #include "CrateManager.h" #include "MatchExtensionGen.h" #include "QuotaUtils.h" +#include "SysTrace.h" #ifndef LOG_TAG #define LOG_TAG "installd" @@ -1327,7 +1326,7 @@ binder::Status InstalldNativeService::fixupAppData(const std::optional<std::stri const char* uuid_ = uuid ? uuid->c_str() : nullptr; for (auto userId : get_known_users(uuid_)) { LOCK_USER(); - ATRACE_BEGIN("fixup user"); + atrace_pm_begin("fixup user"); FTS* fts; FTSENT* p; auto ce_path = create_data_user_ce_path(uuid_, userId); @@ -1417,7 +1416,7 @@ binder::Status InstalldNativeService::fixupAppData(const std::optional<std::stri } } fts_close(fts); - ATRACE_END(); + atrace_pm_end(); } return ok(); } @@ -1970,7 +1969,7 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> // files from the UIDs which are most over their allocated quota // 1. Create trackers for every known UID - ATRACE_BEGIN("create"); + atrace_pm_begin("create"); const auto users = get_known_users(uuid_); #ifdef GRANULAR_LOCKS std::vector<UserLock> userLocks; @@ -2051,10 +2050,10 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> } fts_close(fts); } - ATRACE_END(); + atrace_pm_end(); // 2. Populate tracker stats and insert into priority queue - ATRACE_BEGIN("populate"); + atrace_pm_begin("populate"); auto cmp = [](std::shared_ptr<CacheTracker> left, std::shared_ptr<CacheTracker> right) { return (left->getCacheRatio() < right->getCacheRatio()); }; @@ -2064,11 +2063,11 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> it.second->loadStats(); queue.push(it.second); } - ATRACE_END(); + atrace_pm_end(); // 3. Bounce across the queue, freeing items from whichever tracker is // the most over their assigned quota - ATRACE_BEGIN("bounce"); + atrace_pm_begin("bounce"); std::shared_ptr<CacheTracker> active; while (active || !queue.empty()) { // Only look at apps under quota when explicitly requested @@ -2124,7 +2123,7 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string> } } } - ATRACE_END(); + atrace_pm_end(); } else { return error("Legacy cache logic no longer supported"); @@ -2469,84 +2468,84 @@ binder::Status InstalldNativeService::getAppSize(const std::optional<std::string flags &= ~FLAG_USE_QUOTA; } - ATRACE_BEGIN("obb"); + atrace_pm_begin("obb"); for (const auto& packageName : packageNames) { auto obbCodePath = create_data_media_package_path(uuid_, userId, "obb", packageName.c_str()); calculate_tree_size(obbCodePath, &extStats.codeSize); } - ATRACE_END(); + atrace_pm_end(); // Calculating the app size of the external storage owning app in a manual way, since // calculating it through quota apis also includes external media storage in the app storage // numbers if (flags & FLAG_USE_QUOTA && appId >= AID_APP_START && !ownsExternalStorage(appId)) { - ATRACE_BEGIN("code"); + atrace_pm_begin("code"); for (const auto& codePath : codePaths) { calculate_tree_size(codePath, &stats.codeSize, -1, multiuser_get_shared_gid(0, appId)); } - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("quota"); + atrace_pm_begin("quota"); collectQuotaStats(uuidString, userId, appId, &stats, &extStats); - ATRACE_END(); + atrace_pm_end(); } else { - ATRACE_BEGIN("code"); + atrace_pm_begin("code"); for (const auto& codePath : codePaths) { calculate_tree_size(codePath, &stats.codeSize); } - ATRACE_END(); + atrace_pm_end(); for (size_t i = 0; i < packageNames.size(); i++) { const char* pkgname = packageNames[i].c_str(); - ATRACE_BEGIN("data"); + atrace_pm_begin("data"); auto cePath = create_data_user_ce_package_path(uuid_, userId, pkgname, ceDataInodes[i]); collectManualStats(cePath, &stats); auto dePath = create_data_user_de_package_path(uuid_, userId, pkgname); collectManualStats(dePath, &stats); - ATRACE_END(); + atrace_pm_end(); // In case of sdk sandbox storage (e.g. /data/misc_ce/0/sdksandbox/<package-name>), // collect individual stats of each subdirectory (shared, storage of each sdk etc.) if (appId >= AID_APP_START && appId <= AID_APP_END) { - ATRACE_BEGIN("sdksandbox"); + atrace_pm_begin("sdksandbox"); auto sdkSandboxCePath = create_data_misc_sdk_sandbox_package_path(uuid_, true, userId, pkgname); collectManualStatsForSubDirectories(sdkSandboxCePath, &stats); auto sdkSandboxDePath = create_data_misc_sdk_sandbox_package_path(uuid_, false, userId, pkgname); collectManualStatsForSubDirectories(sdkSandboxDePath, &stats); - ATRACE_END(); + atrace_pm_end(); } if (!uuid) { - ATRACE_BEGIN("profiles"); + atrace_pm_begin("profiles"); calculate_tree_size( create_primary_current_profile_package_dir_path(userId, pkgname), &stats.dataSize); calculate_tree_size( create_primary_reference_profile_package_dir_path(pkgname), &stats.codeSize); - ATRACE_END(); + atrace_pm_end(); } - ATRACE_BEGIN("external"); + atrace_pm_begin("external"); auto extPath = create_data_media_package_path(uuid_, userId, "data", pkgname); collectManualStats(extPath, &extStats); auto mediaPath = create_data_media_package_path(uuid_, userId, "media", pkgname); calculate_tree_size(mediaPath, &extStats.dataSize); - ATRACE_END(); + atrace_pm_end(); } if (!uuid) { - ATRACE_BEGIN("dalvik"); + atrace_pm_begin("dalvik"); int32_t sharedGid = multiuser_get_shared_gid(0, appId); if (sharedGid != -1) { calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize, sharedGid, -1); } - ATRACE_END(); + atrace_pm_end(); } } @@ -2692,41 +2691,41 @@ binder::Status InstalldNativeService::getUserSize(const std::optional<std::strin } if (flags & FLAG_USE_QUOTA) { - ATRACE_BEGIN("code"); + atrace_pm_begin("code"); calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true); - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("data"); + atrace_pm_begin("data"); auto cePath = create_data_user_ce_path(uuid_, userId); collectManualStatsForUser(cePath, &stats, true); auto dePath = create_data_user_de_path(uuid_, userId); collectManualStatsForUser(dePath, &stats, true); - ATRACE_END(); + atrace_pm_end(); if (!uuid) { - ATRACE_BEGIN("profile"); + atrace_pm_begin("profile"); auto userProfilePath = create_primary_cur_profile_dir_path(userId); calculate_tree_size(userProfilePath, &stats.dataSize, -1, -1, true); auto refProfilePath = create_primary_ref_profile_dir_path(); calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true); - ATRACE_END(); + atrace_pm_end(); } - ATRACE_BEGIN("external"); + atrace_pm_begin("external"); auto sizes = getExternalSizesForUserWithQuota(uuidString, userId, appIds); extStats.dataSize += sizes.totalSize; extStats.codeSize += sizes.obbSize; - ATRACE_END(); + atrace_pm_end(); if (!uuid) { - ATRACE_BEGIN("dalvik"); + atrace_pm_begin("dalvik"); calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize, -1, -1, true); calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize, -1, -1, true); - ATRACE_END(); + atrace_pm_end(); } - ATRACE_BEGIN("quota"); + atrace_pm_begin("quota"); int64_t dataSize = extStats.dataSize; for (auto appId : appIds) { if (appId >= AID_APP_START) { @@ -2738,54 +2737,54 @@ binder::Status InstalldNativeService::getUserSize(const std::optional<std::strin } } extStats.dataSize = dataSize; - ATRACE_END(); + atrace_pm_end(); } else { - ATRACE_BEGIN("obb"); + atrace_pm_begin("obb"); auto obbPath = create_data_path(uuid_) + "/media/obb"; calculate_tree_size(obbPath, &extStats.codeSize); - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("code"); + atrace_pm_begin("code"); calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize); - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("data"); + atrace_pm_begin("data"); auto cePath = create_data_user_ce_path(uuid_, userId); collectManualStatsForUser(cePath, &stats); auto dePath = create_data_user_de_path(uuid_, userId); collectManualStatsForUser(dePath, &stats); - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("sdksandbox"); + atrace_pm_begin("sdksandbox"); auto sdkSandboxCePath = create_data_misc_sdk_sandbox_path(uuid_, true, userId); collectManualStatsForUser(sdkSandboxCePath, &stats, false, true); auto sdkSandboxDePath = create_data_misc_sdk_sandbox_path(uuid_, false, userId); collectManualStatsForUser(sdkSandboxDePath, &stats, false, true); - ATRACE_END(); + atrace_pm_end(); if (!uuid) { - ATRACE_BEGIN("profile"); + atrace_pm_begin("profile"); auto userProfilePath = create_primary_cur_profile_dir_path(userId); calculate_tree_size(userProfilePath, &stats.dataSize); auto refProfilePath = create_primary_ref_profile_dir_path(); calculate_tree_size(refProfilePath, &stats.codeSize); - ATRACE_END(); + atrace_pm_end(); } - ATRACE_BEGIN("external"); + atrace_pm_begin("external"); auto dataMediaPath = create_data_media_path(uuid_, userId); collectManualExternalStatsForUser(dataMediaPath, &extStats); #if MEASURE_DEBUG LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache " << extStats.cacheSize; #endif - ATRACE_END(); + atrace_pm_end(); if (!uuid) { - ATRACE_BEGIN("dalvik"); + atrace_pm_begin("dalvik"); calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize); calculate_tree_size(create_primary_cur_profile_dir_path(userId), &stats.dataSize); - ATRACE_END(); + atrace_pm_end(); } } @@ -2833,16 +2832,16 @@ binder::Status InstalldNativeService::getExternalSize(const std::optional<std::s } if (flags & FLAG_USE_QUOTA) { - ATRACE_BEGIN("quota"); + atrace_pm_begin("quota"); auto sizes = getExternalSizesForUserWithQuota(uuidString, userId, appIds); totalSize = sizes.totalSize; audioSize = sizes.audioSize; videoSize = sizes.videoSize; imageSize = sizes.imageSize; obbSize = sizes.obbSize; - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("apps"); + atrace_pm_begin("apps"); struct stats extStats; memset(&extStats, 0, sizeof(extStats)); for (auto appId : appIds) { @@ -2851,9 +2850,9 @@ binder::Status InstalldNativeService::getExternalSize(const std::optional<std::s } } appSize = extStats.dataSize; - ATRACE_END(); + atrace_pm_end(); } else { - ATRACE_BEGIN("manual"); + atrace_pm_begin("manual"); FTS *fts; FTSENT *p; auto path = create_data_media_path(uuid_, userId); @@ -2896,16 +2895,16 @@ binder::Status InstalldNativeService::getExternalSize(const std::optional<std::s } } fts_close(fts); - ATRACE_END(); + atrace_pm_end(); - ATRACE_BEGIN("obb"); + atrace_pm_begin("obb"); auto obbPath = StringPrintf("%s/Android/obb", create_data_media_path(uuid_, userId).c_str()); calculate_tree_size(obbPath, &obbSize); if (!(flags & FLAG_USE_QUOTA)) { totalSize -= obbSize; } - ATRACE_END(); + atrace_pm_end(); } std::vector<int64_t> ret; @@ -3709,7 +3708,7 @@ binder::Status InstalldNativeService::migrateLegacyObbData() { ENFORCE_UID(AID_SYSTEM); // NOTE: The lint warning doesn't apply to the use of system(3) with // absolute parse and no command line arguments. - if (system("/system/bin/migrate_legacy_obb_data.sh") != 0) { // NOLINT(cert-env33-c) + if (system("/system/bin/migrate_legacy_obb_data") != 0) { // NOLINT(cert-env33-c) LOG(ERROR) << "Unable to migrate legacy obb data"; } diff --git a/cmds/installd/SysTrace.cpp b/cmds/installd/SysTrace.cpp new file mode 100644 index 0000000000..fa65c77a2b --- /dev/null +++ b/cmds/installd/SysTrace.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 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 ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER + +#include "SysTrace.h" +#include <utils/Trace.h> + +namespace android::installd { +void atrace_pm_begin(const char* name) { + ATRACE_BEGIN(name); +} + +void atrace_pm_end() { + ATRACE_END(); +} +} /* namespace android::installd */ diff --git a/cmds/installd/SysTrace.h b/cmds/installd/SysTrace.h new file mode 100644 index 0000000000..18506a9258 --- /dev/null +++ b/cmds/installd/SysTrace.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2022 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. + */ + +#pragma once + +namespace android::installd { +void atrace_pm_begin(const char*); +void atrace_pm_end(); +} /* namespace android::installd */ diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp index b2fd7b1e9f..df965ab65f 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -90,6 +90,7 @@ cc_defaults { "Stability.cpp", "Status.cpp", "TextOutput.cpp", + "Trace.cpp", "Utils.cpp", ], @@ -489,6 +490,9 @@ aidl_interface { java: { enabled: false, }, + cpp: { + gen_trace: false, + }, }, } diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp index 0ee5f05030..e581d0b16c 100644 --- a/libs/binder/RpcServer.cpp +++ b/libs/binder/RpcServer.cpp @@ -560,4 +560,14 @@ status_t RpcServer::setupExternalServer(base::unique_fd serverFd) { return OK; } +bool RpcServer::hasActiveRequests() { + RpcMutexLockGuard _l(mLock); + for (const auto& [_, session] : mSessions) { + if (session->hasActiveRequests()) { + return true; + } + } + return !mServer.isInPollingState(); +} + } // namespace android diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp index bef2ed63c7..49843e5953 100644 --- a/libs/binder/RpcSession.cpp +++ b/libs/binder/RpcSession.cpp @@ -952,4 +952,24 @@ RpcSession::ExclusiveConnection::~ExclusiveConnection() { } } +bool RpcSession::hasActiveConnection(const std::vector<sp<RpcConnection>>& connections) { + for (const auto& connection : connections) { + if (connection->exclusiveTid != std::nullopt && !connection->rpcTransport->isWaiting()) { + return true; + } + } + return false; +} + +bool RpcSession::hasActiveRequests() { + RpcMutexUniqueLock _l(mMutex); + if (hasActiveConnection(mConnections.mIncoming)) { + return true; + } + if (hasActiveConnection(mConnections.mOutgoing)) { + return true; + } + return mConnections.mWaitingThreads != 0; +} + } // namespace android diff --git a/libs/binder/Trace.cpp b/libs/binder/Trace.cpp new file mode 100644 index 0000000000..1ebfa1a165 --- /dev/null +++ b/libs/binder/Trace.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 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 <binder/Trace.h> +#include <cutils/trace.h> + +namespace android { +namespace binder { + +void atrace_begin(uint64_t tag, const char* name) { + ::atrace_begin(tag, name); +} + +void atrace_end(uint64_t tag) { + ::atrace_end(tag); +} + +} // namespace binder +} // namespace android diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h index ca02ab2a78..2c99334fa4 100644 --- a/libs/binder/include/binder/RpcServer.h +++ b/libs/binder/include/binder/RpcServer.h @@ -187,6 +187,11 @@ public: std::vector<sp<RpcSession>> listSessions(); size_t numUninitializedSessions(); + /** + * Whether any requests are currently being processed. + */ + bool hasActiveRequests(); + ~RpcServer(); private: diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h index 9630e2fafa..a25ba987c8 100644 --- a/libs/binder/include/binder/RpcSession.h +++ b/libs/binder/include/binder/RpcSession.h @@ -189,6 +189,11 @@ public: */ [[nodiscard]] status_t sendDecStrong(const BpBinder* binder); + /** + * Whether any requests are currently being processed. + */ + bool hasActiveRequests(); + ~RpcSession(); /** @@ -286,6 +291,11 @@ private: [[nodiscard]] status_t initShutdownTrigger(); + /** + * Checks whether any connection is active (Not polling on fd) + */ + bool hasActiveConnection(const std::vector<sp<RpcConnection>>& connections); + enum class ConnectionUse { CLIENT, CLIENT_ASYNC, diff --git a/libs/binder/include/binder/Trace.h b/libs/binder/include/binder/Trace.h new file mode 100644 index 0000000000..99378428ad --- /dev/null +++ b/libs/binder/include/binder/Trace.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2022 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. + */ + +#pragma once + +#include <cutils/trace.h> +#include <stdint.h> + +namespace android { +namespace binder { + +// Trampoline functions allowing generated aidls to trace binder transactions without depending on +// libcutils/libutils +void atrace_begin(uint64_t tag, const char* name); +void atrace_end(uint64_t tag); + +class ScopedTrace { +public: + inline ScopedTrace(uint64_t tag, const char* name) : mTag(tag) { atrace_begin(mTag, name); } + + inline ~ScopedTrace() { atrace_end(mTag); } + +private: + uint64_t mTag; +}; + +} // namespace binder +} // namespace android diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index 32e018d597..33d28e65c5 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -57,6 +57,7 @@ cc_library { srcs: [ "ibinder.cpp", "ibinder_jni.cpp", + "libbinder.cpp", "parcel.cpp", "parcel_jni.cpp", "process.cpp", diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp index 9778ec0a76..28d1f16d64 100644 --- a/libs/binder/ndk/ibinder.cpp +++ b/libs/binder/ndk/ibinder.cpp @@ -14,21 +14,19 @@ * limitations under the License. */ +#include <android-base/logging.h> #include <android/binder_ibinder.h> #include <android/binder_ibinder_platform.h> -#include <android/binder_libbinder.h> -#include "ibinder_internal.h" - #include <android/binder_stability.h> #include <android/binder_status.h> -#include "parcel_internal.h" -#include "status_internal.h" - -#include <android-base/logging.h> #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <private/android_filesystem_config.h> +#include "ibinder_internal.h" +#include "parcel_internal.h" +#include "status_internal.h" + using DeathRecipient = ::android::IBinder::DeathRecipient; using ::android::IBinder; @@ -782,17 +780,6 @@ const char* AIBinder_getCallingSid() { return ::android::IPCThreadState::self()->getCallingSid(); } -android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder) { - if (binder == nullptr) return nullptr; - return binder->getBinder(); -} - -AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder) { - sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder); - AIBinder_incStrong(ndkBinder.get()); - return ndkBinder.get(); -} - void AIBinder_setMinSchedulerPolicy(AIBinder* binder, int policy, int priority) { binder->asABBinder()->setMinSchedulerPolicy(policy, priority); } diff --git a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h index 0bf1e3dba9..95eee26eed 100644 --- a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h +++ b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h @@ -1639,7 +1639,6 @@ static inline binder_status_t AParcel_writeData(AParcel* parcel, const T& value) return AParcel_writeParcelable(parcel, value); } else { static_assert(dependent_false_v<T>, "unrecognized type"); - return STATUS_OK; } } @@ -1707,7 +1706,6 @@ static inline binder_status_t AParcel_readData(const AParcel* parcel, T* value) return AParcel_readParcelable(parcel, value); } else { static_assert(dependent_false_v<T>, "unrecognized type"); - return STATUS_OK; } } diff --git a/libs/binder/ndk/include_cpp/android/binder_to_string.h b/libs/binder/ndk/include_cpp/android/binder_to_string.h index ef71a81328..d7840ec1f0 100644 --- a/libs/binder/ndk/include_cpp/android/binder_to_string.h +++ b/libs/binder/ndk/include_cpp/android/binder_to_string.h @@ -162,7 +162,12 @@ std::string ToString(const _T& t) { } else if constexpr (std::is_same_v<bool, _T>) { return t ? "true" : "false"; } else if constexpr (std::is_same_v<char16_t, _T>) { + // TODO(b/244494451): codecvt is deprecated in C++17 -- suppress the + // warnings. There's no replacement in the standard library yet. + _Pragma("clang diagnostic push") + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\""); return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(t); + _Pragma("clang diagnostic pop"); } else if constexpr (std::is_arithmetic_v<_T>) { return std::to_string(t); } else if constexpr (std::is_same_v<std::string, _T>) { diff --git a/libs/binder/ndk/include_platform/android/binder_libbinder.h b/libs/binder/ndk/include_platform/android/binder_libbinder.h index f0c00e87e6..dfe12a1cf7 100644 --- a/libs/binder/ndk/include_platform/android/binder_libbinder.h +++ b/libs/binder/ndk/include_platform/android/binder_libbinder.h @@ -19,7 +19,9 @@ #if !defined(__ANDROID_APEX__) && !defined(__ANDROID_VNDK__) #include <android/binder_ibinder.h> +#include <android/binder_parcel.h> #include <binder/IBinder.h> +#include <binder/Parcel.h> /** * Get libbinder version of binder from AIBinder. @@ -47,4 +49,26 @@ android::sp<android::IBinder> AIBinder_toPlatformBinder(AIBinder* binder); */ AIBinder* AIBinder_fromPlatformBinder(const android::sp<android::IBinder>& binder); +/** + * View libbinder version of parcel from AParcel (mutable). + * + * The lifetime of the returned parcel is the lifetime of the input AParcel. + * Do not ues this reference after dropping the AParcel. + * + * \param parcel non-null parcel with ownership retained by client + * \return platform parcel object + */ +android::Parcel* AParcel_viewPlatformParcel(AParcel* parcel); + +/** + * View libbinder version of parcel from AParcel (const version). + * + * The lifetime of the returned parcel is the lifetime of the input AParcel. + * Do not ues this reference after dropping the AParcel. + * + * \param parcel non-null parcel with ownership retained by client + * \return platform parcel object + */ +const android::Parcel* AParcel_viewPlatformParcel(const AParcel* parcel); + #endif diff --git a/libs/binder/ndk/libbinder.cpp b/libs/binder/ndk/libbinder.cpp new file mode 100644 index 0000000000..f94d81d8fb --- /dev/null +++ b/libs/binder/ndk/libbinder.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2022 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 <android/binder_libbinder.h> + +#include "ibinder_internal.h" +#include "parcel_internal.h" + +using ::android::IBinder; +using ::android::Parcel; +using ::android::sp; + +sp<IBinder> AIBinder_toPlatformBinder(AIBinder* binder) { + if (binder == nullptr) return nullptr; + return binder->getBinder(); +} + +AIBinder* AIBinder_fromPlatformBinder(const sp<IBinder>& binder) { + sp<AIBinder> ndkBinder = ABpBinder::lookupOrCreateFromBinder(binder); + AIBinder_incStrong(ndkBinder.get()); + return ndkBinder.get(); +} + +Parcel* AParcel_viewPlatformParcel(AParcel* parcel) { + return parcel->get(); +} + +const Parcel* AParcel_viewPlatformParcel(const AParcel* parcel) { + return parcel->get(); +} diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index 6bc9814048..259a73618b 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -158,6 +158,7 @@ LIBBINDER_NDK_PLATFORM { extern "C++" { AIBinder_fromPlatformBinder*; AIBinder_toPlatformBinder*; + AParcel_viewPlatformParcel*; }; local: *; diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp index 1b136dcb8e..6d29238758 100644 --- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp +++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp @@ -661,6 +661,15 @@ TEST(NdkBinder, ConvertToPlatformBinder) { } } +TEST(NdkBinder, ConvertToPlatformParcel) { + ndk::ScopedAParcel parcel = ndk::ScopedAParcel(AParcel_create()); + EXPECT_EQ(OK, AParcel_writeInt32(parcel.get(), 42)); + + android::Parcel* pparcel = AParcel_viewPlatformParcel(parcel.get()); + pparcel->setDataPosition(0); + EXPECT_EQ(42, pparcel->readInt32()); +} + class MyResultReceiver : public BnResultReceiver { public: Mutex mMutex; diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.h b/libs/binder/tests/parcel_fuzzer/binder_ndk.h index 81e79b5382..d19f25bc88 100644 --- a/libs/binder/tests/parcel_fuzzer/binder_ndk.h +++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.h @@ -18,29 +18,27 @@ #include <android/binder_auto_utils.h> #include <vector> +#include <android/binder_libbinder.h> #include <android/binder_parcel.h> #include "parcel_fuzzer.h" -// libbinder_ndk doesn't export this header which breaks down its API for NDK -// and APEX users, but we need access to it to fuzz. -#include "../../ndk/parcel_internal.h" - class NdkParcelAdapter { public: - NdkParcelAdapter() : mParcel(new AParcel(nullptr /*binder*/)) {} + NdkParcelAdapter() : mParcel(AParcel_create()) {} const AParcel* aParcel() const { return mParcel.get(); } AParcel* aParcel() { return mParcel.get(); } - android::Parcel* parcel() { return aParcel()->get(); } + const android::Parcel* parcel() const { return AParcel_viewPlatformParcel(aParcel()); } + android::Parcel* parcel() { return AParcel_viewPlatformParcel(aParcel()); } - const uint8_t* data() const { return aParcel()->get()->data(); } - size_t dataSize() const { return aParcel()->get()->dataSize(); } - size_t dataAvail() const { return aParcel()->get()->dataAvail(); } - size_t dataPosition() const { return aParcel()->get()->dataPosition(); } - size_t dataCapacity() const { return aParcel()->get()->dataCapacity(); } + const uint8_t* data() const { return parcel()->data(); } + size_t dataSize() const { return parcel()->dataSize(); } + size_t dataAvail() const { return parcel()->dataAvail(); } + size_t dataPosition() const { return parcel()->dataPosition(); } + size_t dataCapacity() const { return parcel()->dataCapacity(); } android::status_t setData(const uint8_t* buffer, size_t len) { - return aParcel()->get()->setData(buffer, len); + return parcel()->setData(buffer, len); } android::status_t appendFrom(const NdkParcelAdapter* parcel, int32_t start, int32_t len) { diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp index 32494e3f77..25f609674e 100644 --- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp +++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp @@ -17,6 +17,9 @@ #include <fuzzbinder/random_parcel.h> +#include <android-base/logging.h> +#include <binder/ProcessState.h> + namespace android { void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) { @@ -60,6 +63,15 @@ void fuzzService(const sp<IBinder>& binder, FuzzedDataProvider&& provider) { options.extraFds.push_back(base::unique_fd(dup(retFds[i]))); } } + + // invariants + + auto ps = ProcessState::selfOrNull(); + if (ps) { + CHECK_EQ(0, ps->getThreadPoolMaxTotalThreadCount()) + << "Binder threadpool should not be started by fuzzer because coverage can only " + "cover in-process calls."; + } } } // namespace android diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp index a8713a24d6..f68a56144d 100644 --- a/libs/binder/tests/rpc_fuzzer/main.cpp +++ b/libs/binder/tests/rpc_fuzzer/main.cpp @@ -157,8 +157,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } } - usleep(10000); - if (hangupBeforeShutdown) { connections.clear(); while (!server->listSessions().empty() || server->numUninitializedSessions()) { @@ -167,6 +165,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } } + while (server->hasActiveRequests()) { + usleep(10); + } + while (!server->shutdown()) usleep(1); serverThread.join(); diff --git a/libs/binderthreadstate/test.cpp b/libs/binderthreadstate/test.cpp index 44e2fd19b1..2f731377f0 100644 --- a/libs/binderthreadstate/test.cpp +++ b/libs/binderthreadstate/test.cpp @@ -68,8 +68,13 @@ static void callHidl(size_t id, int32_t idx) { static void callAidl(size_t id, int32_t idx) { sp<IAidlStuff> stuff; - CHECK(OK == android::getService<IAidlStuff>(String16(id2name(id).c_str()), &stuff)); - CHECK(stuff->call(idx).isOk()); + CHECK_EQ(OK, android::getService<IAidlStuff>(String16(id2name(id).c_str()), &stuff)); + auto ret = stuff->call(idx); + CHECK(ret.isOk()) << ret; +} + +static inline std::ostream& operator<<(std::ostream& o, const BinderCallType& s) { + return o << static_cast<std::underlying_type_t<BinderCallType>>(s); } class HidlServer : public IHidlStuff { @@ -79,13 +84,13 @@ public: size_t otherId; Return<void> callLocal() { - CHECK(BinderCallType::NONE == getCurrentServingCall()); + CHECK_EQ(BinderCallType::NONE, getCurrentServingCall()); return android::hardware::Status::ok(); } Return<void> call(int32_t idx) { LOG(INFO) << "HidlServer CALL " << thisId << " to " << otherId << " at idx: " << idx << " with tid: " << gettid(); - CHECK(BinderCallType::HWBINDER == getCurrentServingCall()); + CHECK_EQ(BinderCallType::HWBINDER, getCurrentServingCall()); if (idx > 0) { if (thisId == kP1Id && idx % 4 < 2) { callHidl(otherId, idx - 1); @@ -93,7 +98,7 @@ public: callAidl(otherId, idx - 1); } } - CHECK(BinderCallType::HWBINDER == getCurrentServingCall()); + CHECK_EQ(BinderCallType::HWBINDER, getCurrentServingCall()); return android::hardware::Status::ok(); } }; @@ -104,13 +109,13 @@ public: size_t otherId; Status callLocal() { - CHECK(BinderCallType::NONE == getCurrentServingCall()); + CHECK_EQ(BinderCallType::NONE, getCurrentServingCall()); return Status::ok(); } Status call(int32_t idx) { LOG(INFO) << "AidlServer CALL " << thisId << " to " << otherId << " at idx: " << idx << " with tid: " << gettid(); - CHECK(BinderCallType::BINDER == getCurrentServingCall()); + CHECK_EQ(BinderCallType::BINDER, getCurrentServingCall()); if (idx > 0) { if (thisId == kP2Id && idx % 4 < 2) { callHidl(otherId, idx - 1); @@ -118,7 +123,7 @@ public: callAidl(otherId, idx - 1); } } - CHECK(BinderCallType::BINDER == getCurrentServingCall()); + CHECK_EQ(BinderCallType::BINDER, getCurrentServingCall()); return Status::ok(); } }; @@ -161,13 +166,14 @@ int server(size_t thisId, size_t otherId) { // AIDL android::ProcessState::self()->setThreadPoolMaxThreadCount(1); sp<AidlServer> aidlServer = new AidlServer(thisId, otherId); - CHECK(OK == defaultServiceManager()->addService(String16(id2name(thisId).c_str()), aidlServer)); + CHECK_EQ(OK, + defaultServiceManager()->addService(String16(id2name(thisId).c_str()), aidlServer)); android::ProcessState::self()->startThreadPool(); // HIDL android::hardware::configureRpcThreadpool(1, true /*callerWillJoin*/); sp<IHidlStuff> hidlServer = new HidlServer(thisId, otherId); - CHECK(OK == hidlServer->registerAsService(id2name(thisId).c_str())); + CHECK_EQ(OK, hidlServer->registerAsService(id2name(thisId).c_str())); android::hardware::joinRpcThreadpool(); return EXIT_FAILURE; diff --git a/libs/fakeservicemanager/Android.bp b/libs/fakeservicemanager/Android.bp index 47c0657bbd..29924ff500 100644 --- a/libs/fakeservicemanager/Android.bp +++ b/libs/fakeservicemanager/Android.bp @@ -28,6 +28,7 @@ cc_defaults { cc_library { name: "libfakeservicemanager", defaults: ["fakeservicemanager_defaults"], + export_include_dirs: ["include/fakeservicemanager"], } cc_test_host { @@ -37,4 +38,5 @@ cc_test_host { "test_sm.cpp", ], static_libs: ["libgmock"], + local_include_dirs: ["include/fakeservicemanager"], } diff --git a/libs/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h index e0af5d4ba8..e0af5d4ba8 100644 --- a/libs/fakeservicemanager/ServiceManager.h +++ b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 3732fee7f2..429760ffe0 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -465,7 +465,7 @@ status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& if (flattenWordCount == 13) { usage = (uint64_t(buf[12]) << 32) | uint32_t(buf[6]); } else { - usage = uint64_t(usage_deprecated); + usage = uint64_t(ANDROID_NATIVE_UNSIGNED_CAST(usage_deprecated)); } native_handle* h = native_handle_create(static_cast<int>(numFds), static_cast<int>(numInts)); diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp index 41878e3487..18d670ae38 100644 --- a/services/inputflinger/Android.bp +++ b/services/inputflinger/Android.bp @@ -147,6 +147,7 @@ cc_defaults { srcs: [":libinputflinger_base_sources"], shared_libs: [ "libbase", + "libbinder", "libcutils", "libinput", "liblog", diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp index eef20a96d0..20baa42a20 100644 --- a/services/inputflinger/reader/EventHub.cpp +++ b/services/inputflinger/reader/EventHub.cpp @@ -1485,25 +1485,35 @@ EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const { } std::optional<int32_t> EventHub::getBatteryCapacity(int32_t deviceId, int32_t batteryId) const { - std::scoped_lock _l(mLock); + std::filesystem::path batteryPath; + { + // Do not read the sysfs node to get the battery state while holding + // the EventHub lock. For some peripheral devices, reading battery state + // can be broken and take 5+ seconds. Holding the lock in this case would + // block all other event processing during this time. For now, we assume this + // call never happens on the InputReader thread and read the sysfs node outside + // the lock to prevent event processing from being blocked by this call. + std::scoped_lock _l(mLock); + + const auto infos = getBatteryInfoLocked(deviceId); + auto it = infos.find(batteryId); + if (it == infos.end()) { + return std::nullopt; + } + batteryPath = it->second.path; + } // release lock - const auto infos = getBatteryInfoLocked(deviceId); - auto it = infos.find(batteryId); - if (it == infos.end()) { - return std::nullopt; - } std::string buffer; // Some devices report battery capacity as an integer through the "capacity" file - if (base::ReadFileToString(it->second.path / BATTERY_NODES.at(InputBatteryClass::CAPACITY), + if (base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::CAPACITY), &buffer)) { return std::stoi(base::Trim(buffer)); } // Other devices report capacity as an enum value POWER_SUPPLY_CAPACITY_LEVEL_XXX // These values are taken from kernel source code include/linux/power_supply.h - if (base::ReadFileToString(it->second.path / - BATTERY_NODES.at(InputBatteryClass::CAPACITY_LEVEL), + if (base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::CAPACITY_LEVEL), &buffer)) { // Remove any white space such as trailing new line const auto levelIt = BATTERY_LEVEL.find(base::Trim(buffer)); @@ -1516,15 +1526,27 @@ std::optional<int32_t> EventHub::getBatteryCapacity(int32_t deviceId, int32_t ba } std::optional<int32_t> EventHub::getBatteryStatus(int32_t deviceId, int32_t batteryId) const { - std::scoped_lock _l(mLock); - const auto infos = getBatteryInfoLocked(deviceId); - auto it = infos.find(batteryId); - if (it == infos.end()) { - return std::nullopt; - } + std::filesystem::path batteryPath; + { + // Do not read the sysfs node to get the battery state while holding + // the EventHub lock. For some peripheral devices, reading battery state + // can be broken and take 5+ seconds. Holding the lock in this case would + // block all other event processing during this time. For now, we assume this + // call never happens on the InputReader thread and read the sysfs node outside + // the lock to prevent event processing from being blocked by this call. + std::scoped_lock _l(mLock); + + const auto infos = getBatteryInfoLocked(deviceId); + auto it = infos.find(batteryId); + if (it == infos.end()) { + return std::nullopt; + } + batteryPath = it->second.path; + } // release lock + std::string buffer; - if (!base::ReadFileToString(it->second.path / BATTERY_NODES.at(InputBatteryClass::STATUS), + if (!base::ReadFileToString(batteryPath / BATTERY_NODES.at(InputBatteryClass::STATUS), &buffer)) { ALOGE("Failed to read sysfs battery info: %s", strerror(errno)); return std::nullopt; diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp index ba5083bec3..0d73e072fd 100644 --- a/services/inputflinger/reader/InputDevice.cpp +++ b/services/inputflinger/reader/InputDevice.cpp @@ -547,14 +547,6 @@ void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) { for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); }); } -std::optional<int32_t> InputDevice::getBatteryCapacity() { - return mController ? mController->getBatteryCapacity(DEFAULT_BATTERY_ID) : std::nullopt; -} - -std::optional<int32_t> InputDevice::getBatteryStatus() { - return mController ? mController->getBatteryStatus(DEFAULT_BATTERY_ID) : std::nullopt; -} - bool InputDevice::setLightColor(int32_t lightId, int32_t color) { return mController ? mController->setLightColor(lightId, color) : false; } @@ -622,6 +614,10 @@ void InputDevice::updateLedState(bool reset) { for_each_mapper([reset](InputMapper& mapper) { mapper.updateLedState(reset); }); } +std::optional<int32_t> InputDevice::getBatteryEventHubId() const { + return mController ? std::make_optional(mController->getEventHubId()) : std::nullopt; +} + InputDeviceContext::InputDeviceContext(InputDevice& device, int32_t eventHubId) : mDevice(device), mContext(device.getContext()), diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp index a378ba84cf..e9a82b4d4d 100644 --- a/services/inputflinger/reader/InputReader.cpp +++ b/services/inputflinger/reader/InputReader.cpp @@ -705,23 +705,43 @@ void InputReader::flushSensor(int32_t deviceId, InputDeviceSensorType sensorType } std::optional<int32_t> InputReader::getBatteryCapacity(int32_t deviceId) { - std::scoped_lock _l(mLock); + std::optional<int32_t> eventHubId; + { + // Do not query the battery state while holding the lock. For some peripheral devices, + // reading battery state can be broken and take 5+ seconds. Holding the lock in this case + // would block all other event processing during this time. For now, we assume this + // call never happens on the InputReader thread and get the battery state outside the + // lock to prevent event processing from being blocked by this call. + std::scoped_lock _l(mLock); + InputDevice* device = findInputDeviceLocked(deviceId); + if (!device) return {}; + eventHubId = device->getBatteryEventHubId(); + } // release lock - InputDevice* device = findInputDeviceLocked(deviceId); - if (device) { - return device->getBatteryCapacity(); - } - return std::nullopt; + if (!eventHubId) return {}; + const auto batteryIds = mEventHub->getRawBatteryIds(*eventHubId); + if (batteryIds.empty()) return {}; + return mEventHub->getBatteryCapacity(*eventHubId, batteryIds.front()); } std::optional<int32_t> InputReader::getBatteryStatus(int32_t deviceId) { - std::scoped_lock _l(mLock); + std::optional<int32_t> eventHubId; + { + // Do not query the battery state while holding the lock. For some peripheral devices, + // reading battery state can be broken and take 5+ seconds. Holding the lock in this case + // would block all other event processing during this time. For now, we assume this + // call never happens on the InputReader thread and get the battery state outside the + // lock to prevent event processing from being blocked by this call. + std::scoped_lock _l(mLock); + InputDevice* device = findInputDeviceLocked(deviceId); + if (!device) return {}; + eventHubId = device->getBatteryEventHubId(); + } // release lock - InputDevice* device = findInputDeviceLocked(deviceId); - if (device) { - return device->getBatteryStatus(); - } - return std::nullopt; + if (!eventHubId) return {}; + const auto batteryIds = mEventHub->getRawBatteryIds(*eventHubId); + if (batteryIds.empty()) return {}; + return mEventHub->getBatteryStatus(*eventHubId, batteryIds.front()); } std::vector<InputDeviceLightInfo> InputReader::getLights(int32_t deviceId) { diff --git a/services/inputflinger/reader/controller/PeripheralController.cpp b/services/inputflinger/reader/controller/PeripheralController.cpp index a6934960c9..8065f57524 100644 --- a/services/inputflinger/reader/controller/PeripheralController.cpp +++ b/services/inputflinger/reader/controller/PeripheralController.cpp @@ -524,4 +524,8 @@ std::optional<int32_t> PeripheralController::getLightPlayerId(int32_t lightId) { return light->getLightPlayerId(); } +int32_t PeripheralController::getEventHubId() const { + return getDeviceContext().getEventHubId(); +} + } // namespace android diff --git a/services/inputflinger/reader/controller/PeripheralController.h b/services/inputflinger/reader/controller/PeripheralController.h index b1bc8c732c..ac951ebe2a 100644 --- a/services/inputflinger/reader/controller/PeripheralController.h +++ b/services/inputflinger/reader/controller/PeripheralController.h @@ -31,6 +31,7 @@ public: explicit PeripheralController(InputDeviceContext& deviceContext); ~PeripheralController() override; + int32_t getEventHubId() const override; void populateDeviceInfo(InputDeviceInfo* deviceInfo) override; void dump(std::string& dump) override; bool setLightColor(int32_t lightId, int32_t color) override; @@ -43,6 +44,7 @@ public: private: inline int32_t getDeviceId() { return mDeviceContext.getId(); } inline InputDeviceContext& getDeviceContext() { return mDeviceContext; } + inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; } InputDeviceContext& mDeviceContext; void configureLights(); diff --git a/services/inputflinger/reader/controller/PeripheralControllerInterface.h b/services/inputflinger/reader/controller/PeripheralControllerInterface.h index 7688a431d1..306e36119b 100644 --- a/services/inputflinger/reader/controller/PeripheralControllerInterface.h +++ b/services/inputflinger/reader/controller/PeripheralControllerInterface.h @@ -33,6 +33,8 @@ public: PeripheralControllerInterface() {} virtual ~PeripheralControllerInterface() {} + virtual int32_t getEventHubId() const = 0; + // Interface methods for Battery virtual std::optional<int32_t> getBatteryCapacity(int32_t batteryId) = 0; virtual std::optional<int32_t> getBatteryStatus(int32_t batteryId) = 0; diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h index 728020eadc..b3a24af8a9 100644 --- a/services/inputflinger/reader/include/InputDevice.h +++ b/services/inputflinger/reader/include/InputDevice.h @@ -32,8 +32,6 @@ #include "InputReaderContext.h" namespace android { -// TODO b/180733860 support multiple battery in API and remove this. -constexpr int32_t DEFAULT_BATTERY_ID = 1; class PeripheralController; class PeripheralControllerInterface; @@ -100,8 +98,7 @@ public: void disableSensor(InputDeviceSensorType sensorType); void flushSensor(InputDeviceSensorType sensorType); - std::optional<int32_t> getBatteryCapacity(); - std::optional<int32_t> getBatteryStatus(); + std::optional<int32_t> getBatteryEventHubId() const; bool setLightColor(int32_t lightId, int32_t color); bool setLightPlayerId(int32_t lightId, int32_t playerId); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index 2ccb35e8cb..db4669967f 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -987,7 +987,9 @@ private: return BATTERY_STATUS; } - const std::vector<int32_t> getRawBatteryIds(int32_t deviceId) { return {}; } + const std::vector<int32_t> getRawBatteryIds(int32_t deviceId) override { + return {DEFAULT_BATTERY}; + } std::optional<RawBatteryInfo> getRawBatteryInfo(int32_t deviceId, int32_t batteryId) { return std::nullopt; @@ -2137,6 +2139,8 @@ public: ~FakePeripheralController() override {} + int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); } + void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {} void dump(std::string& dump) override {} @@ -2170,6 +2174,7 @@ private: InputDeviceContext& mDeviceContext; inline int32_t getDeviceId() { return mDeviceContext.getId(); } inline InputDeviceContext& getDeviceContext() { return mDeviceContext; } + inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; } }; TEST_F(InputReaderTest, BatteryGetCapacity) { diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp index bdcab515f2..665a7ee7ee 100644 --- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp +++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp @@ -19,6 +19,7 @@ #define LOG_TAG "VSyncReactor" //#define LOG_NDEBUG 0 +#include <assert.h> #include <cutils/properties.h> #include <log/log.h> #include <utils/Trace.h> diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index d33bc1080c..434c297cc9 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -52,19 +52,12 @@ const String8 SURFACE_NAME("Test Surface Name"); #pragma clang diagnostic ignored "-Wconversion" class CredentialsTest : public ::testing::Test { protected: - void SetUp() override { - // Start the tests as root. - seteuid(AID_ROOT); - - ASSERT_NO_FATAL_FAILURE(initClient()); - } + void SetUp() override { ASSERT_NO_FATAL_FAILURE(initClient()); } void TearDown() override { mComposerClient->dispose(); mBGSurfaceControl.clear(); mComposerClient.clear(); - // Finish the tests as root. - seteuid(AID_ROOT); } sp<IBinder> mDisplay; @@ -99,31 +92,6 @@ protected: } /** - * Sets UID to imitate Graphic's process. - */ - void setGraphicsUID() { - seteuid(AID_ROOT); - seteuid(AID_GRAPHICS); - } - - /** - * Sets UID to imitate System's process. - */ - void setSystemUID() { - seteuid(AID_ROOT); - seteuid(AID_SYSTEM); - } - - /** - * Sets UID to imitate a process that doesn't have any special privileges in - * our code. - */ - void setBinUID() { - seteuid(AID_ROOT); - seteuid(AID_BIN); - } - - /** * Template function the check a condition for different types of users: root * graphics, system, and non-supported user. Root, graphics, and system should * always equal privilegedValue, and non-supported user should equal unprivilegedValue. @@ -131,24 +99,34 @@ protected: template <typename T> void checkWithPrivileges(std::function<T()> condition, T privilegedValue, T unprivilegedValue) { // Check with root. - seteuid(AID_ROOT); - ASSERT_EQ(privilegedValue, condition()); + { + UIDFaker f(AID_SYSTEM); + ASSERT_EQ(privilegedValue, condition()); + } // Check as a Graphics user. - setGraphicsUID(); - ASSERT_EQ(privilegedValue, condition()); + { + UIDFaker f(AID_GRAPHICS); + ASSERT_EQ(privilegedValue, condition()); + } // Check as a system user. - setSystemUID(); - ASSERT_EQ(privilegedValue, condition()); + { + UIDFaker f(AID_SYSTEM); + ASSERT_EQ(privilegedValue, condition()); + } // Check as a non-supported user. - setBinUID(); - ASSERT_EQ(unprivilegedValue, condition()); + { + UIDFaker f(AID_BIN); + ASSERT_EQ(unprivilegedValue, condition()); + } // Check as shell since shell has some additional permissions - seteuid(AID_SHELL); - ASSERT_EQ(unprivilegedValue, condition()); + { + UIDFaker f(AID_SHELL); + ASSERT_EQ(privilegedValue, condition()); + } } }; @@ -157,17 +135,23 @@ TEST_F(CredentialsTest, ClientInitTest) { ASSERT_NO_FATAL_FAILURE(initClient()); // Graphics can init the client. - setGraphicsUID(); - ASSERT_NO_FATAL_FAILURE(initClient()); + { + UIDFaker f(AID_GRAPHICS); + ASSERT_NO_FATAL_FAILURE(initClient()); + } // System can init the client. - setSystemUID(); - ASSERT_NO_FATAL_FAILURE(initClient()); + { + UIDFaker f(AID_SYSTEM); + ASSERT_NO_FATAL_FAILURE(initClient()); + } // Anyone else can init the client. - setBinUID(); - mComposerClient = new SurfaceComposerClient; - ASSERT_NO_FATAL_FAILURE(initClient()); + { + UIDFaker f(AID_BIN); + mComposerClient = new SurfaceComposerClient; + ASSERT_NO_FATAL_FAILURE(initClient()); + } } TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) { @@ -181,7 +165,7 @@ TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) { TEST_F(CredentialsTest, AllowedGetterMethodsTest) { // The following methods are tested with a UID that is not root, graphics, // or system, to show that anyone can access them. - setBinUID(); + UIDFaker f(AID_BIN); const auto display = SurfaceComposerClient::getInternalDisplayToken(); ASSERT_TRUE(display != nullptr); @@ -250,24 +234,34 @@ TEST_F(CredentialsTest, CreateDisplayTest) { }; // Check with root. - seteuid(AID_ROOT); - ASSERT_FALSE(condition()); + { + UIDFaker f(AID_ROOT); + ASSERT_FALSE(condition()); + } // Check as a Graphics user. - setGraphicsUID(); - ASSERT_TRUE(condition()); + { + UIDFaker f(AID_GRAPHICS); + ASSERT_TRUE(condition()); + } // Check as a system user. - setSystemUID(); - ASSERT_TRUE(condition()); + { + UIDFaker f(AID_SYSTEM); + ASSERT_TRUE(condition()); + } // Check as a non-supported user. - setBinUID(); - ASSERT_FALSE(condition()); + { + UIDFaker f(AID_BIN); + ASSERT_FALSE(condition()); + } // Check as shell since shell has some additional permissions - seteuid(AID_SHELL); - ASSERT_FALSE(condition()); + { + UIDFaker f(AID_SHELL); + ASSERT_FALSE(condition()); + } condition = [=]() { sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false); @@ -313,17 +307,22 @@ TEST_F(CredentialsTest, GetLayerDebugInfo) { // is called when we call dumpsys. I don't see a reason why we should change this. std::vector<LayerDebugInfo> outLayers; // Check with root. - seteuid(AID_ROOT); - ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers)); + { + UIDFaker f(AID_ROOT); + ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers)); + } // Check as a shell. - seteuid(AID_SHELL); - ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers)); + { + UIDFaker f(AID_SHELL); + ASSERT_EQ(NO_ERROR, sf->getLayerDebugInfo(&outLayers)); + } // Check as anyone else. - seteuid(AID_ROOT); - seteuid(AID_BIN); - ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers)); + { + UIDFaker f(AID_BIN); + ASSERT_EQ(PERMISSION_DENIED, sf->getLayerDebugInfo(&outLayers)); + } } TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 5ff9399a86..1fe8800e09 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -19,6 +19,8 @@ #include <android/hardware/graphics/common/1.0/types.h> #include <grallocusage/GrallocUsageConversion.h> #include <graphicsenv/GraphicsEnv.h> +#include <hardware/gralloc.h> +#include <hardware/gralloc1.h> #include <log/log.h> #include <sync/sync.h> #include <system/window.h> @@ -42,6 +44,26 @@ namespace driver { namespace { +static uint64_t convertGralloc1ToBufferUsage(uint64_t producerUsage, + uint64_t consumerUsage) { + static_assert(uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) == + uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN), + "expected ConsumerUsage and ProducerUsage CPU_READ_OFTEN " + "bits to match"); + uint64_t merged = producerUsage | consumerUsage; + if ((merged & (GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN)) == + GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) { + merged &= ~uint64_t(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN); + merged |= BufferUsage::CPU_READ_OFTEN; + } + if ((merged & (GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) == + GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) { + merged &= ~uint64_t(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN); + merged |= BufferUsage::CPU_WRITE_OFTEN; + } + return merged; +} + const VkSurfaceTransformFlagsKHR kSupportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR | VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR | @@ -1337,7 +1359,7 @@ VkResult CreateSwapchainKHR(VkDevice device, num_images = 1; } - int32_t legacy_usage = 0; + uint64_t native_usage = 0; if (dispatch.GetSwapchainGrallocUsage2ANDROID) { uint64_t consumer_usage, producer_usage; ATRACE_BEGIN("GetSwapchainGrallocUsage2ANDROID"); @@ -1349,10 +1371,11 @@ VkResult CreateSwapchainKHR(VkDevice device, ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result); return VK_ERROR_SURFACE_LOST_KHR; } - legacy_usage = - android_convertGralloc1To0Usage(producer_usage, consumer_usage); + native_usage = + convertGralloc1ToBufferUsage(consumer_usage, producer_usage); } else if (dispatch.GetSwapchainGrallocUsageANDROID) { ATRACE_BEGIN("GetSwapchainGrallocUsageANDROID"); + int32_t legacy_usage = 0; result = dispatch.GetSwapchainGrallocUsageANDROID( device, create_info->imageFormat, create_info->imageUsage, &legacy_usage); @@ -1361,8 +1384,9 @@ VkResult CreateSwapchainKHR(VkDevice device, ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result); return VK_ERROR_SURFACE_LOST_KHR; } + native_usage = static_cast<uint64_t>(legacy_usage); } - uint64_t native_usage = static_cast<uint64_t>(legacy_usage); + native_usage |= surface.consumer_usage; bool createProtectedSwapchain = false; if (create_info->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) { |