1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.security.cts.cve_2021_0586;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.pm.PackageManager;
22 import android.net.Uri;
23 import androidx.test.runner.AndroidJUnit4;
24 import androidx.test.uiautomator.By;
25 import androidx.test.uiautomator.BySelector;
26 import androidx.test.uiautomator.UiDevice;
27 import androidx.test.uiautomator.Until;
28 import java.io.IOException;
29 import java.util.regex.Pattern;
30 import org.junit.Before;
31 import org.junit.runner.RunWith;
32 import org.junit.Test;
33 
34 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
35 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
36 import static org.junit.Assert.assertNotNull;
37 
38 @RunWith(AndroidJUnit4.class)
39 public class DeviceTest {
40     private static final String TEST_PKG = "android.security.cts.cve_2021_0586";
41     private static final String TEST_PKG_BT = "com.android.settings";
42     private static final int LAUNCH_TIMEOUT_MS = 20000;
43     private UiDevice mDevice;
44     String activityDump = "";
45 
startDevicePickerActivity()46     public void startDevicePickerActivity() {
47         Context context = getApplicationContext();
48         Intent sharingIntent = new Intent(Intent.ACTION_SEND);
49         assertNotNull(sharingIntent);
50         sharingIntent.setType("image/*");
51         sharingIntent.setPackage("com.android.bluetooth");
52         Uri uri = Uri.parse("android.resource://android.security.cts.CVE_2021_0586"
53                 + "/drawable/cve_2021_0586.png");
54         assertNotNull(uri);
55         sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
56         Intent intent = Intent.createChooser(sharingIntent, "Share image");
57         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
58         context.startActivity(intent);
59     }
60 
61     @Before
startMainActivityFromHomeScreen()62     public void startMainActivityFromHomeScreen() {
63         mDevice = UiDevice.getInstance(getInstrumentation());
64         Context context = getApplicationContext();
65         assertNotNull(context);
66         PackageManager packageManager = context.getPackageManager();
67         assertNotNull(packageManager);
68         final Intent intent = packageManager.getLaunchIntentForPackage(TEST_PKG);
69         assertNotNull(intent);
70         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
71         /* Start the launcher activity */
72         context.startActivity(intent);
73         Pattern pattern = Pattern.compile(
74                 getApplicationContext().getResources().getString(R.string.overlay_button),
75                 Pattern.CASE_INSENSITIVE);
76         /* Wait for the overlay window */
77         if (!mDevice.wait(Until.hasObject(By.text(pattern).depth(0)), LAUNCH_TIMEOUT_MS)) {
78             return;
79         }
80         /* Start the DevicePickerActivity */
81         startDevicePickerActivity();
82     }
83 
84     @Test
testOverlayButtonPresence()85     public void testOverlayButtonPresence() {
86         BySelector selector = By.pkg(TEST_PKG_BT);
87         /* Wait for an object of DevicePickerActivity */
88         if (mDevice.wait(Until.hasObject(selector.depth(0)), LAUNCH_TIMEOUT_MS)) {
89             return;
90         }
91         /* Check if the currently running activity is DevicePickerActivity */
92         try {
93             activityDump = mDevice.executeShellCommand("dumpsys activity");
94         } catch (IOException e) {
95             throw new RuntimeException("Could not execute dumpsys activity command");
96         }
97         Pattern activityPattern = Pattern.compile("mResumedActivity.*DevicePickerActivity.*\n");
98         if (!activityPattern.matcher(activityDump).find()) {
99             return;
100         }
101         String message = "Device is vulnerable to b/182584940 hence any app with "
102                 + "SYSTEM_ALERT_WINDOW can overlay the Bluetooth DevicePickerActivity screen";
103         assertNotNull(message, mDevice.findObject(selector));
104     }
105 }
106