diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java index 8a925b9bad38c..ebe54187ddb6a 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackBroadcastReceiver.java @@ -62,6 +62,13 @@ class RollbackBroadcastReceiver extends BroadcastReceiver { return mRollbackBroadcasts.poll(timeout, unit); } + /** + * Waits forever for the next rollback broadcast. + */ + Intent take() throws InterruptedException { + return mRollbackBroadcasts.take(); + } + /** * Unregisters this broadcast receiver. */ diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java index 7505230e69c62..1c202e599f820 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import android.Manifest; -import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -46,8 +45,6 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.Collections; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; /** @@ -790,34 +787,14 @@ public class RollbackTest { rm.getAvailableRollbacks(), TEST_APP_B); assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollbackB); - BlockingQueue crashQueue = new SynchronousQueue<>(); + // Register rollback committed receiver + RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver(); - IntentFilter crashCountFilter = new IntentFilter(); - crashCountFilter.addAction("com.android.tests.rollback.CRASH"); - crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT); + // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback + crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5); - crashCountReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - try { - // Sleep long enough for packagewatchdog to be notified of crash - Thread.sleep(1000); - // Kill app and close AppErrorDialog - ActivityManager am = context.getSystemService(ActivityManager.class); - am.killBackgroundProcesses(TEST_APP_A); - // Allow another package launch - crashQueue.put(intent.getIntExtra("count", 0)); - } catch (InterruptedException e) { - fail("Failed to communicate with test app"); - } - } - }; - context.registerReceiver(crashCountReceiver, crashCountFilter); - - // Start apps PackageWatchdog#TRIGGER_FAILURE_COUNT times so TEST_APP_A crashes - do { - RollbackTestUtils.launchPackage(TEST_APP_A); - } while(crashQueue.take() < 5); + // Verify we received a broadcast for the rollback. + rollbackReceiver.take(); // TEST_APP_A is automatically rolled back by the RollbackPackageHealthObserver assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A)); diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java index 9aed0748266a0..81629aaaec762 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import android.app.ActivityManager; import android.app.AlarmManager; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -47,6 +48,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.SynchronousQueue; /** * Utilities to facilitate testing rollbacks. @@ -187,7 +189,7 @@ class RollbackTestUtils { } /** Launches {@code packageName} with {@link Intent#ACTION_MAIN}. */ - static void launchPackage(String packageName) + private static void launchPackage(String packageName) throws InterruptedException, IOException { Context context = InstrumentationRegistry.getContext(); Intent intent = new Intent(Intent.ACTION_MAIN); @@ -488,4 +490,39 @@ class RollbackTestUtils { } return null; } + + /** + * Send broadcast to crash {@code packageName} {@code count} times. If {@code count} is at least + * {@link PackageWatchdog#TRIGGER_FAILURE_COUNT}, watchdog crash detection will be triggered. + */ + static BroadcastReceiver sendCrashBroadcast(Context context, String packageName, int count) + throws InterruptedException, IOException { + BlockingQueue crashQueue = new SynchronousQueue<>(); + IntentFilter crashCountFilter = new IntentFilter(); + crashCountFilter.addAction("com.android.tests.rollback.CRASH"); + crashCountFilter.addCategory(Intent.CATEGORY_DEFAULT); + + BroadcastReceiver crashCountReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + try { + // Sleep long enough for packagewatchdog to be notified of crash + Thread.sleep(1000); + // Kill app and close AppErrorDialog + ActivityManager am = context.getSystemService(ActivityManager.class); + am.killBackgroundProcesses(packageName); + // Allow another package launch + crashQueue.put(intent.getIntExtra("count", 0)); + } catch (InterruptedException e) { + fail("Failed to communicate with test app"); + } + } + }; + context.registerReceiver(crashCountReceiver, crashCountFilter); + + do { + launchPackage(packageName); + } while(crashQueue.take() < count); + return crashCountReceiver; + } }