RESTRICT AUTOMERGE

Add test for tapjacking permission grant dialog

Test: cts-tradefed run cts -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.PermissionsHostTest#testTapjackingGrantDialog
Bug: 155287782
Change-Id: I329a77f8960999f4f5f60d734649dff0675784f2
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
index d0cc258..87a2057 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -43,6 +43,7 @@
     private static final String APK_28 = "CtsUsePermissionApp28.apk";
     private static final String APK_29 = "CtsUsePermissionApp29.apk";
     private static final String APK_Latest = "CtsUsePermissionAppLatest.apk";
+    private static final String APK_OVERLAY = "CtsUsePermissionAppWithOverlay.apk";
 
     private static final String APK_PERMISSION_POLICY_25 = "CtsPermissionPolicyTest25.apk";
     private static final String PERMISSION_POLICY_25_PKG = "com.android.cts.permission.policy";
@@ -526,6 +527,14 @@
                 "reviewPermissionWhenServiceIsBound");
     }
 
+    public void testTapjackingGrantDialog() throws Exception {
+        assertNull(getDevice().installPackage(mBuildHelper.getTestFile(APK_OVERLAY), false,
+                false));
+
+        runDeviceTests(USES_PERMISSION_PKG, "com.android.cts.usepermission.TapjackingTest",
+                "testTapjackingGrantDialog");
+    }
+
     private void runDeviceTests(String packageName, String testClassName, String testMethodName)
             throws DeviceNotAvailableException {
         Utils.runDeviceTestsAsCurrentUser(getDevice(), packageName, testClassName, testMethodName);
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/Android.mk
new file mode 100644
index 0000000..28242bf
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/Android.mk
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+	androidx.test.rules \
+	compatibility-device-util-axt \
+	ctstestrunner-axt \
+	ub-uiautomator
+
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+	../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java \
+	../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java \
+	../UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+
+LOCAL_PACKAGE_NAME := CtsUsePermissionAppWithOverlay
+
+# For ACCESS_BACKGROUND_LOCATION
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+LOCAL_MIN_SDK_VERSION := 22
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..217ca0c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  ~ Copyright (C) 2020 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.
+  -->
+
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.usepermission">
+
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <application>
+        <activity android:name=".UsePermissionWithOverlay" android:exported="true" />
+        <activity android:name=".OverlayActivity"
+                  android:theme="@style/OverlayTheme" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.usepermission" />
+</manifest>
+
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/drawable/border.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/drawable/border.xml
new file mode 100644
index 0000000..abec030
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/drawable/border.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2020 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.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <corners
+        android:radius="4dp"/>
+    <stroke
+        android:width="4dp"
+        android:color="@android:color/black" />
+</shape>
+
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
new file mode 100644
index 0000000..fb5bd59
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/layout/overlay_activity.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2020 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@drawable/border"
+              android:padding="8dp" >
+
+    <View android:layout_width="match_parent"
+          android:layout_height="0dp"
+          android:layout_weight="1" />
+
+    <TextView android:id="@+id/overlay_description"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:textColor="@android:color/black"
+              android:text="@string/app_description" />
+</LinearLayout>
+
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/strings.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/strings.xml
new file mode 100644
index 0000000..8b5362d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2020 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.
+-->
+<resources>
+    <string name="app_description">This activity attempts to tapjack the activity below.\nAny security sensitive controls below should not respond to taps as long as this activity is visible.</string>
+    <string name="Permissions">Permissions</string>
+    <string name="Deny">Deny</string>
+    <string name="Allow">Allow</string>
+    <string name="AllowAll">Allow all the time</string>
+</resources>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/styles.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/styles.xml
new file mode 100644
index 0000000..85ad792
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/res/values/styles.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2020 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.
+-->
+<resources>
+    <style name="OverlayTheme" parent="android:Theme.Dialog">
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+</resources>
+
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/OverlayActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/OverlayActivity.java
new file mode 100644
index 0000000..94e85e7
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/OverlayActivity.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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.cts.usepermission;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class OverlayActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.overlay_activity);
+
+        WindowManager.LayoutParams params = getWindow().getAttributes();
+
+        params.flags = (WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
+                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
+                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
+                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/TapjackingTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/TapjackingTest.java
new file mode 100644
index 0000000..ddb652b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/TapjackingTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2020 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.cts.usepermission;
+
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Until;
+
+import com.android.compatibility.common.util.ThrowingRunnable;
+
+import org.junit.Test;
+
+public class TapjackingTest extends BasePermissionsTest {
+
+
+    private static final String APP_PACKAGE_NAME = "com.android.cts.usepermission";
+    private final Context mContext = getInstrumentation().getContext();
+
+    @Test
+    public void testTapjackingGrantDialog() throws Exception {
+        assertEquals(PackageManager.PERMISSION_DENIED,
+                mContext.checkPermission(ACCESS_FINE_LOCATION, Process.myPid(), Process.myUid()));
+
+        requestPermissions(new String[]{ACCESS_FINE_LOCATION}, 0, UsePermissionWithOverlay.class,
+                () -> {
+                    // Wait for overlay to hide the dialog
+                    getUiDevice().wait(Until.findObject(By.res(
+                            "com.android.cts.usepermission:id/overlay_description")),
+                            10000).click();
+                    try {
+                        // Try to grant the permission, this should fail
+                        eventually(() -> {
+                            if (mContext.getPackageManager().checkPermission(ACCESS_FINE_LOCATION,
+                                    APP_PACKAGE_NAME) == PackageManager.PERMISSION_DENIED) {
+                                clickAllowForegroundButton();
+                            }
+                            assertEquals(PackageManager.PERMISSION_GRANTED,
+                                    mContext.checkPermission(ACCESS_FINE_LOCATION,
+                                            Process.myPid(), Process.myUid()));
+                        }, 10000);
+                    } catch (RuntimeException e) {
+                        // expected
+                    }
+                });
+
+        assertEquals(PackageManager.PERMISSION_DENIED,
+                mContext.checkPermission(ACCESS_FINE_LOCATION, Process.myPid(), Process.myUid()));
+    }
+
+    /**
+     * Make sure that a {@link Runnable} eventually finishes without throwing a {@link
+     * Exception}.
+     *
+     * @param r The {@link Runnable} to run.
+     * @param r The number of milliseconds to wait for r to not throw
+     */
+    public static void eventually(ThrowingRunnable r, long timeoutMillis) {
+        long start = System.currentTimeMillis();
+
+        while (true) {
+            try {
+                r.run();
+                return;
+            } catch (Throwable e) {
+                if (System.currentTimeMillis() - start < timeoutMillis) {
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException ignored) {
+                        throw new RuntimeException(e);
+                    }
+                } else {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/UsePermissionWithOverlay.java b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/UsePermissionWithOverlay.java
new file mode 100644
index 0000000..1a5ab22
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppWithOverlay/src/com/android/cts/usepermission/UsePermissionWithOverlay.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 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.cts.usepermission;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+public class UsePermissionWithOverlay extends BasePermissionActivity {
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        startActivity(new Intent(this, OverlayActivity.class));
+    }
+}