diff options
| -rw-r--r-- | include/input/InputWindow.h | 4 | ||||
| -rw-r--r-- | libs/input/InputWindow.cpp | 5 | ||||
| -rw-r--r-- | libs/input/tests/InputWindow_test.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 28 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 1 |
5 files changed, 41 insertions, 2 deletions
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index a065a4ce28..916af699e0 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -116,7 +116,7 @@ struct InputWindowInfo { INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002, INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004, }; - + /* These values are filled in by the WM and passed through SurfaceFlinger * unless specified otherwise. */ @@ -165,6 +165,8 @@ struct InputWindowInfo { int32_t displayId; int32_t portalToDisplayId = ADISPLAY_ID_NONE; InputApplicationInfo applicationInfo; + bool replaceTouchableRegionWithCrop; + wp<IBinder> touchableRegionCropHandle; void addTouchableRegion(const Rect& region); diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp index 5c5613df82..5a60347ed3 100644 --- a/libs/input/InputWindow.cpp +++ b/libs/input/InputWindow.cpp @@ -98,7 +98,8 @@ status_t InputWindowInfo::write(Parcel& output) const { output.writeInt32(portalToDisplayId); applicationInfo.write(output); output.write(touchableRegion); - + output.writeBool(replaceTouchableRegionWithCrop); + output.writeWeakBinder(touchableRegionCropHandle); return OK; } @@ -140,6 +141,8 @@ InputWindowInfo InputWindowInfo::read(const Parcel& from) { ret.portalToDisplayId = from.readInt32(); ret.applicationInfo = InputApplicationInfo::read(from); from.read(ret.touchableRegion); + ret.replaceTouchableRegionWithCrop = from.readBool(); + ret.touchableRegionCropHandle = from.readWeakBinder(); return ret; } diff --git a/libs/input/tests/InputWindow_test.cpp b/libs/input/tests/InputWindow_test.cpp index 09dd72b13b..6db18abacf 100644 --- a/libs/input/tests/InputWindow_test.cpp +++ b/libs/input/tests/InputWindow_test.cpp @@ -37,6 +37,7 @@ TEST(InputWindowInfo, ParcellingWithoutToken) { } TEST(InputWindowInfo, Parcelling) { + sp<IBinder> touchableRegionCropHandle = new BBinder(); InputWindowInfo i; i.token = new BBinder(); i.name = "Foobar"; @@ -62,6 +63,8 @@ TEST(InputWindowInfo, Parcelling) { i.inputFeatures = 29; i.displayId = 34; i.portalToDisplayId = 2; + i.replaceTouchableRegionWithCrop = true; + i.touchableRegionCropHandle = touchableRegionCropHandle; Parcel p; i.write(p); @@ -92,6 +95,8 @@ TEST(InputWindowInfo, Parcelling) { ASSERT_EQ(i.inputFeatures, i2.inputFeatures); ASSERT_EQ(i.displayId, i2.displayId); ASSERT_EQ(i.portalToDisplayId, i2.portalToDisplayId); + ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop); + ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle); } } // namespace test diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 5c3fb05744..af27ca3571 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -2009,8 +2009,24 @@ void Layer::commitChildList() { mDrawingParent = mCurrentParent; } +static wp<Layer> extractLayerFromBinder(const wp<IBinder>& weakBinderHandle) { + if (weakBinderHandle == nullptr) { + return nullptr; + } + sp<IBinder> binderHandle = weakBinderHandle.promote(); + if (binderHandle == nullptr) { + return nullptr; + } + sp<Layer::Handle> handle = static_cast<Layer::Handle*>(binderHandle.get()); + if (handle == nullptr) { + return nullptr; + } + return handle->owner; +} + void Layer::setInputInfo(const InputWindowInfo& info) { mCurrentState.inputInfo = info; + mCurrentState.touchableRegionCrop = extractLayerFromBinder(info.touchableRegionCropHandle); mCurrentState.modified = true; mCurrentState.inputInfoChanged = true; setTransactionFlags(eTransactionNeeded); @@ -2199,6 +2215,18 @@ InputWindowInfo Layer::fillInputInfo() { // bounds. info.touchableRegion = info.touchableRegion.translate(info.frameLeft, info.frameTop); info.visible = canReceiveInput(); + + auto cropLayer = mDrawingState.touchableRegionCrop.promote(); + if (info.replaceTouchableRegionWithCrop) { + if (cropLayer == nullptr) { + info.touchableRegion = Region(Rect{mScreenBounds}); + } else { + info.touchableRegion = Region(Rect{cropLayer->mScreenBounds}); + } + } else if (cropLayer != nullptr) { + info.touchableRegion = info.touchableRegion.intersect(Rect{cropLayer->mScreenBounds}); + } + return info; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 1afb9173f3..af50f5914b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -181,6 +181,7 @@ public: bool inputInfoChanged; InputWindowInfo inputInfo; + wp<Layer> touchableRegionCrop; // The fields below this point are only used by BufferStateLayer Geometry active; |