BugreportReceiverTest.java revision 2bfa0858a8cb67e19a1c9df8aad0a4da423a52b8
1e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme/* 2e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Copyright (C) 2015 The Android Open Source Project 3e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * 4e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 5e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * you may not use this file except in compliance with the License. 6e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * You may obtain a copy of the License at 7e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * 8e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * http://www.apache.org/licenses/LICENSE-2.0 9e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * 10e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Unless required by applicable law or agreed to in writing, software 11e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 12e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * See the License for the specific language governing permissions and 14e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * limitations under the License. 15e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 16e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 17e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemepackage com.android.shell; 18e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 19e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport static android.test.MoreAsserts.assertContainsRegex; 20e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport static com.android.shell.ActionSendMultipleConsumerActivity.UI_NAME; 21b9238b37838d653c38ce4e712421adb61978fc22Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT; 2269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_MAX; 2369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_NAME; 2469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_PID; 25b9238b37838d653c38ce4e712421adb61978fc22Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_SCREENSHOT; 2669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED; 2769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_STARTED; 28e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 29e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.BufferedOutputStream; 30e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.BufferedWriter; 31e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.ByteArrayOutputStream; 32e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.FileOutputStream; 33e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.IOException; 34e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.InputStream; 35e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.OutputStreamWriter; 36e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.Writer; 37e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.List; 38e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipEntry; 39e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipInputStream; 40e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipOutputStream; 41e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 42e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport libcore.io.Streams; 43ba477939f0ae38926b4b0a6501a2371acc612433Felipe Lemeimport android.app.ActivityManager; 44ba477939f0ae38926b4b0a6501a2371acc612433Felipe Lemeimport android.app.ActivityManager.RunningServiceInfo; 45e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.app.Instrumentation; 46e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.app.NotificationManager; 47e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.content.Context; 48e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.content.Intent; 49e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.net.Uri; 50e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.os.Bundle; 51e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.os.SystemProperties; 52e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.service.notification.StatusBarNotification; 53e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.support.test.uiautomator.UiDevice; 546bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Lemeimport android.support.test.uiautomator.UiObject; 55e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.test.InstrumentationTestCase; 562bfa0858a8cb67e19a1c9df8aad0a4da423a52b8Felipe Lemeimport android.test.suitebuilder.annotation.LargeTest; 57e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.util.Log; 58e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 59e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener; 60e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 61e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme/** 62e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Integration tests for {@link BugreportReceiver}. 63e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 64e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * These tests don't mock any component and rely on external UI components (like the notification 65e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * bar and activity chooser), which can make them unreliable and slow. 66e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 67e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * The general workflow is: 68e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <ul> 69e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>creates the bug report files 70e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>generates the BUGREPORT_FINISHED intent 71e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>emulate user actions to share the intent with a custom activity 72e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>asserts the extras received by the custom activity 73e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * </ul> 74e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 756bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme * <strong>NOTE</strong>: these tests only work if the device is unlocked. 76e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 772bfa0858a8cb67e19a1c9df8aad0a4da423a52b8Felipe Leme@LargeTest 78e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemepublic class BugreportReceiverTest extends InstrumentationTestCase { 79e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 80e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String TAG = "BugreportReceiverTest"; 81e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 82e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme // Timeout for UI operations, in milliseconds. 83e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final int TIMEOUT = 1000; 84e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 85e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ROOT_DIR = "/data/data/com.android.shell/files/bugreports"; 86e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String BUGREPORT_FILE = "test_bugreport.txt"; 87e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ZIP_FILE = "test_bugreport.zip"; 88e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String PLAIN_TEXT_PATH = ROOT_DIR + "/" + BUGREPORT_FILE; 89e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ZIP_PATH = ROOT_DIR + "/" + ZIP_FILE; 90e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String SCREENSHOT_PATH = ROOT_DIR + "/test_screenshot.png"; 91e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 92e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String BUGREPORT_CONTENT = "Dump, might as well dump!\n"; 93e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String SCREENSHOT_CONTENT = "A picture is worth a thousand words!\n"; 94e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 95e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private Context mContext; 96e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private UiBot mUiBot; 97e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private CustomActionSendMultipleListener mListener; 98e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 99e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme @Override 100e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme protected void setUp() throws Exception { 101e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Instrumentation instrumentation = getInstrumentation(); 102e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mContext = instrumentation.getTargetContext(); 103e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT); 104e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mListener = ActionSendMultipleConsumerActivity.getListener(mContext); 105e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme cancelExistingNotifications(); 1066bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_HIDE); 107e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 108e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 10969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme public void testFullWorkflow() throws Exception { 11069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme final String name = "BUG, Y U NO REPORT?"; 11169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // TODO: call method to remove property instead 112719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.progress", "0"); 113719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.max", "0"); 11469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 11569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Intent intent = new Intent(INTENT_BUGREPORT_STARTED); 11669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_PID, 42); 11769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_NAME, name); 11869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_MAX, 1000); 11969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mContext.sendBroadcast(intent); 12069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 12169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "0.00%"); 12269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 12369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme SystemProperties.set("dumpstate.42.progress", "108"); 12469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "10.80%"); 12569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 12669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme SystemProperties.set("dumpstate.42.progress", "500"); 12769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "50.00%"); 12869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 129719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.max", "2000"); 130719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme assertProgressNotification(name, "25.00%"); 131719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme 13269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 13369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 13469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Bundle extras = sendBugreportFinishedIntent(42, PLAIN_TEXT_PATH, SCREENSHOT_PATH); 13569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 13669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 137ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme String service = BugreportProgressService.class.getName(); 138ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme assertFalse("Service '" + service + "' is still running", isServiceRunning(service)); 13969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 14069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 1416bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme public void testBugreportFinished_withWarning() throws Exception { 1426bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Explicitly shows the warning. 1436bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_SHOW); 1446bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1456bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Send notification and click on share. 1466bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 1476bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme Intent intent = new Intent(INTENT_BUGREPORT_FINISHED); 1486bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme intent.putExtra(EXTRA_BUGREPORT, PLAIN_TEXT_PATH); 1496bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mContext.sendBroadcast(intent); 1506bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title)); 1516bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1526bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Handle the warning 1536bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm)); 1546bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // TODO: get ok and showMessageAgain from the dialog reference above 1556bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme UiObject showMessageAgain = 1566bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_repeat)); 1576bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.click(showMessageAgain, "show-message-again"); 1586bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme UiObject ok = mUiBot.getVisibleObject(mContext.getString(com.android.internal.R.string.ok)); 1596bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.click(ok, "ok"); 1606bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1616bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Share the bugreport. 1626bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.chooseActivity(UI_NAME); 1636bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme Bundle extras = mListener.getExtras(); 1646bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 1656bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1666bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Make sure it's hidden now. 1676bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme int newState = BugreportPrefs.getWarningState(mContext, BugreportPrefs.STATE_UNKNOWN); 1686bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme assertEquals("Didn't change state", BugreportPrefs.STATE_HIDE, newState); 1696bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme } 1706bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 171e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception { 172e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 173e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 174e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, SCREENSHOT_PATH); 175e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 176e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 177e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 178e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception { 179e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT); 180e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 181e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, SCREENSHOT_PATH); 182e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 183e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 184e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 185e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception { 186e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 187e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, null); 188e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 189e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 190e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 191e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception { 192e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT); 193e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, null); 194e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 195e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 196e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 197e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void cancelExistingNotifications() { 198e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme NotificationManager nm = NotificationManager.from(mContext); 199e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme for (StatusBarNotification notification : nm.getActiveNotifications()) { 200e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme int id = notification.getId(); 201e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.i(TAG, "Canceling existing notification (id=" + id + ")"); 202e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme nm.cancel(id); 203e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 204e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 205e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 20669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme private void assertProgressNotification(String name, String percent) { 20769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // TODO: it current looks for 3 distinct objects, without taking advantage of their 20869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // relationship. 20969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme String title = mContext.getString(R.string.bugreport_in_progress_title); 21069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Log.v(TAG, "Looking for progress notification title: '" + title+ "'"); 21169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getNotification(title); 21269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'"); 21369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getObject(name); 21469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getObject(percent); 21569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 21669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 217e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme /** 218e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Sends a "bugreport finished" intent and waits for the result. 219e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * 220e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * @return extras sent to the bugreport finished consumer. 221e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 222e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private Bundle sendBugreportFinishedIntent(String bugreportPath, String screenshotPath) { 22369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme return sendBugreportFinishedIntent(null, bugreportPath, screenshotPath); 22469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 22569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 22669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme private Bundle sendBugreportFinishedIntent(Integer pid, String bugreportPath, 22769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme String screenshotPath) { 22869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Intent intent = new Intent(INTENT_BUGREPORT_FINISHED); 22969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme if (pid != null) { 23069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_PID, pid); 23169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 232e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (bugreportPath != null) { 233e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme intent.putExtra(EXTRA_BUGREPORT, bugreportPath); 234e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 235e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (screenshotPath != null) { 236e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme intent.putExtra(EXTRA_SCREENSHOT, screenshotPath); 237e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 238e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 239e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mContext.sendBroadcast(intent); 240e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 241e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title)); 242e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot.chooseActivity(UI_NAME); 243e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme return mListener.getExtras(); 244e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 245e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 246e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme /** 247e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Asserts the proper ACTION_SEND_MULTIPLE intent was sent. 248e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 249e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertActionSendMultiple(Bundle extras, String bugreportContent, 250e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String screenshotContent) throws IOException { 251e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String body = extras.getString(Intent.EXTRA_TEXT); 252e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContainsRegex("missing build info", 253e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme SystemProperties.get("ro.build.description"), body); 254e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContainsRegex("missing serial number", 255e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme SystemProperties.get("ro.serialno"), body); 256e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 257e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong subject", ZIP_FILE, extras.getString(Intent.EXTRA_SUBJECT)); 258e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 259e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme List<Uri> attachments = extras.getParcelableArrayList(Intent.EXTRA_STREAM); 260e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme int expectedSize = screenshotContent != null ? 2 : 1; 261e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong number of attachments", expectedSize, attachments.size()); 262e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 263e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme // Need to interact through all attachments, since order is not guaranteed. 264e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Uri zipUri = null, screenshotUri = null; 265e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme for (Uri attachment : attachments) { 266e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (attachment.getPath().endsWith(".zip")) { 267e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zipUri = attachment; 268e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 269e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (attachment.getPath().endsWith(".png")) { 270e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme screenshotUri = attachment; 271e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 272e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 273e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNotNull("did not get .zip attachment", zipUri); 274e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertZipContent(zipUri, BUGREPORT_FILE, BUGREPORT_CONTENT); 275e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 276e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (screenshotContent != null) { 277e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNotNull("did not get .png attachment", screenshotUri); 278e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContent(screenshotUri, SCREENSHOT_CONTENT); 279e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } else { 280e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNull("should not have .png attachment", screenshotUri); 281e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 282e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 283e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 284e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertContent(Uri uri, String expectedContent) throws IOException { 285e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "assertContents(uri=" + uri); 286e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (InputStream is = mContext.getContentResolver().openInputStream(uri)) { 287e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String actualContent = new String(Streams.readFully(is)); 288e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong content for '" + uri + "'", expectedContent, actualContent); 289e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 290e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 291e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 292e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertZipContent(Uri uri, String entryName, String expectedContent) 293e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme throws IOException, IOException { 294e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "assertZipEntry(uri=" + uri + ", entryName=" + entryName); 295e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (ZipInputStream zis = new ZipInputStream(mContext.getContentResolver().openInputStream( 296e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme uri))) { 297e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ZipEntry entry; 298e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme while ((entry = zis.getNextEntry()) != null) { 299e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "Zip entry: " + entry.getName()); 300e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (entry.getName().equals(entryName)) { 301e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ByteArrayOutputStream bos = new ByteArrayOutputStream(); 302e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Streams.copy(zis, bos); 303e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String actualContent = new String(bos.toByteArray(), "UTF-8"); 304e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme bos.close(); 305e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong content for zip entry'" + entryName + "' on '" + uri + "'", 306e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme expectedContent, actualContent); 307e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme return; 308e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 309e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 310e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 311e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme fail("Did not find entry '" + entryName + "' on file '" + uri + "'"); 312e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 313e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 314ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme private boolean isServiceRunning(String name) { 315ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme ActivityManager manager = (ActivityManager) mContext 316ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme .getSystemService(Context.ACTIVITY_SERVICE); 317ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 318ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme if (service.service.getClassName().equals(name)) { 319ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme return true; 320ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 321ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 322ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme return false; 323ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 324ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme 325e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static void createTextFile(String path, String content) throws IOException { 326e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "createFile(" + path + ")"); 327e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (Writer writer = new BufferedWriter(new OutputStreamWriter( 328e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme new FileOutputStream(path)))) { 329e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme writer.write(content); 330e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 331e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 332e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 333e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void createZipFile(String path, String entryName, String content) throws IOException { 334e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "createZipFile(" + path + ", " + entryName + ")"); 335e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (ZipOutputStream zos = new ZipOutputStream( 336e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme new BufferedOutputStream(new FileOutputStream(path)))) { 337e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ZipEntry entry = new ZipEntry(entryName); 338e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.putNextEntry(entry); 339e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme byte[] data = content.getBytes(); 340e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.write(data, 0, data.length); 341e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.closeEntry(); 342e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 343e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 344e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme} 345