BugreportReceiverTest.java revision ba477939f0ae38926b4b0a6501a2371acc612433
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; 56e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.util.Log; 57e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 58e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener; 59e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 60e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme/** 61e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Integration tests for {@link BugreportReceiver}. 62e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 63e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * These tests don't mock any component and rely on external UI components (like the notification 64e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * bar and activity chooser), which can make them unreliable and slow. 65e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 66e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * The general workflow is: 67e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <ul> 68e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>creates the bug report files 69e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>generates the BUGREPORT_FINISHED intent 70e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>emulate user actions to share the intent with a custom activity 71e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>asserts the extras received by the custom activity 72e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * </ul> 73e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p> 746bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme * <strong>NOTE</strong>: these tests only work if the device is unlocked. 75e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 76e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemepublic class BugreportReceiverTest extends InstrumentationTestCase { 77e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 78e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String TAG = "BugreportReceiverTest"; 79e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 80e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme // Timeout for UI operations, in milliseconds. 81e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final int TIMEOUT = 1000; 82e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 83e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ROOT_DIR = "/data/data/com.android.shell/files/bugreports"; 84e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String BUGREPORT_FILE = "test_bugreport.txt"; 85e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ZIP_FILE = "test_bugreport.zip"; 86e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String PLAIN_TEXT_PATH = ROOT_DIR + "/" + BUGREPORT_FILE; 87e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String ZIP_PATH = ROOT_DIR + "/" + ZIP_FILE; 88e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String SCREENSHOT_PATH = ROOT_DIR + "/test_screenshot.png"; 89e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 90e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String BUGREPORT_CONTENT = "Dump, might as well dump!\n"; 91e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static final String SCREENSHOT_CONTENT = "A picture is worth a thousand words!\n"; 92e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 93e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private Context mContext; 94e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private UiBot mUiBot; 95e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private CustomActionSendMultipleListener mListener; 96e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 97e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme @Override 98e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme protected void setUp() throws Exception { 99e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Instrumentation instrumentation = getInstrumentation(); 100e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mContext = instrumentation.getTargetContext(); 101e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT); 102e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mListener = ActionSendMultipleConsumerActivity.getListener(mContext); 103e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme cancelExistingNotifications(); 1046bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_HIDE); 105e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 106e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 10769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme public void testFullWorkflow() throws Exception { 10869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme final String name = "BUG, Y U NO REPORT?"; 10969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // TODO: call method to remove property instead 110719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.progress", "0"); 111719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.max", "0"); 11269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 11369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Intent intent = new Intent(INTENT_BUGREPORT_STARTED); 11469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_PID, 42); 11569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_NAME, name); 11669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_MAX, 1000); 11769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mContext.sendBroadcast(intent); 11869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 11969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "0.00%"); 12069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 12169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme SystemProperties.set("dumpstate.42.progress", "108"); 12269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "10.80%"); 12369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 12469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme SystemProperties.set("dumpstate.42.progress", "500"); 12569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertProgressNotification(name, "50.00%"); 12669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 127719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme SystemProperties.set("dumpstate.42.max", "2000"); 128719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme assertProgressNotification(name, "25.00%"); 129719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme 13069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 13169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 13269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Bundle extras = sendBugreportFinishedIntent(42, PLAIN_TEXT_PATH, SCREENSHOT_PATH); 13369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 13469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 135ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme String service = BugreportProgressService.class.getName(); 136ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme assertFalse("Service '" + service + "' is still running", isServiceRunning(service)); 13769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 13869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 1396bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme public void testBugreportFinished_withWarning() throws Exception { 1406bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Explicitly shows the warning. 1416bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_SHOW); 1426bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1436bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Send notification and click on share. 1446bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 1456bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme Intent intent = new Intent(INTENT_BUGREPORT_FINISHED); 1466bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme intent.putExtra(EXTRA_BUGREPORT, PLAIN_TEXT_PATH); 1476bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mContext.sendBroadcast(intent); 1486bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title)); 1496bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1506bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Handle the warning 1516bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm)); 1526bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // TODO: get ok and showMessageAgain from the dialog reference above 1536bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme UiObject showMessageAgain = 1546bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_repeat)); 1556bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.click(showMessageAgain, "show-message-again"); 1566bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme UiObject ok = mUiBot.getVisibleObject(mContext.getString(com.android.internal.R.string.ok)); 1576bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.click(ok, "ok"); 1586bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1596bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Share the bugreport. 1606bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme mUiBot.chooseActivity(UI_NAME); 1616bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme Bundle extras = mListener.getExtras(); 1626bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 1636bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 1646bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme // Make sure it's hidden now. 1656bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme int newState = BugreportPrefs.getWarningState(mContext, BugreportPrefs.STATE_UNKNOWN); 1666bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme assertEquals("Didn't change state", BugreportPrefs.STATE_HIDE, newState); 1676bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme } 1686bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme 169e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception { 170e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 171e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 172e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, SCREENSHOT_PATH); 173e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 174e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 175e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 176e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception { 177e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT); 178e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(SCREENSHOT_PATH, SCREENSHOT_CONTENT); 179e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, SCREENSHOT_PATH); 180e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT); 181e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 182e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 183e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception { 184e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createTextFile(PLAIN_TEXT_PATH, BUGREPORT_CONTENT); 185e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(PLAIN_TEXT_PATH, null); 186e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 187e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 188e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 189e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception { 190e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme createZipFile(ZIP_PATH, BUGREPORT_FILE, BUGREPORT_CONTENT); 191e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Bundle extras = sendBugreportFinishedIntent(ZIP_PATH, null); 192e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertActionSendMultiple(extras, BUGREPORT_CONTENT, null); 193e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 194e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 195e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void cancelExistingNotifications() { 196e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme NotificationManager nm = NotificationManager.from(mContext); 197e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme for (StatusBarNotification notification : nm.getActiveNotifications()) { 198e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme int id = notification.getId(); 199e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.i(TAG, "Canceling existing notification (id=" + id + ")"); 200e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme nm.cancel(id); 201e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 202e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 203e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 20469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme private void assertProgressNotification(String name, String percent) { 20569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // TODO: it current looks for 3 distinct objects, without taking advantage of their 20669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme // relationship. 20769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme String title = mContext.getString(R.string.bugreport_in_progress_title); 20869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Log.v(TAG, "Looking for progress notification title: '" + title+ "'"); 20969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getNotification(title); 21069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'"); 21169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getObject(name); 21269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme mUiBot.getObject(percent); 21369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 21469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 215e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme /** 216e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Sends a "bugreport finished" intent and waits for the result. 217e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * 218e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * @return extras sent to the bugreport finished consumer. 219e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 220e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private Bundle sendBugreportFinishedIntent(String bugreportPath, String screenshotPath) { 22169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme return sendBugreportFinishedIntent(null, bugreportPath, screenshotPath); 22269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 22369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme 22469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme private Bundle sendBugreportFinishedIntent(Integer pid, String bugreportPath, 22569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme String screenshotPath) { 22669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme Intent intent = new Intent(INTENT_BUGREPORT_FINISHED); 22769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme if (pid != null) { 22869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme intent.putExtra(EXTRA_PID, pid); 22969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme } 230e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (bugreportPath != null) { 231e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme intent.putExtra(EXTRA_BUGREPORT, bugreportPath); 232e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 233e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (screenshotPath != null) { 234e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme intent.putExtra(EXTRA_SCREENSHOT, screenshotPath); 235e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 236e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 237e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mContext.sendBroadcast(intent); 238e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 239e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title)); 240e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme mUiBot.chooseActivity(UI_NAME); 241e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme return mListener.getExtras(); 242e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 243e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 244e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme /** 245e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Asserts the proper ACTION_SEND_MULTIPLE intent was sent. 246e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */ 247e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertActionSendMultiple(Bundle extras, String bugreportContent, 248e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String screenshotContent) throws IOException { 249e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String body = extras.getString(Intent.EXTRA_TEXT); 250e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContainsRegex("missing build info", 251e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme SystemProperties.get("ro.build.description"), body); 252e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContainsRegex("missing serial number", 253e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme SystemProperties.get("ro.serialno"), body); 254e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 255e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong subject", ZIP_FILE, extras.getString(Intent.EXTRA_SUBJECT)); 256e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 257e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme List<Uri> attachments = extras.getParcelableArrayList(Intent.EXTRA_STREAM); 258e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme int expectedSize = screenshotContent != null ? 2 : 1; 259e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong number of attachments", expectedSize, attachments.size()); 260e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 261e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme // Need to interact through all attachments, since order is not guaranteed. 262e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Uri zipUri = null, screenshotUri = null; 263e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme for (Uri attachment : attachments) { 264e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (attachment.getPath().endsWith(".zip")) { 265e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zipUri = attachment; 266e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 267e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (attachment.getPath().endsWith(".png")) { 268e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme screenshotUri = attachment; 269e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 270e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 271e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNotNull("did not get .zip attachment", zipUri); 272e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertZipContent(zipUri, BUGREPORT_FILE, BUGREPORT_CONTENT); 273e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 274e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (screenshotContent != null) { 275e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNotNull("did not get .png attachment", screenshotUri); 276e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertContent(screenshotUri, SCREENSHOT_CONTENT); 277e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } else { 278e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertNull("should not have .png attachment", screenshotUri); 279e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 280e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 281e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 282e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertContent(Uri uri, String expectedContent) throws IOException { 283e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "assertContents(uri=" + uri); 284e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (InputStream is = mContext.getContentResolver().openInputStream(uri)) { 285e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String actualContent = new String(Streams.readFully(is)); 286e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong content for '" + uri + "'", expectedContent, actualContent); 287e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 288e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 289e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 290e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void assertZipContent(Uri uri, String entryName, String expectedContent) 291e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme throws IOException, IOException { 292e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "assertZipEntry(uri=" + uri + ", entryName=" + entryName); 293e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (ZipInputStream zis = new ZipInputStream(mContext.getContentResolver().openInputStream( 294e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme uri))) { 295e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ZipEntry entry; 296e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme while ((entry = zis.getNextEntry()) != null) { 297e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "Zip entry: " + entry.getName()); 298e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme if (entry.getName().equals(entryName)) { 299e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ByteArrayOutputStream bos = new ByteArrayOutputStream(); 300e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Streams.copy(zis, bos); 301e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme String actualContent = new String(bos.toByteArray(), "UTF-8"); 302e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme bos.close(); 303e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme assertEquals("wrong content for zip entry'" + entryName + "' on '" + uri + "'", 304e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme expectedContent, actualContent); 305e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme return; 306e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 307e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 308e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 309e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme fail("Did not find entry '" + entryName + "' on file '" + uri + "'"); 310e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 311e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 312ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme private boolean isServiceRunning(String name) { 313ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme ActivityManager manager = (ActivityManager) mContext 314ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme .getSystemService(Context.ACTIVITY_SERVICE); 315ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 316ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme if (service.service.getClassName().equals(name)) { 317ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme return true; 318ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 319ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 320ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme return false; 321ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme } 322ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme 323e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private static void createTextFile(String path, String content) throws IOException { 324e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "createFile(" + path + ")"); 325e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (Writer writer = new BufferedWriter(new OutputStreamWriter( 326e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme new FileOutputStream(path)))) { 327e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme writer.write(content); 328e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 329e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 330e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme 331e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme private void createZipFile(String path, String entryName, String content) throws IOException { 332e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme Log.v(TAG, "createZipFile(" + path + ", " + entryName + ")"); 333e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme try (ZipOutputStream zos = new ZipOutputStream( 334e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme new BufferedOutputStream(new FileOutputStream(path)))) { 335e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme ZipEntry entry = new ZipEntry(entryName); 336e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.putNextEntry(entry); 337e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme byte[] data = content.getBytes(); 338e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.write(data, 0, data.length); 339e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme zos.closeEntry(); 340e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 341e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme } 342e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme} 343