diff options
-rw-r--r-- | libs/input/PointerController.cpp | 16 | ||||
-rw-r--r-- | libs/input/PointerController.h | 2 | ||||
-rw-r--r-- | libs/input/SpriteController.cpp | 33 | ||||
-rw-r--r-- | libs/input/SpriteController.h | 10 | ||||
-rw-r--r-- | libs/input/TouchSpotController.cpp | 7 | ||||
-rw-r--r-- | libs/input/TouchSpotController.h | 5 | ||||
-rw-r--r-- | libs/input/tests/PointerController_test.cpp | 39 | ||||
-rw-r--r-- | libs/input/tests/mocks/MockSprite.h | 1 |
8 files changed, 99 insertions, 14 deletions
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index f9dc5fac7e21..933a33eb8b0e 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -272,7 +272,10 @@ void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t if (it == mLocked.spotControllers.end()) { mLocked.spotControllers.try_emplace(displayId, displayId, mContext); } - mLocked.spotControllers.at(displayId).setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits); + bool skipScreenshot = mLocked.displaysToSkipScreenshot.find(displayId) != + mLocked.displaysToSkipScreenshot.end(); + mLocked.spotControllers.at(displayId).setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits, + skipScreenshot); } void PointerController::clearSpots() { @@ -352,6 +355,17 @@ void PointerController::setCustomPointerIcon(const SpriteIcon& icon) { mCursorController.setCustomPointerIcon(icon); } +void PointerController::setSkipScreenshot(int32_t displayId, bool skip) { + if (!mEnabled) return; + + std::scoped_lock lock(getLock()); + if (skip) { + mLocked.displaysToSkipScreenshot.insert(displayId); + } else { + mLocked.displaysToSkipScreenshot.erase(displayId); + } +} + void PointerController::doInactivityTimeout() { fade(Transition::GRADUAL); } diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h index 6ee5707622ca..d76ca5d15a31 100644 --- a/libs/input/PointerController.h +++ b/libs/input/PointerController.h @@ -67,6 +67,7 @@ public: void clearSpots() override; void updatePointerIcon(PointerIconStyle iconId) override; void setCustomPointerIcon(const SpriteIcon& icon) override; + void setSkipScreenshot(int32_t displayId, bool skip) override; virtual void setInactivityTimeout(InactivityTimeout inactivityTimeout); void doInactivityTimeout(); @@ -115,6 +116,7 @@ private: std::vector<gui::DisplayInfo> mDisplayInfos; std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers; + std::unordered_set<int32_t /* displayId */> displaysToSkipScreenshot; } mLocked GUARDED_BY(getLock()); class DisplayInfoListener : public gui::WindowInfosListener { diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index a63453d655e2..0baa9291f54d 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -129,7 +129,7 @@ void SpriteController::doUpdateSprites() { update.state.surfaceVisible = false; update.state.surfaceControl = obtainSurface(update.state.surfaceWidth, update.state.surfaceHeight, - update.state.displayId); + update.state.displayId, update.state.skipScreenshot); if (update.state.surfaceControl != NULL) { update.surfaceChanged = surfaceChanged = true; } @@ -209,7 +209,7 @@ void SpriteController::doUpdateSprites() { (update.state.dirty & (DIRTY_ALPHA | DIRTY_POSITION | DIRTY_TRANSFORMATION_MATRIX | DIRTY_LAYER | DIRTY_VISIBILITY | DIRTY_HOTSPOT | DIRTY_DISPLAY_ID | DIRTY_ICON_STYLE | - DIRTY_DRAW_DROP_SHADOW))))) { + DIRTY_DRAW_DROP_SHADOW | DIRTY_SKIP_SCREENSHOT))))) { needApplyTransaction = true; if (wantSurfaceVisibleAndDrawn @@ -260,6 +260,14 @@ void SpriteController::doUpdateSprites() { t.setLayer(update.state.surfaceControl, surfaceLayer); } + if (wantSurfaceVisibleAndDrawn && + (becomingVisible || (update.state.dirty & DIRTY_SKIP_SCREENSHOT))) { + int32_t flags = + update.state.skipScreenshot ? ISurfaceComposerClient::eSkipScreenshot : 0; + t.setFlags(update.state.surfaceControl, flags, + ISurfaceComposerClient::eSkipScreenshot); + } + if (becomingVisible) { t.show(update.state.surfaceControl); @@ -332,8 +340,8 @@ void SpriteController::ensureSurfaceComposerClient() { } } -sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height, - int32_t displayId) { +sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height, int32_t displayId, + bool hideOnMirrored) { ensureSurfaceComposerClient(); const sp<SurfaceControl> parent = mParentSurfaceProvider(displayId); @@ -341,11 +349,13 @@ sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height ALOGE("Failed to get the parent surface for pointers on display %d", displayId); } + int32_t createFlags = ISurfaceComposerClient::eHidden | ISurfaceComposerClient::eCursorWindow; + if (hideOnMirrored) { + createFlags |= ISurfaceComposerClient::eSkipScreenshot; + } const sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface(String8("Sprite"), width, height, - PIXEL_FORMAT_RGBA_8888, - ISurfaceComposerClient::eHidden | - ISurfaceComposerClient::eCursorWindow, + PIXEL_FORMAT_RGBA_8888, createFlags, parent ? parent->getHandle() : nullptr); if (surfaceControl == nullptr || !surfaceControl->isValid()) { ALOGE("Error creating sprite surface."); @@ -474,6 +484,15 @@ void SpriteController::SpriteImpl::setDisplayId(int32_t displayId) { } } +void SpriteController::SpriteImpl::setSkipScreenshot(bool skip) { + AutoMutex _l(mController.mLock); + + if (mLocked.state.skipScreenshot != skip) { + mLocked.state.skipScreenshot = skip; + invalidateLocked(DIRTY_SKIP_SCREENSHOT); + } +} + void SpriteController::SpriteImpl::invalidateLocked(uint32_t dirty) { bool wasDirty = mLocked.state.dirty; mLocked.state.dirty |= dirty; diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h index 35776e9961b3..4e4ba6551aec 100644 --- a/libs/input/SpriteController.h +++ b/libs/input/SpriteController.h @@ -96,6 +96,10 @@ public: /* Sets the id of the display where the sprite should be shown. */ virtual void setDisplayId(int32_t displayId) = 0; + + /* Sets the flag to hide sprite on mirrored displays. + * This will add ISurfaceComposerClient::eSkipScreenshot flag to the sprite. */ + virtual void setSkipScreenshot(bool skip) = 0; }; /* @@ -152,6 +156,7 @@ private: DIRTY_DISPLAY_ID = 1 << 7, DIRTY_ICON_STYLE = 1 << 8, DIRTY_DRAW_DROP_SHADOW = 1 << 9, + DIRTY_SKIP_SCREENSHOT = 1 << 10, }; /* Describes the state of a sprite. @@ -182,6 +187,7 @@ private: int32_t surfaceHeight; bool surfaceDrawn; bool surfaceVisible; + bool skipScreenshot; inline bool wantSurfaceVisible() const { return visible && alpha > 0.0f && icon.isValid(); @@ -209,6 +215,7 @@ private: virtual void setAlpha(float alpha); virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix); virtual void setDisplayId(int32_t displayId); + virtual void setSkipScreenshot(bool skip); inline const SpriteState& getStateLocked() const { return mLocked.state; @@ -272,7 +279,8 @@ private: void doDisposeSurfaces(); void ensureSurfaceComposerClient(); - sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, int32_t displayId); + sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, int32_t displayId, + bool hideOnMirrored); }; } // namespace android diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp index 99952aa14904..530d54129791 100644 --- a/libs/input/TouchSpotController.cpp +++ b/libs/input/TouchSpotController.cpp @@ -40,12 +40,13 @@ namespace android { // --- Spot --- void TouchSpotController::Spot::updateSprite(const SpriteIcon* icon, float newX, float newY, - int32_t displayId) { + int32_t displayId, bool skipScreenshot) { sprite->setLayer(Sprite::BASE_LAYER_SPOT + id); sprite->setAlpha(alpha); sprite->setTransformationMatrix(SpriteTransformationMatrix(scale, 0.0f, 0.0f, scale)); sprite->setPosition(newX, newY); sprite->setDisplayId(displayId); + sprite->setSkipScreenshot(skipScreenshot); x = newX; y = newY; @@ -84,7 +85,7 @@ TouchSpotController::~TouchSpotController() { } void TouchSpotController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, - BitSet32 spotIdBits) { + BitSet32 spotIdBits, bool skipScreenshot) { #if DEBUG_SPOT_UPDATES ALOGD("setSpots: idBits=%08x", spotIdBits.value); for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) { @@ -116,7 +117,7 @@ void TouchSpotController::setSpots(const PointerCoords* spotCoords, const uint32 spot = createAndAddSpotLocked(id, mLocked.displaySpots); } - spot->updateSprite(&icon, x, y, mDisplayId); + spot->updateSprite(&icon, x, y, mDisplayId, skipScreenshot); } for (Spot* spot : mLocked.displaySpots) { diff --git a/libs/input/TouchSpotController.h b/libs/input/TouchSpotController.h index 5bbc75d9570b..608653c6a2e7 100644 --- a/libs/input/TouchSpotController.h +++ b/libs/input/TouchSpotController.h @@ -32,7 +32,7 @@ public: TouchSpotController(int32_t displayId, PointerControllerContext& context); ~TouchSpotController(); void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, - BitSet32 spotIdBits); + BitSet32 spotIdBits, bool skipScreenshot); void clearSpots(); void reloadSpotResources(); @@ -59,7 +59,8 @@ private: y(0.0f), mLastIcon(nullptr) {} - void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId); + void updateSprite(const SpriteIcon* icon, float x, float y, int32_t displayId, + bool skipScreenshot); void dump(std::string& out, const char* prefix = "") const; private: diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp index a1bb5b3f1cc4..fcf226c9b949 100644 --- a/libs/input/tests/PointerController_test.cpp +++ b/libs/input/tests/PointerController_test.cpp @@ -372,6 +372,45 @@ TEST_F(PointerControllerTest, notifiesPolicyWhenPointerDisplayChanges) { << "The pointer display changes to invalid when PointerController is destroyed."; } +TEST_F(PointerControllerTest, updatesSkipScreenshotFlagForTouchSpots) { + ensureDisplayViewportIsSet(); + + PointerCoords testSpotCoords; + testSpotCoords.clear(); + testSpotCoords.setAxisValue(AMOTION_EVENT_AXIS_X, 1); + testSpotCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1); + BitSet32 testIdBits; + testIdBits.markBit(0); + std::array<uint32_t, MAX_POINTER_ID + 1> testIdToIndex; + + sp<MockSprite> testSpotSprite(new NiceMock<MockSprite>); + + // By default sprite is not marked secure + EXPECT_CALL(*mSpriteController, createSprite).WillOnce(Return(testSpotSprite)); + EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(false)); + + // Update spots to sync state with sprite + mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits, + ADISPLAY_ID_DEFAULT); + testing::Mock::VerifyAndClearExpectations(testSpotSprite.get()); + + // Marking the display to skip screenshot should update sprite as well + mPointerController->setSkipScreenshot(ADISPLAY_ID_DEFAULT, true); + EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(true)); + + // Update spots to sync state with sprite + mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits, + ADISPLAY_ID_DEFAULT); + testing::Mock::VerifyAndClearExpectations(testSpotSprite.get()); + + // Reset flag and verify again + mPointerController->setSkipScreenshot(ADISPLAY_ID_DEFAULT, false); + EXPECT_CALL(*testSpotSprite, setSkipScreenshot).With(testing::Args<0>(false)); + mPointerController->setSpots(&testSpotCoords, testIdToIndex.cbegin(), testIdBits, + ADISPLAY_ID_DEFAULT); + testing::Mock::VerifyAndClearExpectations(testSpotSprite.get()); +} + class PointerControllerWindowInfoListenerTest : public Test {}; TEST_F(PointerControllerWindowInfoListenerTest, diff --git a/libs/input/tests/mocks/MockSprite.h b/libs/input/tests/mocks/MockSprite.h index 013b79c3a3bf..0867221d9eed 100644 --- a/libs/input/tests/mocks/MockSprite.h +++ b/libs/input/tests/mocks/MockSprite.h @@ -34,6 +34,7 @@ public: MOCK_METHOD(void, setAlpha, (float), (override)); MOCK_METHOD(void, setTransformationMatrix, (const SpriteTransformationMatrix&), (override)); MOCK_METHOD(void, setDisplayId, (int32_t), (override)); + MOCK_METHOD(void, setSkipScreenshot, (bool), (override)); }; } // namespace android |