Create button which ignores clicks when window is partially obscured

Currently there is a protection to prevent clicks which go through an
overlay, but the overlay might be covering sensitive information rather
than the button. We now prevent clicks if there is any overlay over any part
of the window.

Test: Manual
Test: atest PermissionTapjackingTest
Bug: 175190844

Change-Id: Ie0238aede5fb1d781e71c3c6f30b63dd02a1eb2c
diff --git a/PermissionController/res/layout/grant_permissions.xml b/PermissionController/res/layout/grant_permissions.xml
index 82e2d58..1db5611 100644
--- a/PermissionController/res/layout/grant_permissions.xml
+++ b/PermissionController/res/layout/grant_permissions.xml
@@ -95,47 +95,47 @@
                 <Space
                     style="@style/PermissionGrantButtonBarSpace"/>
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_allow_button"
                     android:text="@string/grant_dialog_button_allow"
                     style="@style/PermissionGrantButtonAllow" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_allow_foreground_only_button"
                     android:text="@string/grant_dialog_button_allow_foreground"
                     style="@style/PermissionGrantButtonAllowForeground" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_allow_one_time_button"
                     android:text="@string/grant_dialog_button_allow_one_time"
                     style="@style/PermissionGrantButtonAllowOneTime" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_deny_button"
                     android:text="@string/grant_dialog_button_deny"
                     style="@style/PermissionGrantButtonDeny" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_deny_and_dont_ask_again_button"
                     android:text="@string/grant_dialog_button_deny"
                     style="@style/PermissionGrantButtonDeny" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_no_upgrade_button"
                     android:text="@string/grant_dialog_button_no_upgrade"
                     style="@style/PermissionGrantButtonNoUpgrade" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_no_upgrade_and_dont_ask_again_button"
                     android:text="@string/grant_dialog_button_no_upgrade"
                     style="@style/PermissionGrantButtonNoUpgrade" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_no_upgrade_one_time_button"
                     android:text="@string/grant_dialog_button_no_upgrade_one_time"
                     style="@style/PermissionGrantButtonNoUpgrade" />
 
-                <Button
+                <com.android.permissioncontroller.permission.ui.widget.SecureButton
                     android:id="@+id/permission_no_upgrade_one_time_and_dont_ask_again_button"
                     android:text="@string/grant_dialog_button_no_upgrade_one_time"
                     style="@style/PermissionGrantButtonNoUpgrade" />
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/widget/SecureButton.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/widget/SecureButton.java
new file mode 100644
index 0000000..20025d0
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/widget/SecureButton.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.permissioncontroller.permission.ui.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.Button;
+
+/**
+ * A button which doesn't allow clicking when any part of the window is obscured
+ */
+public class SecureButton extends Button {
+
+    private static final int FLAGS_WINDOW_IS_OBSCURED =
+            MotionEvent.FLAG_WINDOW_IS_OBSCURED | MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
+
+    public SecureButton(Context context) {
+        super(context);
+    }
+
+    public SecureButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public SecureButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public SecureButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public boolean onFilterTouchEventForSecurity(MotionEvent event) {
+        return (event.getFlags() & FLAGS_WINDOW_IS_OBSCURED) == 0
+                && super.onFilterTouchEventForSecurity(event);
+    }
+}