diff options
-rw-r--r-- | libs/gui/Android.bp | 1 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 8 | ||||
-rw-r--r-- | libs/gui/LayerStatePermissions.cpp | 58 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 12 | ||||
-rw-r--r-- | libs/gui/include/gui/ISurfaceComposer.h | 2 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerStatePermissions.h | 29 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceComposerClient.h | 2 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 64 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 27 | ||||
-rw-r--r-- | services/surfaceflinger/TransactionState.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/tests/Credentials_test.cpp | 53 | ||||
-rw-r--r-- | services/surfaceflinger/tests/WindowInfosListener_test.cpp | 39 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h | 74 |
15 files changed, 277 insertions, 100 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 33bb343c9d..80fed98434 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -226,6 +226,7 @@ cc_library_shared { "ITransactionCompletedListener.cpp", "LayerDebugInfo.cpp", "LayerMetadata.cpp", + "LayerStatePermissions.cpp", "LayerState.cpp", "OccupancyTracker.cpp", "StreamSplitter.cpp", diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index cefb9a71d6..d72f65eb7a 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -62,7 +62,7 @@ public: status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& commands, int64_t desiredPresentTime, + InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, @@ -188,9 +188,9 @@ status_t BnSurfaceComposer::onTransact( SAFE_PARCEL(data.readUint64, &transactionId); return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken, - inputWindowCommands, desiredPresentTime, isAutoTimestamp, - uncacheBuffers, hasListenerCallbacks, listenerCallbacks, - transactionId); + std::move(inputWindowCommands), desiredPresentTime, + isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, + listenerCallbacks, transactionId); } default: { return BBinder::onTransact(code, data, reply, flags); diff --git a/libs/gui/LayerStatePermissions.cpp b/libs/gui/LayerStatePermissions.cpp new file mode 100644 index 0000000000..28697ca953 --- /dev/null +++ b/libs/gui/LayerStatePermissions.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 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/IPCThreadState.h> +#include <gui/LayerStatePermissions.h> +#include <private/android_filesystem_config.h> +#ifndef __ANDROID_VNDK__ +#include <binder/PermissionCache.h> +#endif // __ANDROID_VNDK__ +#include <gui/LayerState.h> + +namespace android { +std::unordered_map<std::string, int> LayerStatePermissions::mPermissionMap = { + // If caller has ACCESS_SURFACE_FLINGER, they automatically get ROTATE_SURFACE_FLINGER + // permission, as well + {"android.permission.ACCESS_SURFACE_FLINGER", + layer_state_t::Permission::ACCESS_SURFACE_FLINGER | + layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, + {"android.permission.ROTATE_SURFACE_FLINGER", + layer_state_t::Permission::ROTATE_SURFACE_FLINGER}, + {"android.permission.INTERNAL_SYSTEM_WINDOW", + layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW}, +}; + +static bool callingThreadHasPermission(const std::string& permission __attribute__((unused)), + int pid __attribute__((unused)), + int uid __attribute__((unused))) { +#ifndef __ANDROID_VNDK__ + return uid == AID_GRAPHICS || uid == AID_SYSTEM || + PermissionCache::checkPermission(String16(permission.c_str()), pid, uid); +#endif // __ANDROID_VNDK__ + return false; +} + +uint32_t LayerStatePermissions::getTransactionPermissions(int pid, int uid) { + uint32_t permissions = 0; + for (auto [permissionName, permissionVal] : mPermissionMap) { + if (callingThreadHasPermission(permissionName, pid, uid)) { + permissions |= permissionVal; + } + } + + return permissions; +} +} // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index eb5cc4f8ab..1b13ec1c06 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -54,6 +54,7 @@ #include <ui/DynamicDisplayInfo.h> #include <android-base/thread_annotations.h> +#include <gui/LayerStatePermissions.h> #include <private/gui/ComposerService.h> #include <private/gui/ComposerServiceAIDL.h> @@ -716,11 +717,16 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) mListenerCallbacks = other.mListenerCallbacks; } -void SurfaceComposerClient::Transaction::sanitize() { +void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) { + uint32_t permissions = LayerStatePermissions::getTransactionPermissions(pid, uid); for (auto & [handle, composerState] : mComposerStates) { - composerState.state.sanitize(0 /* permissionMask */); + composerState.state.sanitize(permissions); + } + if (!mInputWindowCommands.empty() && + (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) { + ALOGE("Only privileged callers are allowed to send input commands."); + mInputWindowCommands.clear(); } - mInputWindowCommands.clear(); } std::unique_ptr<SurfaceComposerClient::Transaction> diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 1e67225a4e..bd21851c14 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -113,7 +113,7 @@ public: virtual status_t setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, + InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) = 0; diff --git a/libs/gui/include/gui/LayerStatePermissions.h b/libs/gui/include/gui/LayerStatePermissions.h new file mode 100644 index 0000000000..a90f30c621 --- /dev/null +++ b/libs/gui/include/gui/LayerStatePermissions.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 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 <stdint.h> +#include <string> +#include <unordered_map> + +namespace android { +class LayerStatePermissions { +public: + static uint32_t getTransactionPermissions(int pid, int uid); + +private: + static std::unordered_map<std::string, int> mPermissionMap; +}; +} // namespace android
\ No newline at end of file diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 945b164fdc..8d2cdaf5b8 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -744,7 +744,7 @@ public: * * TODO (b/213644870): Remove all permissioned things from Transaction */ - void sanitize(); + void sanitize(int pid, int uid); static sp<IBinder> getDefaultApplyToken(); static void setDefaultApplyToken(sp<IBinder> applyToken); diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index fccc408473..5bc6904563 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -699,7 +699,7 @@ public: Vector<ComposerState>& /*state*/, const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/, const sp<IBinder>& /*applyToken*/, - const InputWindowCommands& /*inputWindowCommands*/, + InputWindowCommands /*inputWindowCommands*/, int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, const std::vector<client_cache_t>& /*cachedBuffer*/, bool /*hasListenerCallbacks*/, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2d406788cf..95159d7d2a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -110,6 +110,7 @@ #include <unordered_map> #include <vector> +#include <gui/LayerStatePermissions.h> #include <ui/DisplayIdentification.h> #include "BackgroundExecutor.h" #include "Client.h" @@ -4405,7 +4406,7 @@ bool SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& tran transaction.inputWindowCommands, transaction.desiredPresentTime, transaction.isAutoTimestamp, std::move(transaction.uncacheBufferIds), transaction.postTime, - transaction.permissions, transaction.hasListenerCallbacks, + transaction.hasListenerCallbacks, transaction.listenerCallbacks, transaction.originPid, transaction.originUid, transaction.id); } @@ -4484,24 +4485,27 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_s status_t SurfaceFlinger::setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, - bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId) { + InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, + const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, + const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) { ATRACE_CALL(); - uint32_t permissions = - callingThreadHasUnscopedSurfaceFlingerAccess() ? - layer_state_t::Permission::ACCESS_SURFACE_FLINGER : 0; - // Avoid checking for rotation permissions if the caller already has ACCESS_SURFACE_FLINGER - // permissions. - if ((permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) || - callingThreadHasPermission(sRotateSurfaceFlinger)) { - permissions |= layer_state_t::Permission::ROTATE_SURFACE_FLINGER; + IPCThreadState* ipc = IPCThreadState::self(); + const int originPid = ipc->getCallingPid(); + const int originUid = ipc->getCallingUid(); + uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid); + for (auto composerState : states) { + composerState.state.sanitize(permissions); } - if (callingThreadHasPermission(sInternalSystemWindow)) { - permissions |= layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW; + for (DisplayState display : displays) { + display.sanitize(permissions); + } + + if (!inputWindowCommands.empty() && + (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) { + ALOGE("Only privileged callers are allowed to send input commands."); + inputWindowCommands.clear(); } if (flags & (eEarlyWakeupStart | eEarlyWakeupEnd)) { @@ -4517,10 +4521,6 @@ status_t SurfaceFlinger::setTransactionState( const int64_t postTime = systemTime(); - IPCThreadState* ipc = IPCThreadState::self(); - const int originPid = ipc->getCallingPid(); - const int originUid = ipc->getCallingUid(); - std::vector<uint64_t> uncacheBufferIds; uncacheBufferIds.reserve(uncacheBuffers.size()); for (const auto& uncacheBuffer : uncacheBuffers) { @@ -4567,12 +4567,11 @@ status_t SurfaceFlinger::setTransactionState( displays, flags, applyToken, - inputWindowCommands, + std::move(inputWindowCommands), desiredPresentTime, isAutoTimestamp, std::move(uncacheBufferIds), postTime, - permissions, hasListenerCallbacks, listenerCallbacks, originPid, @@ -4601,14 +4600,12 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, - const int64_t postTime, uint32_t permissions, - bool hasListenerCallbacks, + const int64_t postTime, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) { uint32_t transactionFlags = 0; if (!mLayerLifecycleManagerEnabled) { for (DisplayState& display : displays) { - display.sanitize(permissions); transactionFlags |= setDisplayStateLocked(display); } } @@ -4625,12 +4622,12 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin if (mLegacyFrontEndEnabled) { clientStateFlags |= setClientStateLocked(frameTimelineInfo, resolvedState, desiredPresentTime, - isAutoTimestamp, postTime, permissions, transactionId); + isAutoTimestamp, postTime, transactionId); } else /*mLayerLifecycleManagerEnabled*/ { clientStateFlags |= updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime, isAutoTimestamp, - postTime, permissions, transactionId); + postTime, transactionId); } if ((flags & eAnimation) && resolvedState.state.surface) { if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) { @@ -4647,12 +4644,7 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin } transactionFlags |= clientStateFlags; - - if (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) { - transactionFlags |= addInputWindowCommands(inputWindowCommands); - } else if (!inputWindowCommands.empty()) { - ALOGE("Only privileged callers are allowed to send input commands."); - } + transactionFlags |= addInputWindowCommands(inputWindowCommands); for (uint64_t uncacheBufferId : uncacheBufferIds) { mBufferIdsToUncache.push_back(uncacheBufferId); @@ -4689,7 +4681,6 @@ bool SurfaceFlinger::applyAndCommitDisplayTransactionStates( uint32_t transactionFlags = 0; for (auto& transaction : transactions) { for (DisplayState& display : transaction.displays) { - display.sanitize(transaction.permissions); transactionFlags |= setDisplayStateLocked(display); } } @@ -4788,10 +4779,8 @@ bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermis uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo, ResolvedComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, - uint64_t transactionId) { + int64_t postTime, uint64_t transactionId) { layer_state_t& s = composerState.state; - s.sanitize(permissions); std::vector<ListenerCallbacks> filteredListeners; for (auto& listener : s.listeners) { @@ -5140,10 +5129,8 @@ uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& f ResolvedComposerState& composerState, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, - uint32_t permissions, uint64_t transactionId) { layer_state_t& s = composerState.state; - s.sanitize(permissions); std::vector<ListenerCallbacks> filteredListeners; for (auto& listener : s.listeners) { @@ -5425,7 +5412,6 @@ void SurfaceFlinger::initializeDisplays() { const nsecs_t now = systemTime(); state.desiredPresentTime = now; state.postTime = now; - state.permissions = layer_state_t::ACCESS_SURFACE_FLINGER; state.originPid = mPid; state.originUid = static_cast<int>(getuid()); const uint64_t transactionId = (static_cast<uint64_t>(mPid) << 32) | mUniqueTransactionId++; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 8cc0184e99..cfaa221a45 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -510,7 +510,7 @@ private: status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, + InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks, @@ -731,14 +731,16 @@ private: /* * Transactions */ - bool applyTransactionState( - const FrameTimelineInfo& info, std::vector<ResolvedComposerState>& state, - Vector<DisplayState>& displays, uint32_t flags, - const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, - bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, - const int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid, - uint64_t transactionId) REQUIRES(mStateLock); + bool applyTransactionState(const FrameTimelineInfo& info, + std::vector<ResolvedComposerState>& state, + Vector<DisplayState>& displays, uint32_t flags, + const InputWindowCommands& inputWindowCommands, + const int64_t desiredPresentTime, bool isAutoTimestamp, + const std::vector<uint64_t>& uncacheBufferIds, + const int64_t postTime, bool hasListenerCallbacks, + const std::vector<ListenerCallbacks>& listenerCallbacks, + int originPid, int originUid, uint64_t transactionId) + REQUIRES(mStateLock); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext); @@ -759,12 +761,11 @@ private: uint32_t setClientStateLocked(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, uint64_t transactionId) - REQUIRES(mStateLock); + int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, - int64_t postTime, uint32_t permissions, - uint64_t transactionId) REQUIRES(mStateLock); + int64_t postTime, uint64_t transactionId) + REQUIRES(mStateLock); uint32_t getTransactionFlags() const; // Sets the masked bits, and schedules a commit if needed. diff --git a/services/surfaceflinger/TransactionState.h b/services/surfaceflinger/TransactionState.h index 35c8b6c647..62a7dfd0f1 100644 --- a/services/surfaceflinger/TransactionState.h +++ b/services/surfaceflinger/TransactionState.h @@ -54,7 +54,7 @@ struct TransactionState { const Vector<DisplayState>& displayStates, uint32_t transactionFlags, const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, - std::vector<uint64_t> uncacheBufferIds, int64_t postTime, uint32_t permissions, + std::vector<uint64_t> uncacheBufferIds, int64_t postTime, bool hasListenerCallbacks, std::vector<ListenerCallbacks> listenerCallbacks, int originPid, int originUid, uint64_t transactionId) : frameTimelineInfo(frameTimelineInfo), @@ -67,7 +67,6 @@ struct TransactionState { isAutoTimestamp(isAutoTimestamp), uncacheBufferIds(std::move(uncacheBufferIds)), postTime(postTime), - permissions(permissions), hasListenerCallbacks(hasListenerCallbacks), listenerCallbacks(listenerCallbacks), originPid(originPid), @@ -126,7 +125,6 @@ struct TransactionState { bool isAutoTimestamp; std::vector<uint64_t> uncacheBufferIds; int64_t postTime; - uint32_t permissions; bool hasListenerCallbacks; std::vector<ListenerCallbacks> listenerCallbacks; int originPid; diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index 4a45eb5586..69e9a169e3 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -31,6 +31,7 @@ #include <utils/String8.h> #include <functional> #include "utils/ScreenshotUtils.h" +#include "utils/WindowInfosListenerUtils.h" namespace android { @@ -378,6 +379,58 @@ TEST_F(CredentialsTest, GetActiveColorModeBasicCorrectness) { ASSERT_NE(static_cast<ColorMode>(BAD_VALUE), colorMode); } +TEST_F(CredentialsTest, TransactionPermissionTest) { + WindowInfosListenerUtils windowInfosListenerUtils; + std::string name = "Test Layer"; + sp<IBinder> token = sp<BBinder>::make(); + WindowInfo windowInfo; + windowInfo.name = name; + windowInfo.token = token; + sp<SurfaceControl> surfaceControl = + mComposerClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eFXSurfaceBufferState); + const Rect crop(0, 0, 100, 100); + { + UIDFaker f(AID_SYSTEM); + Transaction() + .setLayerStack(surfaceControl, ui::DEFAULT_LAYER_STACK) + .show(surfaceControl) + .setLayer(surfaceControl, INT32_MAX - 1) + .setCrop(surfaceControl, crop) + .setInputWindowInfo(surfaceControl, windowInfo) + .apply(); + } + + // Called from non privileged process + Transaction().setTrustedOverlay(surfaceControl, true); + { + UIDFaker f(AID_SYSTEM); + auto windowIsPresentAndNotTrusted = [&](const std::vector<WindowInfo>& windowInfos) { + auto foundWindowInfo = + WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + if (!foundWindowInfo) { + return false; + } + return !foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); + }; + windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndNotTrusted); + } + + { + UIDFaker f(AID_SYSTEM); + Transaction().setTrustedOverlay(surfaceControl, true); + auto windowIsPresentAndTrusted = [&](const std::vector<WindowInfo>& windowInfos) { + auto foundWindowInfo = + WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); + if (!foundWindowInfo) { + return false; + } + return foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); + }; + windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndTrusted); + } +} + } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/tests/WindowInfosListener_test.cpp b/services/surfaceflinger/tests/WindowInfosListener_test.cpp index 3f27360cb7..ad9a674456 100644 --- a/services/surfaceflinger/tests/WindowInfosListener_test.cpp +++ b/services/surfaceflinger/tests/WindowInfosListener_test.cpp @@ -20,11 +20,13 @@ #include <private/android_filesystem_config.h> #include <cstdint> #include <future> +#include "utils/WindowInfosListenerUtils.h" namespace android { using Transaction = SurfaceComposerClient::Transaction; using gui::DisplayInfo; using gui::WindowInfo; +constexpr auto findMatchingWindowInfo = WindowInfosListenerUtils::findMatchingWindowInfo; using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; @@ -37,45 +39,14 @@ protected: void TearDown() override { seteuid(AID_ROOT); } - struct WindowInfosListener : public gui::WindowInfosListener { - public: - WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) - : mPredicate(std::move(predicate)), mPromise(promise) {} - - void onWindowInfosChanged(const gui::WindowInfosUpdate& update) override { - if (mPredicate(update.windowInfos)) { - mPromise.set_value(); - } - } - - private: - WindowInfosPredicate mPredicate; - std::promise<void>& mPromise; - }; - sp<SurfaceComposerClient> mClient; + WindowInfosListenerUtils mWindowInfosListenerUtils; - bool waitForWindowInfosPredicate(WindowInfosPredicate predicate) { - std::promise<void> promise; - auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); - mClient->addWindowInfosListener(listener); - auto future = promise.get_future(); - bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; - mClient->removeWindowInfosListener(listener); - return satisfied; + bool waitForWindowInfosPredicate(const WindowInfosPredicate& predicate) { + return mWindowInfosListenerUtils.waitForWindowInfosPredicate(std::move(predicate)); } }; -const WindowInfo* findMatchingWindowInfo(const WindowInfo& targetWindowInfo, - const std::vector<WindowInfo>& windowInfos) { - for (const WindowInfo& windowInfo : windowInfos) { - if (windowInfo.token == targetWindowInfo.token) { - return &windowInfo; - } - } - return nullptr; -} - TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) { std::string name = "Test Layer"; sp<IBinder> token = sp<BBinder>::make(); diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp index dbb7c6ce63..6a641b3926 100644 --- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp @@ -386,7 +386,7 @@ public: transaction.applyToken, transaction.inputWindowCommands, transaction.desiredPresentTime, - transaction.isAutoTimestamp, {}, systemTime(), 0, + transaction.isAutoTimestamp, {}, systemTime(), mHasListenerCallbacks, mCallbacks, getpid(), static_cast<int>(getuid()), transaction.id); mFlinger.setTransactionStateInternal(transactionState); diff --git a/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h new file mode 100644 index 0000000000..8e28a75ed4 --- /dev/null +++ b/services/surfaceflinger/tests/utils/WindowInfosListenerUtils.h @@ -0,0 +1,74 @@ +/* + * Copyright 2023 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 <gtest/gtest.h> +#include <gui/SurfaceComposerClient.h> +#include <private/android_filesystem_config.h> +#include <cstdint> +#include <future> + +namespace android { +using Transaction = SurfaceComposerClient::Transaction; +using gui::DisplayInfo; +using gui::WindowInfo; + +using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>; + +class WindowInfosListenerUtils { +public: + WindowInfosListenerUtils() { mClient = sp<SurfaceComposerClient>::make(); } + + bool waitForWindowInfosPredicate(const WindowInfosPredicate& predicate) { + std::promise<void> promise; + auto listener = sp<WindowInfosListener>::make(std::move(predicate), promise); + mClient->addWindowInfosListener(listener); + auto future = promise.get_future(); + bool satisfied = future.wait_for(std::chrono::seconds{1}) == std::future_status::ready; + mClient->removeWindowInfosListener(listener); + return satisfied; + } + + static const WindowInfo* findMatchingWindowInfo(const WindowInfo& targetWindowInfo, + const std::vector<WindowInfo>& windowInfos) { + for (const WindowInfo& windowInfo : windowInfos) { + if (windowInfo.token == targetWindowInfo.token) { + return &windowInfo; + } + } + return nullptr; + } + +private: + struct WindowInfosListener : public gui::WindowInfosListener { + public: + WindowInfosListener(WindowInfosPredicate predicate, std::promise<void>& promise) + : mPredicate(std::move(predicate)), mPromise(promise) {} + + void onWindowInfosChanged(const gui::WindowInfosUpdate& update) override { + if (mPredicate(update.windowInfos)) { + mPromise.set_value(); + } + } + + private: + WindowInfosPredicate mPredicate; + std::promise<void>& mPromise; + }; + + sp<SurfaceComposerClient> mClient; +}; + +} // namespace android |