diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 63b9bb39cba0e..8b73c5ed552e1 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -47,6 +47,7 @@ import android.content.res.Configuration; import android.graphics.Bitmap; import android.net.Uri; import android.os.AsyncTask; +import android.os.Binder; import android.os.BugreportManager; import android.os.BugreportManager.BugreportCallback; import android.os.BugreportManager.BugreportCallback.BugreportErrorCode; @@ -186,7 +187,7 @@ public class BugreportProgressService extends Service { static final int SCREENSHOT_DELAY_SECONDS = 3; /** System property where dumpstate stores last triggered bugreport id */ - private static final String PROPERTY_LAST_ID = "dumpstate.last_id"; + static final String PROPERTY_LAST_ID = "dumpstate.last_id"; private static final String BUGREPORT_SERVICE = "bugreport"; @@ -233,7 +234,7 @@ public class BugreportProgressService extends Service { private File mBugreportsDir; - private BugreportManager mBugreportManager; + @VisibleForTesting BugreportManager mBugreportManager; /** * id of the notification used to set service on foreground. @@ -248,6 +249,11 @@ public class BugreportProgressService extends Service { */ private boolean mTakingScreenshot; + /** + * The delay timeout before taking a screenshot. + */ + @VisibleForTesting int mScreenshotDelaySec = SCREENSHOT_DELAY_SECONDS; + @GuardedBy("sNotificationBundle") private static final Bundle sNotificationBundle = new Bundle(); @@ -282,6 +288,7 @@ public class BugreportProgressService extends Service { mContext.getString(R.string.bugreport_notification_channel), isTv(this) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW)); + mBugreportManager = mContext.getSystemService(BugreportManager.class); } @Override @@ -305,7 +312,7 @@ public class BugreportProgressService extends Service { @Override public IBinder onBind(Intent intent) { - return null; + return new LocalBinder(); } @Override @@ -373,8 +380,14 @@ public class BugreportProgressService extends Service { public void onFinished() { mInfo.renameBugreportFile(); mInfo.renameScreenshots(); + if (mInfo.bugreportFile.length() == 0) { + Log.e(TAG, "Bugreport file empty. File path = " + mInfo.bugreportFile); + onError(BUGREPORT_ERROR_RUNTIME); + return; + } synchronized (mLock) { sendBugreportFinishedBroadcastLocked(); + mMainThreadHandler.post(() -> mInfoDialog.onBugreportFinished(mInfo)); } } @@ -400,10 +413,6 @@ public class BugreportProgressService extends Service { @GuardedBy("mLock") private void sendBugreportFinishedBroadcastLocked() { final String bugreportFilePath = mInfo.bugreportFile.getAbsolutePath(); - if (mInfo.bugreportFile.length() == 0) { - Log.e(TAG, "Bugreport file empty. File path = " + bugreportFilePath); - return; - } if (mInfo.type == BugreportParams.BUGREPORT_MODE_REMOTE) { sendRemoteBugreportFinishedBroadcast(mContext, bugreportFilePath, mInfo.bugreportFile); @@ -609,12 +618,21 @@ public class BugreportProgressService extends Service { BugreportInfo info = new BugreportInfo(mContext, baseName, name, shareTitle, shareDescription, bugreportType, mBugreportsDir); + synchronized (mLock) { + if (info.bugreportFile.exists()) { + Log.e(TAG, "Failed to start bugreport generation, the requested bugreport file " + + info.bugreportFile + " already exists"); + return; + } + info.createBugreportFile(); + } ParcelFileDescriptor bugreportFd = info.getBugreportFd(); if (bugreportFd == null) { Log.e(TAG, "Failed to start bugreport generation as " + " bugreport parcel file descriptor is null."); return; } + info.createScreenshotFile(mBugreportsDir); ParcelFileDescriptor screenshotFd = null; if (isDefaultScreenshotRequired(bugreportType, /* hasScreenshotButton= */ !mIsTv)) { screenshotFd = info.getDefaultScreenshotFd(); @@ -627,8 +645,6 @@ public class BugreportProgressService extends Service { } } - mBugreportManager = (BugreportManager) mContext.getSystemService( - Context.BUGREPORT_SERVICE); final Executor executor = ActivityThread.currentActivityThread().getExecutor(); Log.i(TAG, "bugreport type = " + bugreportType @@ -888,12 +904,12 @@ public class BugreportProgressService extends Service { collapseNotificationBar(); final String msg = mContext.getResources() .getQuantityString(com.android.internal.R.plurals.bugreport_countdown, - SCREENSHOT_DELAY_SECONDS, SCREENSHOT_DELAY_SECONDS); + mScreenshotDelaySec, mScreenshotDelaySec); Log.i(TAG, msg); // Show a toast just once, otherwise it might be captured in the screenshot. Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); - takeScreenshot(id, SCREENSHOT_DELAY_SECONDS); + takeScreenshot(id, mScreenshotDelaySec); } /** @@ -1248,6 +1264,7 @@ public class BugreportProgressService extends Service { .setContentText(content) .setContentIntent(PendingIntent.getService(mContext, info.id, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT)) + .setOnlyAlertOnce(false) .setDeleteIntent(newCancelIntent(mContext, info)); if (!TextUtils.isEmpty(info.getName())) { @@ -1287,6 +1304,7 @@ public class BugreportProgressService extends Service { .setLocalOnly(true) .setColor(context.getColor( com.android.internal.R.color.system_notification_accent_color)) + .setOnlyAlertOnce(true) .extend(new Notification.TvExtender()); } @@ -1620,6 +1638,16 @@ public class BugreportProgressService extends Service { || c == '_' || c == '-'; } + /** + * A local binder with interface to return an instance of BugreportProgressService for the + * purpose of testing. + */ + final class LocalBinder extends Binder { + @VisibleForTesting BugreportProgressService getService() { + return BugreportProgressService.this; + } + } + /** * Helper class encapsulating the UI elements and logic used to display a dialog where user * can change the details of a bugreport. @@ -1749,6 +1777,22 @@ public class BugreportProgressService extends Service { } } + /** + * Notifies the dialog that the bugreport has finished so it disables the {@code name} + * field. + *
Once the bugreport is finished dumpstate has already generated the final files, so
+ * changing the name would have no effect.
+ */
+ void onBugreportFinished(BugreportInfo info) {
+ if (mId == info.id && mInfoName != null) {
+ mInfoName.setEnabled(false);
+ mInfoName.setText(null);
+ if (!TextUtils.isEmpty(info.getName())) {
+ mInfoName.setText(info.getName());
+ }
+ }
+ }
+
void cancel() {
if (mDialog != null) {
mDialog.cancel();
@@ -1883,12 +1927,10 @@ public class BugreportProgressService extends Service {
this.shareDescription = shareDescription == null ? "" : shareDescription;
this.type = type;
this.baseName = baseName;
- createBugreportFile(bugreportsDir);
- createScreenshotFile(bugreportsDir);
+ this.bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
}
- void createBugreportFile(File bugreportsDir) {
- bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
+ void createBugreportFile() {
createReadWriteFile(bugreportFile);
}
@@ -1993,12 +2035,21 @@ public class BugreportProgressService extends Service {
Log.i(TAG, "Deleting empty bugreport file: " + bugreportFile);
bugreportFile.delete();
}
- for (File file : screenshotFiles) {
- if (file.length() == 0) {
+ deleteEmptyScreenshots();
+ }
+
+ /**
+ * Deletes empty screenshot files.
+ */
+ private void deleteEmptyScreenshots() {
+ screenshotFiles.removeIf(file -> {
+ final long length = file.length();
+ if (length == 0) {
Log.i(TAG, "Deleting empty screenshot file: " + file);
file.delete();
}
- }
+ return length == 0;
+ });
}
/**
@@ -2006,7 +2057,8 @@ public class BugreportProgressService extends Service {
* {@code initialName} if user has changed it.
*/
void renameScreenshots() {
- if (TextUtils.isEmpty(name)) {
+ deleteEmptyScreenshots();
+ if (TextUtils.isEmpty(name) || screenshotFiles.isEmpty()) {
return;
}
final List
- * These tests don't mock any component and rely on external UI components (like the notification
- * bar and activity chooser), which can make them unreliable and slow.
+ * These tests rely on external UI components (like the notificatio bar and activity chooser),
+ * which can make them unreliable and slow.
*
* The general workflow is:
*
@@ -115,63 +128,48 @@ public class BugreportReceiverTest {
// Timeout for UI operations, in milliseconds.
private static final int TIMEOUT = (int) (5 * DateUtils.SECOND_IN_MILLIS);
+ // The default timeout is too short to verify the notification button state. Using a longer
+ // timeout in the tests.
+ private static final int SCREENSHOT_DELAY_SECONDS = 5;
+
// Timeout for when waiting for a screenshot to finish.
private static final int SAFE_SCREENSHOT_DELAY = SCREENSHOT_DELAY_SECONDS + 10;
- private static final String BUGREPORTS_DIR = "bugreports";
private static final String BUGREPORT_FILE = "test_bugreport.txt";
- private static final String ZIP_FILE = "test_bugreport.zip";
- private static final String ZIP_FILE2 = "test_bugreport2.zip";
private static final String SCREENSHOT_FILE = "test_screenshot.png";
-
private static final String BUGREPORT_CONTENT = "Dump, might as well dump!\n";
private static final String SCREENSHOT_CONTENT = "A picture is worth a thousand words!\n";
- private static final int PID = 42;
- private static final int PID2 = 24;
- private static final int ID = 108;
- private static final int ID2 = 801;
- private static final String PROGRESS_PROPERTY = "dumpstate." + PID + ".progress";
- private static final String MAX_PROPERTY = "dumpstate." + PID + ".max";
- private static final String NAME_PROPERTY = "dumpstate." + PID + ".name";
private static final String NAME = "BUG, Y U NO REPORT?";
- private static final String NAME2 = "A bugreport's life";
private static final String NEW_NAME = "Bug_Forrest_Bug";
- private static final String NEW_NAME2 = "BugsyReportsy";
private static final String TITLE = "Wimbugdom Champion 2015";
- private static final String TITLE2 = "Master of the Universe";
- private static final String DESCRIPTION = "One's description...";
- private static final String DESCRIPTION2 = "...is another's treasure.";
- // TODO(b/143130523): Fix (update) tests and add to presubmit
- private static final String EXTRA_MAX = "android.intent.extra.MAX";
- private static final String EXTRA_PID = "android.intent.extra.PID";
- private static final String INTENT_BUGREPORT_STARTED =
- "com.android.internal.intent.action.BUGREPORT_STARTED";
private static final String NO_DESCRIPTION = null;
private static final String NO_NAME = null;
private static final String NO_SCREENSHOT = null;
private static final String NO_TITLE = null;
- private static final int NO_ID = 0;
- private static final boolean RENAMED_SCREENSHOTS = true;
- private static final boolean DIDNT_RENAME_SCREENSHOTS = false;
private String mDescription;
-
- private String mPlainTextPath;
- private String mZipPath;
- private String mZipPath2;
- private String mScreenshotPath;
+ private String mProgressTitle;
+ private int mBugreportId;
private Context mContext;
private UiBot mUiBot;
private CustomActionSendMultipleListener mListener;
+ private BugreportProgressService mService;
+ private IDumpstateListener mIDumpstateListener;
+ private ParcelFileDescriptor mBugreportFd;
+ private ParcelFileDescriptor mScreenshotFd;
+
+ @Mock private IDumpstate mMockIDumpstate;
@Rule public TestName mName = new TestName();
+ @Rule public ServiceTestRule mServiceRule = new ServiceTestRule();
@Before
public void setUp() throws Exception {
Log.i(TAG, getName() + ".setup()");
+ MockitoAnnotations.initMocks(this);
Instrumentation instrumentation = getInstrumentation();
mContext = instrumentation.getTargetContext();
mUiBot = new UiBot(instrumentation, TIMEOUT);
@@ -179,15 +177,8 @@ public class BugreportReceiverTest {
cancelExistingNotifications();
- mPlainTextPath = getPath(BUGREPORT_FILE);
- mZipPath = getPath(ZIP_FILE);
- mZipPath2 = getPath(ZIP_FILE2);
- mScreenshotPath = getPath(SCREENSHOT_FILE);
- createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
- createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
- createZipFile(mZipPath, BUGREPORT_FILE, BUGREPORT_CONTENT);
- createZipFile(mZipPath2, BUGREPORT_FILE, BUGREPORT_CONTENT);
-
+ mBugreportId = getBugreportId();
+ mProgressTitle = getBugreportInProgress(mBugreportId);
// Creates a multi-line description.
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 20; i++) {
@@ -195,6 +186,22 @@ public class BugreportReceiverTest {
}
mDescription = sb.toString();
+ // Mocks BugreportManager and updates tests value to the service
+ mService = ((BugreportProgressService.LocalBinder) mServiceRule.bindService(
+ new Intent(mContext, BugreportProgressService.class))).getService();
+ mService.mBugreportManager = new BugreportManager(mContext, mMockIDumpstate);
+ mService.mScreenshotDelaySec = SCREENSHOT_DELAY_SECONDS;
+ // Dup the fds which are passing to startBugreport function.
+ Mockito.doAnswer(invocation -> {
+ final boolean isScreenshotRequested = invocation.getArgument(6);
+ if (isScreenshotRequested) {
+ mScreenshotFd = ParcelFileDescriptor.dup(invocation.getArgument(3));
+ }
+ mBugreportFd = ParcelFileDescriptor.dup(invocation.getArgument(2));
+ return null;
+ }).when(mMockIDumpstate).startBugreport(anyInt(), any(), any(), any(), anyInt(), any(),
+ anyBoolean());
+
setWarningState(mContext, STATE_HIDE);
mUiBot.turnScreenOn();
@@ -203,6 +210,13 @@ public class BugreportReceiverTest {
@After
public void tearDown() throws Exception {
Log.i(TAG, getName() + ".tearDown()");
+ if (mBugreportFd != null) {
+ IoUtils.closeQuietly(mBugreportFd);
+ }
+ if (mScreenshotFd != null) {
+ IoUtils.closeQuietly(mScreenshotFd);
+ }
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
try {
cancelExistingNotifications();
} finally {
@@ -219,131 +233,90 @@ public class BugreportReceiverTest {
*/
@Test
public void testProgress() throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
+ assertProgressNotification(mProgressTitle, 0f);
- assertProgressNotification(NAME, 0f);
+ mIDumpstateListener.onProgress(10);
+ assertProgressNotification(mProgressTitle, 10);
- SystemProperties.set(PROGRESS_PROPERTY, "108");
- assertProgressNotification(NAME, 10.80f);
-
- assertProgressNotification(NAME, 50.00f);
-
- SystemProperties.set(PROGRESS_PROPERTY, "950");
- assertProgressNotification(NAME, 95.00f);
-
- // Make sure progress never goes back...
- SystemProperties.set(MAX_PROPERTY, "2000");
- assertProgressNotification(NAME, 95.00f);
-
- SystemProperties.set(PROGRESS_PROPERTY, "1000");
- assertProgressNotification(NAME, 95.00f);
-
- // ...only forward...
- SystemProperties.set(PROGRESS_PROPERTY, "1902");
- assertProgressNotification(NAME, 95.10f);
-
- SystemProperties.set(PROGRESS_PROPERTY, "1960");
- assertProgressNotification(NAME, 98.00f);
+ mIDumpstateListener.onProgress(95);
+ assertProgressNotification(mProgressTitle, 95.00f);
// ...but never more than the capped value.
- SystemProperties.set(PROGRESS_PROPERTY, "2000");
- assertProgressNotification(NAME, 99.00f);
+ mIDumpstateListener.onProgress(200);
+ assertProgressNotification(mProgressTitle, 99);
- SystemProperties.set(PROGRESS_PROPERTY, "3000");
- assertProgressNotification(NAME, 99.00f);
+ mIDumpstateListener.onProgress(300);
+ assertProgressNotification(mProgressTitle, 99);
- Bundle extras =
- sendBugreportFinishedAndGetSharedIntent(ID, mPlainTextPath, mScreenshotPath);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
- NAME, NO_TITLE, NO_DESCRIPTION, 0, RENAMED_SCREENSHOTS);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras);
assertServiceNotRunning();
}
@Test
public void testProgress_cancel() throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
- final NumberFormat nf = NumberFormat.getPercentInstance();
- nf.setMinimumFractionDigits(2);
- nf.setMaximumFractionDigits(2);
+ assertProgressNotification(mProgressTitle, 00.00f);
- assertProgressNotification(NAME, 00.00f);
+ cancelFromNotification(mProgressTitle);
- cancelFromNotification();
-
- waitForService(false);
+ assertServiceNotRunning();
}
@Test
public void testProgress_takeExtraScreenshot() throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
takeScreenshot();
assertScreenshotButtonEnabled(false);
waitForScreenshotButtonEnabled(true);
- sendBugreportFinished(ID, mPlainTextPath, mScreenshotPath);
-
- Bundle extras = acceptBugreportAndGetSharedIntent(ID);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
- NAME, NO_TITLE, NO_DESCRIPTION, 1, RENAMED_SCREENSHOTS);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1);
assertServiceNotRunning();
}
@Test
public void testScreenshotFinishesAfterBugreport() throws Exception {
- resetProperties();
-
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
takeScreenshot();
- sendBugreportFinished(ID, mPlainTextPath, NO_SCREENSHOT);
- waitShareNotification(ID);
+ sendBugreportFinished();
+ waitShareNotification(mBugreportId);
// There's no indication in the UI about the screenshot finish, so just sleep like a baby...
sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS);
- Bundle extras = acceptBugreportAndGetSharedIntent(ID);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, ID, PID, ZIP_FILE,
- NAME, NO_TITLE, NO_DESCRIPTION, 1, RENAMED_SCREENSHOTS);
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras, NO_NAME, NO_TITLE, NO_DESCRIPTION, 1);
assertServiceNotRunning();
}
@Test
public void testProgress_changeDetailsInvalidInput() throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME);
+ DetailsUi detailsUi = new DetailsUi(mBugreportId);
- // Check initial name.
- detailsUi.assertName(NAME);
-
- // Change name - it should have changed system property once focus is changed.
+ // Change name
detailsUi.focusOnName();
detailsUi.nameField.setText(NEW_NAME);
detailsUi.focusAwayFromName();
- assertPropertyValue(NAME_PROPERTY, NEW_NAME);
-
- // Cancel the dialog to make sure property was restored.
- detailsUi.clickCancel();
- assertPropertyValue(NAME_PROPERTY, NAME);
+ detailsUi.clickOk();
// Now try to set an invalid name.
- detailsUi.reOpen(NAME);
+ detailsUi.reOpen(NEW_NAME);
detailsUi.nameField.setText("/etc/passwd");
detailsUi.clickOk();
- assertPropertyValue(NAME_PROPERTY, "_etc_passwd");
// Finally, make the real changes.
detailsUi.reOpen("_etc_passwd");
@@ -353,27 +326,20 @@ public class BugreportReceiverTest {
detailsUi.clickOk();
- assertPropertyValue(NAME_PROPERTY, NEW_NAME);
assertProgressNotification(NEW_NAME, 00.00f);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID, mPlainTextPath,
- mScreenshotPath, TITLE);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
- NEW_NAME, TITLE, mDescription, 0, RENAMED_SCREENSHOTS);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE);
+ assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
}
@Test
public void testProgress_cancelBugClosesDetailsDialog() throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME);
- detailsUi.assertName(NAME); // Sanity check
-
- cancelFromNotification();
+ cancelFromNotification(mProgressTitle);
mUiBot.collapseStatusBar();
assertDetailsUiClosed();
@@ -381,40 +347,24 @@ public class BugreportReceiverTest {
}
@Test
- public void testProgress_changeDetailsPlainBugreport() throws Exception {
- changeDetailsTest(true);
- }
-
- @Test
- public void testProgress_changeDetailsZippedBugreport() throws Exception {
- changeDetailsTest(false);
- }
-
- private void changeDetailsTest(boolean plainText) throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ public void testProgress_changeDetailsTest() throws Exception {
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME);
-
- // Check initial name.
- detailsUi.assertName(NAME);
+ DetailsUi detailsUi = new DetailsUi(mBugreportId);
// Change fields.
- detailsUi.reOpen(NAME);
+ detailsUi.reOpen(mProgressTitle);
detailsUi.nameField.setText(NEW_NAME);
detailsUi.titleField.setText(TITLE);
detailsUi.descField.setText(mDescription);
detailsUi.clickOk();
- assertPropertyValue(NAME_PROPERTY, NEW_NAME);
assertProgressNotification(NEW_NAME, 00.00f);
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID,
- plainText? mPlainTextPath : mZipPath, mScreenshotPath, TITLE);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
- NEW_NAME, TITLE, mDescription, 0, RENAMED_SCREENSHOTS);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(TITLE);
+ assertActionSendMultiple(extras, NEW_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
}
@@ -430,60 +380,18 @@ public class BugreportReceiverTest {
}
private void changeJustDetailsTest(boolean touchDetails) throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
waitForScreenshotButtonEnabled(true);
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME, touchDetails);
+ DetailsUi detailsUi = new DetailsUi(mBugreportId, touchDetails);
detailsUi.nameField.setText("");
detailsUi.titleField.setText("");
detailsUi.descField.setText(mDescription);
detailsUi.clickOk();
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID, mZipPath, mScreenshotPath);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
- NO_NAME, NO_TITLE, mDescription, 0, DIDNT_RENAME_SCREENSHOTS);
-
- assertServiceNotRunning();
- }
-
- @Test
- public void testProgress_changeJustDetailsIsClearedOnSecondBugreport() throws Exception {
- resetProperties();
- sendBugreportStarted(ID, PID, NAME, 1000);
- waitForScreenshotButtonEnabled(true);
-
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME);
- detailsUi.assertName(NAME);
- detailsUi.assertTitle("");
- detailsUi.assertDescription("");
- assertTrue("didn't enable name on UI", detailsUi.nameField.isEnabled());
- detailsUi.nameField.setText(NEW_NAME);
- detailsUi.titleField.setText(TITLE);
- detailsUi.descField.setText(DESCRIPTION);
- detailsUi.clickOk();
-
- sendBugreportStarted(ID2, PID2, NAME2, 1000);
-
- sendBugreportFinished(ID, mZipPath, mScreenshotPath);
- Bundle extras = acceptBugreportAndGetSharedIntent(TITLE);
-
- detailsUi = new DetailsUi(mUiBot, ID2, NAME2);
- detailsUi.assertName(NAME2);
- detailsUi.assertTitle("");
- detailsUi.assertDescription("");
- assertTrue("didn't enable name on UI", detailsUi.nameField.isEnabled());
- detailsUi.nameField.setText(NEW_NAME2);
- detailsUi.titleField.setText(TITLE2);
- detailsUi.descField.setText(DESCRIPTION2);
- detailsUi.clickOk();
-
- // Must use a different zip file otherwise it will fail because zip already contains
- // title.txt and description.txt entries.
- extras = sendBugreportFinishedAndGetSharedIntent(ID2, mZipPath2, NO_SCREENSHOT, TITLE2);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, ID2, PID2, TITLE2,
- NEW_NAME2, TITLE2, DESCRIPTION2, 0, RENAMED_SCREENSHOTS);
+ Bundle extras = sendBugreportFinishedAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras, NO_NAME, NO_TITLE, mDescription, 0);
assertServiceNotRunning();
}
@@ -507,26 +415,25 @@ public class BugreportReceiverTest {
}
private void bugreportFinishedWhileChangingDetailsTest(boolean waitScreenshot) throws Exception {
- resetProperties();
- sendBugreportStarted(1000);
+ sendBugreportStarted();
if (waitScreenshot) {
waitForScreenshotButtonEnabled(true);
}
- DetailsUi detailsUi = new DetailsUi(mUiBot, ID, NAME);
+ DetailsUi detailsUi = new DetailsUi(mBugreportId);
// Finish the bugreport while user's still typing the name.
detailsUi.nameField.setText(NEW_NAME);
- sendBugreportFinished(ID, mPlainTextPath, mScreenshotPath);
+ sendBugreportFinished();
// Wait until the share notification is received...
- waitShareNotification(ID);
+ waitShareNotification(mBugreportId);
// ...then close notification bar.
mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
// Make sure UI was updated properly.
assertFalse("didn't disable name on UI", detailsUi.nameField.isEnabled());
- assertEquals("didn't revert name on UI", NAME, detailsUi.nameField.getText().toString());
+ assertNotEquals("didn't revert name on UI", NAME, detailsUi.nameField.getText());
// Finish changing other fields.
detailsUi.titleField.setText(TITLE);
@@ -534,9 +441,8 @@ public class BugreportReceiverTest {
detailsUi.clickOk();
// Finally, share bugreport.
- Bundle extras = acceptBugreportAndGetSharedIntent(ID);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
- NAME, TITLE, mDescription, 0, RENAMED_SCREENSHOTS);
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras, NO_NAME, TITLE, mDescription, 0);
assertServiceNotRunning();
}
@@ -569,11 +475,14 @@ public class BugreportReceiverTest {
}
// Send notification and click on share.
- sendBugreportFinished(NO_ID, mPlainTextPath, null);
- mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title, NO_ID));
+ sendBugreportStarted();
+ waitForScreenshotButtonEnabled(true);
+ sendBugreportFinished();
+ mUiBot.clickOnNotification(mContext.getString(
+ R.string.bugreport_finished_title, mBugreportId));
// Handle the warning
- mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm));
+ mUiBot.getObject(mContext.getString(R.string.bugreport_confirm));
// TODO: get ok and dontShowAgain from the dialog reference above
UiObject dontShowAgain =
mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_dont_repeat));
@@ -597,43 +506,45 @@ public class BugreportReceiverTest {
// Share the bugreport.
mUiBot.chooseActivity(UI_NAME);
Bundle extras = mListener.getExtras();
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
+ assertActionSendMultiple(extras);
// Make sure it's hidden now.
int newState = getWarningState(mContext, STATE_UNKNOWN);
assertEquals("Didn't change state", STATE_HIDE, newState);
}
+ @Test
+ public void testBugreportFinished_withEmptyBugreportFile() throws Exception {
+ sendBugreportStarted();
+
+ IoUtils.closeQuietly(mBugreportFd);
+ mBugreportFd = null;
+ sendBugreportFinished();
+
+ assertServiceNotRunning();
+ }
+
@Test
public void testShareBugreportAfterServiceDies() throws Exception {
- sendBugreportFinished(NO_ID, mPlainTextPath, NO_SCREENSHOT);
- waitForService(false);
- Bundle extras = acceptBugreportAndGetSharedIntent(NO_ID);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
+ sendBugreportStarted();
+ waitForScreenshotButtonEnabled(true);
+ sendBugreportFinished();
+ killService();
+ assertServiceNotRunning();
+ Bundle extras = acceptBugreportAndGetSharedIntent(mBugreportId);
+ assertActionSendMultiple(extras);
}
@Test
- public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, mScreenshotPath);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
- }
+ public void testBugreportRequestTwice_oneStartBugreportInvoked() throws Exception {
+ sendBugreportStarted();
+ new BugreportRequestedReceiver().onReceive(mContext,
+ new Intent(INTENT_BUGREPORT_REQUESTED));
+ getInstrumentation().waitForIdleSync();
- @Test
- public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception {
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, mScreenshotPath);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
- }
-
- @Test
- public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception {
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, NO_SCREENSHOT);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
- }
-
- @Test
- public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception {
- Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, NO_SCREENSHOT);
- assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
+ verify(mMockIDumpstate, times(1)).startBugreport(anyInt(), any(), any(), any(),
+ anyInt(), any(), anyBoolean());
+ sendBugreportFinished();
}
private void cancelExistingNotifications() {
@@ -664,10 +575,10 @@ public class BugreportReceiverTest {
assertEquals("old notifications were not cancelled", 0, nm.getActiveNotifications().length);
}
- private void cancelFromNotification() {
- openProgressNotification(NAME);
- UiObject cancelButton = mUiBot.getVisibleObject(mContext.getString(
- com.android.internal.R.string.cancel).toUpperCase());
+ private void cancelFromNotification(String name) {
+ openProgressNotification(name);
+ UiObject cancelButton = mUiBot.getObject(mContext.getString(
+ com.android.internal.R.string.cancel));
mUiBot.click(cancelButton, "cancel_button");
}
@@ -676,67 +587,60 @@ public class BugreportReceiverTest {
// TODO: need a way to get the ProgresBar from the "android:id/progress" UIObject...
}
- private UiObject openProgressNotification(String bugreportName) {
- Log.v(TAG, "Looking for progress notification for '" + bugreportName + "'");
- return mUiBot.getNotification(bugreportName);
- }
-
- void resetProperties() {
- // TODO: call method to remove property instead
- SystemProperties.set(PROGRESS_PROPERTY, "Reset");
- SystemProperties.set(MAX_PROPERTY, "Reset");
- SystemProperties.set(NAME_PROPERTY, "Reset");
+ private void openProgressNotification(String title) {
+ Log.v(TAG, "Looking for progress notification for '" + title + "'");
+ UiObject2 notification = mUiBot.getNotification2(title);
+ if (notification != null) {
+ mUiBot.expandNotification(notification);
+ }
}
/**
- * Sends a "bugreport started" intent with the default values.
+ * Sends a "bugreport requested" intent with the default values.
*/
- private void sendBugreportStarted(int max) throws Exception {
- sendBugreportStarted(ID, PID, NAME, max);
- }
+ private void sendBugreportStarted() throws Exception {
+ Intent intent = new Intent(INTENT_BUGREPORT_REQUESTED);
+ // Ideally, we should invoke BugreportRequestedReceiver by sending
+ // INTENT_BUGREPORT_REQUESTED. But the intent has been protected broadcast by the system
+ // starting from S.
+ new BugreportRequestedReceiver().onReceive(mContext, intent);
- private void sendBugreportStarted(int id, int pid, String name, int max) throws Exception {
- Intent intent = new Intent(INTENT_BUGREPORT_STARTED);
- intent.setPackage("com.android.shell");
- intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtra(EXTRA_ID, id);
- intent.putExtra(EXTRA_PID, pid);
- intent.putExtra(EXTRA_NAME, name);
- intent.putExtra(EXTRA_MAX, max);
- mContext.sendBroadcast(intent);
+ ArgumentCaptor