blob: f17da747d6f343fbcf43e080c5212bd351abba27 [file] [log] [blame]
package com.android.cts.intent.sender;
import static com.google.common.truth.Truth.assertWithMessage;
import android.app.UiAutomation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.os.UserHandle;
import android.provider.Settings;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.BySelector;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.test.InstrumentationTestCase;
import android.util.Log;
public class SuspendPackageTest extends InstrumentationTestCase {
private static final String TAG = "IntentSender.SuspendPackageTest";
private static final int WAIT_DIALOG_TIMEOUT_IN_MS = 5000;
private static final BySelector POPUP_TITLE_WATCH_SELECTOR = By
.clazz(android.widget.TextView.class.getName())
.res("android:id/alertTitle")
.pkg("com.google.android.apps.wearable.settings");
private static final BySelector POPUP_TITLE_AUTOMOTIVE_SELECTOR = By
.clazz(android.widget.TextView.class.getName())
.res("com.android.car.settings:id/car_ui_alert_title")
.pkg("com.android.car.settings");
private static final BySelector SUSPEND_BUTTON_SELECTOR = By
.clazz(android.widget.Button.class.getName())
.res("android:id/button1");
private IntentSenderActivity mActivity;
private Context mContext;
private PackageManager mPackageManager;
private UiAutomation mUiAutomation;
private static final String DEFAULT_SETTINGS_PKG = "com.android.settings";
private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
private static final String TARGET_ACTIVITY_NAME =
"com.android.cts.intent.receiver.SimpleIntentReceiverActivity";
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = getInstrumentation().getTargetContext();
String packageName = mContext.getPackageName();
int userId = mContext.getUserId();
Class<IntentSenderActivity> activityClass = IntentSenderActivity.class;
Log.d(TAG, "setup(): launching " + activityClass + " on user " + userId);
mActivity = launchActivity(packageName, activityClass, null);
assertWithMessage("activity %s launched on package %s on user %s",
activityClass, packageName, userId).that(mActivity).isNotNull();
Log.d(TAG, "setup(): launched activity " + mActivity);
mPackageManager = mContext.getPackageManager();
mUiAutomation = getInstrumentation().getUiAutomation();
}
@Override
public void tearDown() throws Exception {
if (mActivity != null) {
mActivity.finish();
}
super.tearDown();
}
public void testPackageSuspended() throws Exception {
assertPackageSuspended(/* suspended= */ true, /* customDialog= */ false);
}
public void testPackageNotSuspended() throws Exception {
assertPackageSuspended(/* suspended= */ false, /* customDialog= */ false);
}
public void testPackageSuspendedWithPackageManager() throws Exception {
assertPackageSuspended(/* suspended= */ true, /* customDialog= */ true);
}
/**
* Verify that the package is suspended by trying to start the activity inside it. If the
* package is not suspended, the target activity will return the result.
*/
private void assertPackageSuspended(boolean suspended, boolean customDialog) throws Exception {
Intent intent = new Intent();
intent.setClassName(INTENT_RECEIVER_PKG, TARGET_ACTIVITY_NAME);
Intent result = mActivity.getResult(intent);
Log.d(TAG, "assertPackageSuspended(suspended=" + suspended
+ ", customDialog=" + customDialog + "): result for activity "
+ INTENT_RECEIVER_PKG + "/" + TARGET_ACTIVITY_NAME + " on user "
+ mContext.getUserId() + ": " + result);
if (suspended) {
if (customDialog) {
dismissCustomDialog();
} else {
dismissPolicyTransparencyDialog();
}
assertWithMessage("result for activitiy %s while suspended", intent).that(result)
.isNull();
} else {
assertWithMessage("result for activitiy %s while NOT suspended", intent)
.that(result).isNotNull();
}
// No matter if it is suspended or not, we should be able to resolve the activity.
ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, /* flags= */ 0);
assertWithMessage("ResolveInfo for activity %s", intent).that(resolveInfo).isNotNull();
Log.d(TAG, "ResolveInfo: " + resolveInfo);
}
/**
* Wait for the policy transparency dialog and dismiss it.
*/
private void dismissPolicyTransparencyDialog() {
final UiDevice device = UiDevice.getInstance(getInstrumentation());
if (isWatch()) {
device.wait(Until.hasObject(POPUP_TITLE_WATCH_SELECTOR), WAIT_DIALOG_TIMEOUT_IN_MS);
final UiObject2 title = device.findObject(POPUP_TITLE_WATCH_SELECTOR);
assertWithMessage("Policy transparency dialog title").that(title).isNotNull();
title.swipe(Direction.RIGHT, 1.0f);
} else if (isAutomotive()) {
device.wait(Until.hasObject(POPUP_TITLE_AUTOMOTIVE_SELECTOR),
WAIT_DIALOG_TIMEOUT_IN_MS);
Log.d(TAG, "waiting for " + POPUP_TITLE_AUTOMOTIVE_SELECTOR);
final UiObject2 title = device.findObject(POPUP_TITLE_AUTOMOTIVE_SELECTOR);
assertWithMessage("Policy transparency dialog title").that(title).isNotNull();
// "OK" button only present in the dialog if it is blocked by policy.
BySelector selector = getPopUpButtonSelector();
Log.d(TAG, "waiting for " + selector);
final UiObject2 button = device.findObject(getPopUpButtonSelector());
assertWithMessage("OK button").that(button).isNotNull();
button.click();
} else {
device.wait(Until.hasObject(getPopUpImageSelector()), WAIT_DIALOG_TIMEOUT_IN_MS);
final UiObject2 icon = device.findObject(getPopUpImageSelector());
assertWithMessage("Policy transparency dialog icon").that(icon).isNotNull();
// "OK" button only present in the dialog if it is blocked by policy.
final UiObject2 button = device.findObject(getPopUpButtonSelector());
assertWithMessage("OK button").that(button).isNotNull();
button.click();
}
}
private void dismissCustomDialog() {
final UiDevice device = UiDevice.getInstance(getInstrumentation());
device.wait(Until.hasObject(SUSPEND_BUTTON_SELECTOR), WAIT_DIALOG_TIMEOUT_IN_MS);
final UiObject2 button = device.findObject(SUSPEND_BUTTON_SELECTOR);
assertWithMessage("OK button").that(button).isNotNull();
}
private boolean isWatch() {
return (getInstrumentation().getContext().getResources().getConfiguration().uiMode
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_WATCH;
}
private boolean isAutomotive() {
return mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
private String getSettingsPackageName() {
String settingsPackageName = "com.android.settings";
try {
mUiAutomation.adoptShellPermissionIdentity("android.permission.INTERACT_ACROSS_USERS");
ResolveInfo resolveInfo = mPackageManager.resolveActivityAsUser(
new Intent(Settings.ACTION_SETTINGS), PackageManager.MATCH_SYSTEM_ONLY,
UserHandle.USER_SYSTEM);
if (resolveInfo != null && resolveInfo.activityInfo != null) {
return resolveInfo.activityInfo.packageName;
}
Log.w(TAG, "Unable to resolve ACTION_SETTINGS intent.");
return DEFAULT_SETTINGS_PKG;
} finally {
mUiAutomation.dropShellPermissionIdentity();
}
}
private BySelector getPopUpButtonSelector() {
return By.clazz(android.widget.Button.class.getName())
.res("android:id/button1")
.pkg(getSettingsPackageName());
}
private BySelector getPopUpImageSelector() {
final String settingsPackageName = getSettingsPackageName();
return By.clazz(android.widget.ImageView.class.getName())
.res(settingsPackageName + ":id/admin_support_icon")
.pkg(settingsPackageName);
}
}