diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml index 734c877d78299..26cf7920c35bd 100644 --- a/packages/SystemUI/res/layout/rounded_corners.xml +++ b/packages/SystemUI/res/layout/rounded_corners.xml @@ -14,7 +14,7 @@ ** See the License for the specific language governing permissions and ** limitations under the License. --> - @@ -32,4 +32,4 @@ android:tint="#ff000000" android:layout_gravity="right|bottom" android:src="@drawable/rounded" /> - + diff --git a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java new file mode 100644 index 0000000000000..646f69eede942 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 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. + */ + +package com.android.systemui; + +import android.content.Context; +import android.graphics.Region; +import android.graphics.Region.Op; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.InternalInsetsInfo; +import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; +import android.widget.FrameLayout; + +/** + * Frame layout that will intercept the touches of children if they want to + */ +public class RegionInterceptingFrameLayout extends FrameLayout { + public RegionInterceptingFrameLayout(Context context) { + super(context); + } + + public RegionInterceptingFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public RegionInterceptingFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public RegionInterceptingFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener); + } + + private final OnComputeInternalInsetsListener mInsetsListener = internalInsetsInfo -> { + internalInsetsInfo.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION); + internalInsetsInfo.touchableRegion.setEmpty(); + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + if (!(child instanceof RegionInterceptableView)) { + continue; + } + RegionInterceptableView riv = (RegionInterceptableView) child; + if (!riv.shouldInterceptTouch()) { + continue; + } + Region unionRegion = riv.getInterceptRegion(); + if (unionRegion == null) { + continue; + } + + internalInsetsInfo.touchableRegion.op(riv.getInterceptRegion(), Op.UNION); + } + }; + + public interface RegionInterceptableView { + default public boolean shouldInterceptTouch() { + return false; + } + + public Region getInterceptRegion(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index ec2390fbcfc63..f7ecabf9e15d1 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -48,6 +48,7 @@ import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; +import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.plugins.qs.QS; @@ -229,8 +230,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { ViewGroup.LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH | WindowManager.LayoutParams.FLAG_SLIPPERY @@ -309,7 +309,8 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } - public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener { + public static class DisplayCutoutView extends View implements DisplayManager.DisplayListener, + RegionInterceptableView { private final DisplayInfo mInfo = new DisplayInfo(); private final Paint mPaint = new Paint(); @@ -459,5 +460,19 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } } + + @Override + public boolean shouldInterceptTouch() { + return mInfo.displayCutout != null && getVisibility() == VISIBLE; + } + + @Override + public Region getInterceptRegion() { + if (mInfo.displayCutout == null) { + return null; + } + + return mInfo.displayCutout.getBounds(); + } } }