Intercept touches in the emulated DisplayCutout
Added a RegionInterceptingFrameLayout that can add the regions of its children to the touchable region of the inernal insets, and added DisplayCutoutView as a RegionInterceptableView child. Test: taps inside the DisplayCutout view do nothing Change-Id: I86120b39084da2b686d9954b4b16ea94efbd0f95 Fixes: 74946584
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
-->
|
||||
<FrameLayout
|
||||
<com.android.systemui.RegionInterceptingFrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
@@ -32,4 +32,4 @@
|
||||
android:tint="#ff000000"
|
||||
android:layout_gravity="right|bottom"
|
||||
android:src="@drawable/rounded" />
|
||||
</FrameLayout>
|
||||
</com.android.systemui.RegionInterceptingFrameLayout>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user