Allow touches to pass through screenshot shelf view

Bug: 332410350
Bug: 329659738
Test: manual
Flag: ACONFIG com.android.systemui.screenshot_shelf_ui DEVELOPMENT
Change-Id: I47e07f87242273bd6463b01783c4b9fafa97e391
Merged-In: I47e07f87242273bd6463b01783c4b9fafa97e391
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
index 6b9332b..254c133 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
@@ -28,6 +28,7 @@
 import android.view.View
 import android.view.ViewTreeObserver
 import android.view.WindowInsets
+import android.view.WindowManager
 import android.window.OnBackInvokedCallback
 import android.window.OnBackInvokedDispatcher
 import com.android.internal.logging.UiEventLogger
@@ -53,6 +54,7 @@
 constructor(
     private val logger: UiEventLogger,
     private val viewModel: ScreenshotViewModel,
+    private val windowManager: WindowManager,
     @Assisted private val context: Context,
     @Assisted private val displayId: Int
 ) : ScreenshotViewProxy {
@@ -79,6 +81,16 @@
         addPredictiveBackListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
         setOnKeyListener { requestDismissal(SCREENSHOT_DISMISSED_OTHER) }
         debugLog(DEBUG_WINDOW) { "adding OnComputeInternalInsetsListener" }
+        view.viewTreeObserver.addOnComputeInternalInsetsListener { info ->
+            val touchableRegion =
+                view.getTouchRegion(
+                    windowManager.currentWindowMetrics.windowInsets.getInsets(
+                        WindowInsets.Type.systemGestures()
+                    )
+                )
+            info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION)
+            info.touchableRegion.set(touchableRegion)
+        }
         screenshotPreview = view.screenshotPreview
     }
 
@@ -194,6 +206,7 @@
             }
         )
     }
+
     private fun setOnKeyListener(onDismissRequested: (ScreenshotEvent) -> Unit) {
         view.setOnKeyListener(
             object : View.OnKeyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
index 747ad4f..b7a03ef 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/ScreenshotShelfView.kt
@@ -17,17 +17,70 @@
 package com.android.systemui.screenshot.ui
 
 import android.content.Context
+import android.graphics.Insets
+import android.graphics.Rect
+import android.graphics.Region
 import android.util.AttributeSet
+import android.view.View
 import android.widget.ImageView
 import androidx.constraintlayout.widget.ConstraintLayout
 import com.android.systemui.res.R
+import com.android.systemui.screenshot.FloatingWindowUtil
 
 class ScreenshotShelfView(context: Context, attrs: AttributeSet? = null) :
     ConstraintLayout(context, attrs) {
     lateinit var screenshotPreview: ImageView
 
+    private val displayMetrics = context.resources.displayMetrics
+    private val tmpRect = Rect()
+    private lateinit var actionsContainerBackground: View
+    private lateinit var dismissButton: View
+
     override fun onFinishInflate() {
         super.onFinishInflate()
         screenshotPreview = requireViewById(R.id.screenshot_preview)
+        actionsContainerBackground = requireViewById(R.id.actions_container_background)
+        dismissButton = requireViewById(R.id.screenshot_dismiss_button)
+    }
+
+    fun getTouchRegion(gestureInsets: Insets): Region {
+        val region = getSwipeRegion()
+
+        // Receive touches in gesture insets so they don't cause TOUCH_OUTSIDE
+        // left edge gesture region
+        val insetRect = Rect(0, 0, gestureInsets.left, displayMetrics.heightPixels)
+        region.op(insetRect, Region.Op.UNION)
+        // right edge gesture region
+        insetRect.set(
+            displayMetrics.widthPixels - gestureInsets.right,
+            0,
+            displayMetrics.widthPixels,
+            displayMetrics.heightPixels
+        )
+        region.op(insetRect, Region.Op.UNION)
+
+        return region
+    }
+
+    private fun getSwipeRegion(): Region {
+        val swipeRegion = Region()
+        val padding = FloatingWindowUtil.dpToPx(displayMetrics, -1 * TOUCH_PADDING_DP).toInt()
+        swipeRegion.addInsetView(screenshotPreview, padding)
+        swipeRegion.addInsetView(actionsContainerBackground, padding)
+        swipeRegion.addInsetView(dismissButton, padding)
+        findViewById<View>(R.id.screenshot_message_container)?.let {
+            swipeRegion.addInsetView(it, padding)
+        }
+        return swipeRegion
+    }
+
+    private fun Region.addInsetView(view: View, padding: Int = 0) {
+        view.getBoundsOnScreen(tmpRect)
+        tmpRect.inset(padding, padding)
+        this.op(tmpRect, Region.Op.UNION)
+    }
+
+    companion object {
+        private const val TOUCH_PADDING_DP = 12f
     }
 }