blob: 891bd181084c42b8f6e3e877e5e0768da6c4bc43 [file] [log] [blame]
/*
* 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 android.security.cts.CVE_2021_0481;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.SystemClock;
import android.util.Log;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import androidx.test.filters.SdkSuppress;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
import androidx.test.uiautomator.BySelector;
import java.util.List;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeNoException;
/**
* launch "Settings" app
* set up user photo
*/
@RunWith(AndroidJUnit4.class)
public class DeviceTest {
class ClickableNotFound extends Exception{
public ClickableNotFound(String s){
super(s);
}
}
private static final String BASIC_SAMPLE_PACKAGE
= "android.security.cts.CVE_2021_0481";
private static final int LAUNCH_TIMEOUT_MS = 20000;
private static final String TAG = "TAG_2021_0481";
private static final int IS_FOUND_FLAG = 1; // 0001
private static final int IS_CHECKED_FLAG = 2; // 0010
private UiDevice mDevice;
@Test
public void testUserPhotoSetUp() {
//set mDevice and go to homescreen
mDevice = UiDevice.getInstance(getInstrumentation());
mDevice.pressHome();
//start "Settings" app
Intent myIntent = new Intent("android.settings.USER_SETTINGS");
//android.provider.Settings.ACTION_USER_SETTINGS
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try{
getApplicationContext().startActivity(myIntent);
} catch(android.content.ActivityNotFoundException e){
Log.d(TAG, "Activity to be tested doesn't exist. Test will pass.");
return;
}
//wait for "User Settings" activity to appear.
SystemClock.sleep(6000);
//perform UI test steps
try {
//in "Multiple users" activity showing "Use multiple users" switch
searchAndClick(mDevice, "android:id/switch_widget", 2000);
//in "Multiple users" activity showing a list of current users,
//look for the first item "android:id/title" on the list showing "You(Owner)"
searchAndClick(mDevice, "android:id/title", 2000);
//in "Profile Info" dialog window showing clickable user silhouette
//look for clickable android.widget.ImageView object with attributes:
// getContentDescription()=Select photo
// getResourceName()=com.android.settings:id/user_photo
searchAndClick(mDevice, "com.android.settings:id/user_photo", 2000);
//in unnamed subdialog showing two options: "Take a photo" "Choose an image"
searchAndClick(mDevice, "Choose an image", 6000);
//in "Browse Files in Other Apps" activity
searchAndClick(mDevice, "android.security.cts.CVE_2021_0481.EvilActivity", 5000);
//Image is chosen as (evilActivity) so we are getting back to
//"Profile Info" dialog window showing clickable user silhouette
//end "Cancel" and "OK" buttons.
//look for "Cancel button and click it"
searchAndClick(mDevice, "Cancel", 2000);
} catch (ClickableNotFound e){
Log.d(TAG, e.toString());
assumeNoException(e);
}
Log.d(TAG, "end of testUserPhotoSetUp()");
}
//see what is on screen and click on object containing name
//throw exception if object not found
private void searchAndClick(UiDevice mDevice, String name, int timeOut) throws ClickableNotFound {
int ret;
List<UiObject2> objects = mDevice.findObjects(By.clickable(true));
boolean found = false;
Log.d(TAG, "looking for " + name);
Log.d(TAG, "found " + String.valueOf(objects!=null ? objects.size() : 0) + " clickables");
if(objects != null){
for (UiObject2 o : objects) {
if((ret=searchAndLog(o, name, "")) !=0 )
{
found=true;
Log.d(TAG, name + " found");
if((ret & IS_CHECKED_FLAG) == 0) {
o.click();
Log.d(TAG, name + " clicked");
SystemClock.sleep(timeOut); //wait for click result to appear onscreen
}
break; //to avoid androidx.test.uiautomator.StaleObjectException
}
}
}
if(!found) {
throw new ClickableNotFound("\"" + name + "\" not found to click on");
}
}
//Search for 'name' in UiObject2
//returns int flags showing search result:
// IS_CHECKED_FLAG - 'name' matches o.getResourceName() and o.isSelected()==true
// IS_FOUND_FLAG - 'name' matches anything else
private int searchAndLog(UiObject2 o, String name, String prefix){
int ret = 0;
String lname = o.getText();
String cname = o.getClassName();
String cdesc = o.getContentDescription();
String rname = o.getResourceName();
boolean checked = o.isChecked();
Log.d(TAG, prefix + "class=" + cname);
Log.d(TAG, prefix + "o.getText()=" + lname);
Log.d(TAG, prefix + "o.getContentDescription()=" + cdesc);
Log.d(TAG, prefix + "o.getResourceName()=" + rname);
Log.d(TAG, prefix + "o.getChildCount()=" + o.getChildCount());
if( rname != null && rname.equals(name) && checked) {
ret |= IS_CHECKED_FLAG;
}
else if(lname != null && lname.equals(name) || cdesc != null && cdesc.equals(name) || rname != null && rname.equals(name) ) {
ret |= IS_FOUND_FLAG;
}
if(ret != 0) {
Log.d(TAG, prefix + "found-->" + name);
return ret;
} else {
java.util.List<UiObject2> objects2 = o.getChildren();
if(objects2 != null && objects2.size() > 0 && prefix.length() < 50) {
for (UiObject2 o2 : objects2) {
if((ret=searchAndLog(o2, name, prefix + "__")) != 0){
return ret;
}
}
}
}
return ret;
}
}