Merge "Cleaning up pm SuspendPackagesTest"

This commit is contained in:
TreeHugger Robot
2021-12-22 00:19:50 +00:00
committed by Android (Google) Code Review
3 changed files with 19 additions and 323 deletions

View File

@@ -1685,14 +1685,12 @@ public class LauncherAppsService extends SystemService {
continue;
}
final String[] filteredPackagesWithoutExtras =
getFilteredPackageNames(packages, cookie);
// If all packages are filtered, skip notifying listener.
if (ArrayUtils.isEmpty(filteredPackagesWithoutExtras)) {
continue;
}
getFilteredPackageNames(packagesNullExtras, cookie);
try {
listener.onPackagesSuspended(user, filteredPackagesWithoutExtras,
/* launcherExtras= */ null);
if (!ArrayUtils.isEmpty(filteredPackagesWithoutExtras)) {
listener.onPackagesSuspended(user, filteredPackagesWithoutExtras,
/* launcherExtras= */ null);
}
for (int idx = 0; idx < packagesWithExtras.size(); idx++) {
Pair<String, Bundle> packageExtraPair = packagesWithExtras.get(idx);
if (!isPackageVisibleToListener(packageExtraPair.first, cookie)) {

View File

@@ -97,6 +97,10 @@
<uses-permission
android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
<queries>
<package android:name="com.android.servicestests.apps.suspendtestapp" />
</queries>
<!-- Uses API introduced in O (26) -->
<uses-sdk android:minSdkVersion="1"
android:targetSdkVersion="26"/>

View File

@@ -25,23 +25,16 @@ import static android.app.AppOpsManager.opToName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.SuspendDialogInfo;
import android.content.res.Resources;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Handler;
@@ -50,13 +43,6 @@ import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;
import android.util.Log;
import android.view.IWindowManager;
import android.view.WindowManagerGlobal;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
@@ -65,7 +51,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.servicestests.apps.suspendtestapp.SuspendTestActivity;
import com.android.servicestests.apps.suspendtestapp.SuspendTestReceiver;
import org.junit.After;
@@ -76,7 +61,6 @@ import org.junit.runner.RunWith;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -84,8 +68,6 @@ import java.util.concurrent.atomic.AtomicReference;
@LargeTest
@FlakyTest
public class SuspendPackagesTest {
private static final String TAG = SuspendPackagesTest.class.getSimpleName();
private static final String TEST_APP_LABEL = "Suspend Test App";
private static final String TEST_APP_PACKAGE_NAME = SuspendTestReceiver.PACKAGE_NAME;
private static final String[] PACKAGES_TO_SUSPEND = new String[]{TEST_APP_PACKAGE_NAME};
@@ -105,75 +87,11 @@ public class SuspendPackagesTest {
public static final String EXTRA_RECEIVED_PACKAGE_NAME =
SuspendPackagesTest.INSTRUMENTATION_PACKAGE + ".extra.RECEIVED_PACKAGE_NAME";
private Context mContext;
private PackageManager mPackageManager;
private LauncherApps mLauncherApps;
private Handler mReceiverHandler;
private AppCommunicationReceiver mAppCommsReceiver;
private StubbedCallback mTestCallback;
private UiDevice mUiDevice;
private ComponentName mDeviceAdminComponent;
private boolean mPoSet;
private boolean mDoSet;
private static final class AppCommunicationReceiver extends BroadcastReceiver {
private Context context;
private boolean registered;
private SynchronousQueue<Intent> intentQueue = new SynchronousQueue<>();
AppCommunicationReceiver(Context context) {
this.context = context;
}
void register(Handler handler, String... actions) {
registered = true;
final IntentFilter intentFilter = new IntentFilter();
for (String action : actions) {
intentFilter.addAction(action);
}
context.registerReceiver(this, intentFilter, null, handler);
}
void unregister() {
if (registered) {
context.unregisterReceiver(this);
}
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "AppCommunicationReceiver#onReceive: " + intent.getAction());
try {
intentQueue.offer(intent, 5, TimeUnit.SECONDS);
} catch (InterruptedException ie) {
throw new RuntimeException("Receiver thread interrupted", ie);
}
}
Intent pollForIntent(long secondsToWait) {
if (!registered) {
throw new IllegalStateException("Receiver not registered");
}
final Intent intent;
try {
intent = intentQueue.poll(secondsToWait, TimeUnit.SECONDS);
} catch (InterruptedException ie) {
throw new RuntimeException("Interrupted while waiting for app broadcast", ie);
}
return intent;
}
void drainPendingBroadcasts() {
while (pollForIntent(5) != null) ;
}
Intent receiveIntentFromApp() {
final Intent intentReceived = pollForIntent(5);
assertNotNull("No intent received from app within 5 seconds", intentReceived);
return intentReceived;
}
}
@Before
public void setUp() {
@@ -181,9 +99,6 @@ public class SuspendPackagesTest {
mPackageManager = mContext.getPackageManager();
mLauncherApps = (LauncherApps) mContext.getSystemService(Context.LAUNCHER_APPS_SERVICE);
mReceiverHandler = new Handler(Looper.getMainLooper());
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mDeviceAdminComponent = new ComponentName(mContext,
"com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
IPackageManager ipm = AppGlobals.getPackageManager();
try {
// Otherwise implicit broadcasts will not be delivered.
@@ -192,31 +107,6 @@ public class SuspendPackagesTest {
e.rethrowAsRuntimeException();
}
unsuspendTestPackage();
mAppCommsReceiver = new AppCommunicationReceiver(mContext);
}
/**
* Care should be taken when used with {@link #mAppCommsReceiver} in the same test as both use
* the same handler.
*/
private Bundle requestAppAction(String action) throws InterruptedException {
final AtomicReference<Bundle> result = new AtomicReference<>();
final CountDownLatch receiverLatch = new CountDownLatch(1);
final ComponentName testReceiverComponent = new ComponentName(TEST_APP_PACKAGE_NAME,
SuspendTestReceiver.class.getCanonicalName());
final Intent broadcastIntent = new Intent(action)
.setComponent(testReceiverComponent)
.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendOrderedBroadcast(broadcastIntent, null, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
result.set(getResultExtras(true));
receiverLatch.countDown();
}
}, mReceiverHandler, 0, null, null);
assertTrue("Test receiver timed out ", receiverLatch.await(5, TimeUnit.SECONDS));
return result.get();
}
private PersistableBundle getExtras(String keyPrefix, long lval, String sval, double dval) {
@@ -240,14 +130,6 @@ public class SuspendPackagesTest {
assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
}
private void startTestAppActivity() {
final Intent testActivity = new Intent()
.setComponent(new ComponentName(TEST_APP_PACKAGE_NAME,
SuspendTestActivity.class.getCanonicalName()))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(testActivity);
}
private static boolean areSameExtras(BaseBundle expected, BaseBundle received) {
if (expected != null) {
expected.get(""); // hack to unparcel the bundles.
@@ -264,93 +146,6 @@ public class SuspendPackagesTest {
}
}
@Test
public void testIsPackageSuspended() throws Exception {
suspendTestPackage(null, null, null);
assertTrue("isPackageSuspended is false",
mPackageManager.isPackageSuspended(TEST_APP_PACKAGE_NAME));
}
@Test
public void testSuspendedStateFromApp() throws Exception {
Bundle resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
assertFalse(resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED, true));
assertNull(resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
final PersistableBundle appExtras = getExtras("testSuspendedStateFromApp", 20, "20", 0.2);
suspendTestPackage(appExtras, null, null);
resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
assertTrue("resultFromApp:suspended is false",
resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED));
final Bundle receivedAppExtras =
resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS);
assertSameExtras("Received app extras different to the ones supplied",
appExtras, receivedAppExtras);
}
@Test
public void testMyPackageSuspendedUnsuspended() {
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_SUSPENDED,
ACTION_REPORT_MY_PACKAGE_UNSUSPENDED);
mAppCommsReceiver.drainPendingBroadcasts();
final PersistableBundle appExtras = getExtras("testMyPackageSuspendBroadcasts", 1, "1", .1);
suspendTestPackage(appExtras, null, null);
Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
assertSameExtras("Received app extras different to the ones supplied", appExtras,
intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
unsuspendTestPackage();
intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("MY_PACKAGE_UNSUSPENDED delivery not reported",
ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
}
@Test
public void testUpdatingAppExtras() {
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_SUSPENDED);
final PersistableBundle extras1 = getExtras("testMyPackageSuspendedOnChangingExtras", 1,
"1", 0.1);
suspendTestPackage(extras1, null, null);
Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
assertSameExtras("Received app extras different to the ones supplied", extras1,
intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
final PersistableBundle extras2 = getExtras("testMyPackageSuspendedOnChangingExtras", 2,
"2", 0.2);
suspendTestPackage(extras2, null, null);
intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("MY_PACKAGE_SUSPENDED delivery not reported",
ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
assertSameExtras("Received app extras different to the updated extras", extras2,
intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
}
@Test
public void testCannotSuspendSelf() {
final String[] unchangedPkgs = mPackageManager.setPackagesSuspended(
new String[]{mContext.getOpPackageName()}, true, null, null,
(SuspendDialogInfo) null);
assertTrue(unchangedPkgs.length == 1);
assertEquals(mContext.getOpPackageName(), unchangedPkgs[0]);
}
@Test
public void testActivityStoppedOnSuspend() {
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_TEST_ACTIVITY_STARTED,
ACTION_REPORT_TEST_ACTIVITY_STOPPED);
startTestAppActivity();
Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("Test activity start not reported",
ACTION_REPORT_TEST_ACTIVITY_STARTED, intentFromApp.getAction());
suspendTestPackage(null, null, null);
intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals("Test activity stop not reported on suspending the test app",
ACTION_REPORT_TEST_ACTIVITY_STOPPED, intentFromApp.getAction());
}
@Test
public void testGetLauncherExtrasNonNull() {
final Bundle extrasWhenUnsuspended = mLauncherApps.getSuspendedPackageLauncherExtras(
@@ -383,14 +178,15 @@ public class SuspendPackagesTest {
public void testOnPackagesSuspendedNewAndOld() throws InterruptedException {
final PersistableBundle suppliedExtras = getExtras(
"testOnPackagesSuspendedNewAndOld", 2, "2", 0.2);
final AtomicReference<String> overridingBothCallbackResult = new AtomicReference<>("");
final CountDownLatch twoCallbackLatch = new CountDownLatch(2);
final AtomicReference<String> error = new AtomicReference<>("");
final CountDownLatch rightCallbackLatch = new CountDownLatch(1);
final CountDownLatch wrongCallbackLatch = new CountDownLatch(1);
mTestCallback = new StubbedCallback() {
@Override
public void onPackagesSuspended(String[] packageNames, UserHandle user) {
overridingBothCallbackResult.set(overridingBothCallbackResult.get()
error.set(error.get()
+ "Old callback called even when the new one is overriden. ");
twoCallbackLatch.countDown();
wrongCallbackLatch.countDown();
}
@Override
@@ -411,17 +207,16 @@ public class SuspendPackagesTest {
errorString.append("Unexpected launcherExtras, supplied: " + suppliedExtras
+ ", received: " + launcherExtras + ". ");
}
overridingBothCallbackResult.set(overridingBothCallbackResult.get()
error.set(error.get()
+ errorString.toString());
twoCallbackLatch.countDown();
rightCallbackLatch.countDown();
}
};
mLauncherApps.registerCallback(mTestCallback, mReceiverHandler);
suspendTestPackage(null, suppliedExtras, null);
assertFalse("Both callbacks were invoked", twoCallbackLatch.await(5, TimeUnit.SECONDS));
twoCallbackLatch.countDown();
assertTrue("No callback was invoked", twoCallbackLatch.await(2, TimeUnit.SECONDS));
final String result = overridingBothCallbackResult.get();
assertFalse("Wrong callback was invoked", wrongCallbackLatch.await(5, TimeUnit.SECONDS));
assertTrue("Right callback wasn't invoked", rightCallbackLatch.await(2, TimeUnit.SECONDS));
final String result = error.get();
assertTrue("Callbacks did not complete as expected: " + result, result.isEmpty());
}
@@ -457,103 +252,6 @@ public class SuspendPackagesTest {
assertTrue("Callback did not complete as expected: " + result, result.isEmpty());
}
private void turnScreenOn() throws Exception {
if (!mUiDevice.isScreenOn()) {
mUiDevice.wakeUp();
}
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
wm.dismissKeyguard(null, null);
}
@Test
public void testInterceptorActivity() throws Exception {
turnScreenOn();
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MORE_DETAILS_ACTIVITY_STARTED,
ACTION_REPORT_TEST_ACTIVITY_STARTED);
final String testMessage = "This is a test message to report suspension of %1$s";
suspendTestPackage(null, null,
new SuspendDialogInfo.Builder().setMessage(testMessage).build());
startTestAppActivity();
assertNull("No broadcast was expected from app", mAppCommsReceiver.pollForIntent(2));
assertNotNull("Given dialog message not shown", mUiDevice.wait(
Until.findObject(By.text(String.format(testMessage, TEST_APP_LABEL))), 5000));
final String buttonText = mContext.getResources().getString(Resources.getSystem()
.getIdentifier("app_suspended_more_details", "string", "android"));
final UiObject2 moreDetailsButton = mUiDevice.findObject(
By.clickable(true).text(buttonText));
assertNotNull(buttonText + " button not shown", moreDetailsButton);
moreDetailsButton.click();
final Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals(buttonText + " activity start not reported",
ACTION_REPORT_MORE_DETAILS_ACTIVITY_STARTED, intentFromApp.getAction());
final String receivedPackageName = intentFromApp.getStringExtra(
EXTRA_RECEIVED_PACKAGE_NAME);
assertEquals("Wrong package name received by " + buttonText + " activity",
TEST_APP_PACKAGE_NAME, receivedPackageName);
}
private boolean setProfileOwner() throws IOException {
final String result = mUiDevice.executeShellCommand("dpm set-profile-owner --user cur "
+ mDeviceAdminComponent.flattenToString());
return mPoSet = result.trim().startsWith("Success");
}
private boolean setDeviceOwner() throws IOException {
final String result = mUiDevice.executeShellCommand("dpm set-device-owner --user cur "
+ mDeviceAdminComponent.flattenToString());
return mDoSet = result.trim().startsWith("Success");
}
private void removeProfileOrDeviceOwner() throws IOException {
if (mPoSet || mDoSet) {
mUiDevice.executeShellCommand("dpm remove-active-admin --user cur "
+ mDeviceAdminComponent.flattenToString());
mPoSet = mDoSet = false;
}
}
@Test
public void testCanSuspendWhenProfileOwner() throws IOException {
assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
assertTrue("Profile-owner could not be set", setProfileOwner());
suspendTestPackage(null, null, null);
}
@Test
public void testCanSuspendWhenDeviceOwner() throws IOException {
assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
assertTrue("Device-owner could not be set", setDeviceOwner());
suspendTestPackage(null, null, null);
}
@Test
public void testPackageUnsuspendedOnAddingDeviceOwner() throws IOException {
assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
ACTION_REPORT_MY_PACKAGE_SUSPENDED);
mAppCommsReceiver.drainPendingBroadcasts();
suspendTestPackage(null, null, null);
Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
assertTrue("Device-owner could not be set", setDeviceOwner());
intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
}
@Test
public void testPackageUnsuspendedOnAddingProfileOwner() throws IOException {
assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
ACTION_REPORT_MY_PACKAGE_SUSPENDED);
mAppCommsReceiver.drainPendingBroadcasts();
suspendTestPackage(null, null, null);
Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
assertTrue("Profile-owner could not be set", setProfileOwner());
intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
}
@Test
public void testCameraBlockedOnSuspend() throws Exception {
assertOpBlockedOnSuspend(OP_CAMERA);
@@ -596,13 +294,9 @@ public class SuspendPackagesTest {
@After
public void tearDown() throws IOException {
mAppCommsReceiver.unregister();
if (mTestCallback != null) {
mLauncherApps.unregisterCallback(mTestCallback);
}
removeProfileOrDeviceOwner();
mContext.sendBroadcast(new Intent(ACTION_FINISH_TEST_ACTIVITY)
.setPackage(TEST_APP_PACKAGE_NAME));
}
private static abstract class StubbedCallback extends LauncherApps.Callback {