Close details dialog when bugreport is canceled by user.

BUG: 30158896
Change-Id: I0eab22586f6b431f2abe837088d48a655e03d213
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 6bc4df7..5a69b0c 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -17,6 +17,7 @@
 package com.android.shell;
 
 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
+
 import static com.android.shell.BugreportPrefs.STATE_HIDE;
 import static com.android.shell.BugreportPrefs.STATE_UNKNOWN;
 import static com.android.shell.BugreportPrefs.getWarningState;
@@ -44,6 +45,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
+
 import com.google.android.collect.Lists;
 
 import android.accounts.Account;
@@ -78,6 +80,7 @@
 import android.util.Log;
 import android.util.Patterns;
 import android.util.SparseArray;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.view.View.OnFocusChangeListener;
@@ -543,6 +546,7 @@
             deleteScreenshots(info);
         }
         stopProgress(id);
+        mInfoDialog.cancel();
     }
 
     /**
@@ -1404,7 +1408,7 @@
         /**
          * Sets its internal state and displays the dialog.
          */
-        private void initialize(final Context context, BugreportInfo info) {
+        void initialize(final Context context, BugreportInfo info) {
             final String dialogTitle =
                     context.getString(R.string.bugreport_info_dialog_title, info.id);
             // First initializes singleton.
@@ -1450,6 +1454,7 @@
                                     }
                                 })
                         .create();
+                mDialog.setCancelable(true);
 
                 mDialog.getWindow().setAttributes(
                         new WindowManager.LayoutParams(
@@ -1545,13 +1550,18 @@
          * <p>Once the bugreport is finished dumpstate has already generated the final files, so
          * changing the name would have no effect.
          */
-        private void onBugreportFinished(int id) {
+        void onBugreportFinished(int id) {
             if (mInfoName != null) {
                 mInfoName.setEnabled(false);
                 mInfoName.setText(mSavedName);
             }
         }
 
+        void cancel() {
+            if (mDialog != null) {
+                mDialog.cancel();
+            }
+        }
     }
 
     /**
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index 44e956a..ad66dfc 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -153,7 +153,7 @@
         Log.i(TAG, "#### setup() on " + getName());
         Instrumentation instrumentation = getInstrumentation();
         mContext = instrumentation.getTargetContext();
-        mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT);
+        mUiBot = new UiBot(instrumentation, TIMEOUT);
         mListener = ActionSendMultipleConsumerActivity.getListener(mContext);
 
         cancelExistingNotifications();
@@ -233,10 +233,7 @@
 
         assertProgressNotification(NAME, 00.00f);
 
-        openProgressNotification(ID);
-        UiObject cancelButton = mUiBot.getVisibleObject(mContext.getString(
-                com.android.internal.R.string.cancel).toUpperCase());
-        mUiBot.click(cancelButton, "cancel_button");
+        cancelFromNotification();
 
         waitForService(false);
     }
@@ -323,6 +320,21 @@
         assertServiceNotRunning();
     }
 
+    public void testProgress_cancelBugClosesDetailsDialog() throws Exception {
+        resetProperties();
+        sendBugreportStarted(1000);
+        waitForScreenshotButtonEnabled(true);
+
+        DetailsUi detailsUi = new DetailsUi(mUiBot, ID);
+        detailsUi.assertName(NAME);  // Sanity check
+
+        cancelFromNotification();
+        mUiBot.closeNotifications();
+
+        assertDetailsUiClosed();
+        assertServiceNotRunning();
+    }
+
     public void testProgress_changeDetailsPlainBugreport() throws Exception {
         changeDetailsTest(true);
     }
@@ -579,6 +591,13 @@
         }
     }
 
+    private void cancelFromNotification() {
+        openProgressNotification(ID);
+        UiObject cancelButton = mUiBot.getVisibleObject(mContext.getString(
+                com.android.internal.R.string.cancel).toUpperCase());
+        mUiBot.click(cancelButton, "cancel_button");
+    }
+
     private void assertProgressNotification(String name, float percent) {
         // TODO: it currently looks for 3 distinct objects, without taking advantage of their
         // relationship.
@@ -929,6 +948,11 @@
                 screenshotButton.isEnabled());
     }
 
+    private void assertDetailsUiClosed() {
+        // TODO: unhardcode resource ids
+        mUiBot.assertNotVisibleById("android:id/alertTitle");
+    }
+
     /**
      * Helper class containing the UiObjects present in the bugreport info dialog.
      */
diff --git a/packages/Shell/tests/src/com/android/shell/UiBot.java b/packages/Shell/tests/src/com/android/shell/UiBot.java
index 30f1692..ef24791 100644
--- a/packages/Shell/tests/src/com/android/shell/UiBot.java
+++ b/packages/Shell/tests/src/com/android/shell/UiBot.java
@@ -16,6 +16,8 @@
 
 package com.android.shell;
 
+import android.app.Instrumentation;
+import android.app.StatusBarManager;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
@@ -24,6 +26,8 @@
 import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.util.Log;
+
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
 /**
@@ -34,11 +38,13 @@
     private static final String TAG = "UiBot";
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
 
+    private final Instrumentation mInstrumentation;
     private final UiDevice mDevice;
     private final int mTimeout;
 
-    public UiBot(UiDevice device, int timeout) {
-        mDevice = device;
+    public UiBot(Instrumentation instrumentation, int timeout) {
+        mInstrumentation = instrumentation;
+        mDevice = UiDevice.getInstance(instrumentation);
         mTimeout = timeout;
     }
 
@@ -57,6 +63,13 @@
         return getObject(text);
     }
 
+    public void closeNotifications() throws Exception {
+        // TODO: mDevice should provide such method..
+        StatusBarManager sbm =
+                (StatusBarManager) mInstrumentation.getContext().getSystemService("statusbar");
+        sbm.collapsePanels();
+    }
+
     /**
      * Opens the system notification and clicks a given notification.
      *
@@ -111,6 +124,16 @@
         return uiObject;
     }
 
+    /**
+     * Asserts an object is not visible.
+     */
+    public void assertNotVisibleById(String id) {
+        // TODO: not working when the bugreport dialog is shown, it hangs until the dialog is
+        // dismissed and hence always work.
+        boolean hasIt = mDevice.hasObject(By.res(id));
+        assertFalse("should not have found object with id '" + id+ "'", hasIt);
+    }
+
 
     /**
      * Clicks on a UI element.