Add progressbar to BugReportApp.
When BugReport is initiated when dumpstate is in progress
by the BugReport app, it will show a dialog with a progress
bar and numeric value of the progress.
When dumpstate finishes, it changes the title to "bug report collected",
it doesn't close the dialog.
Bug: 134530860
Change-Id: I2e768d47b8122e3cd67e7872c5373d901cc8e3d6
Test: tested on a hawk rig - took bugreport, uploaded,
clicked start bugreport shortcut when it's running,
it shows a progress.
(cherry picked from commit ca85bfd52e652589f1fbf7dfecc50a6c003a0242)
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
index b0c754a..cce327d 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
@@ -17,6 +17,7 @@
import static com.google.android.car.bugreport.PackageUtils.getPackageVersion;
+import android.annotation.FloatRange;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.app.Notification;
@@ -32,11 +33,14 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.Display;
import android.widget.Toast;
+import com.google.common.util.concurrent.AtomicDouble;
+
import libcore.io.IoUtils;
import java.io.BufferedOutputStream;
@@ -93,22 +97,40 @@
private static final String MESSAGE_FAILURE_DUMPSTATE = "Failed to grab dumpstate";
private static final String MESSAGE_FAILURE_ZIP = "Failed to zip files";
- // Binder given to clients
+ private static final int PROGRESS_HANDLER_EVENT_PROGRESS = 1;
+ private static final String PROGRESS_HANDLER_DATA_PROGRESS = "progress";
+
+ static final float MAX_PROGRESS_VALUE = 100f;
+
+ /** Binder given to clients. */
private final IBinder mBinder = new ServiceBinder();
+ private final AtomicBoolean mIsCollectingBugReport = new AtomicBoolean(false);
+ private final AtomicDouble mBugReportProgress = new AtomicDouble(0);
+
private MetaBugReport mMetaBugReport;
private NotificationManager mNotificationManager;
private NotificationChannel mNotificationChannel;
- private AtomicBoolean mIsCollectingBugReport = new AtomicBoolean(false);
- private Handler mHandler;
private ScheduledExecutorService mSingleThreadExecutor;
+ private BugReportProgressListener mBugReportProgressListener;
private Car mCar;
private CarBugreportManager mBugreportManager;
private CarBugreportManager.CarBugreportManagerCallback mCallback;
- /**
- * Client binder.
- */
+ /** A handler on the main thread. */
+ private Handler mHandler;
+
+ /** A listener that's notified when bugreport progress changes. */
+ interface BugReportProgressListener {
+ /**
+ * Called when bug report progress changes.
+ *
+ * @param progress - a bug report progress in [0.0, 100.0].
+ */
+ void onProgress(float progress);
+ }
+
+ /** Client binder. */
public class ServiceBinder extends Binder {
BugReportService getService() {
// Return this instance of LocalService so clients can call public methods
@@ -116,6 +138,23 @@
}
}
+ /** A handler on a main thread. */
+ private class BugReportHandler extends Handler {
+ @Override
+ public void handleMessage(Message message) {
+ switch (message.what) {
+ case PROGRESS_HANDLER_EVENT_PROGRESS:
+ if (mBugReportProgressListener != null) {
+ float progress = message.getData().getFloat(PROGRESS_HANDLER_DATA_PROGRESS);
+ mBugReportProgressListener.onProgress(progress);
+ }
+ break;
+ default:
+ Log.d(TAG, "Unknown event " + message.what + ", ignoring.");
+ }
+ }
+ }
+
@Override
public void onCreate() {
mNotificationManager = getSystemService(NotificationManager.class);
@@ -124,8 +163,8 @@
getString(R.string.notification_bugreport_channel_name),
NotificationManager.IMPORTANCE_MIN);
mNotificationManager.createNotificationChannel(mNotificationChannel);
- mHandler = new Handler();
mSingleThreadExecutor = Executors.newSingleThreadScheduledExecutor();
+ mHandler = new BugReportHandler();
mCar = Car.createCar(this);
try {
mBugreportManager = (CarBugreportManager) mCar.getCarManager(Car.CAR_BUGREPORT_SERVICE);
@@ -144,6 +183,7 @@
Log.i(TAG, String.format("Will start collecting bug report, version=%s",
getPackageVersion(this)));
mIsCollectingBugReport.set(true);
+ mBugReportProgress.set(0);
Notification notification =
new Notification.Builder(this, NOTIFICATION_STATUS_CHANNEL_ID)
@@ -161,16 +201,32 @@
return START_NOT_STICKY;
}
+ /** Returns true if bugreporting is in progress. */
public boolean isCollectingBugReport() {
return mIsCollectingBugReport.get();
}
+ /** Returns current bugreport progress. */
+ public float getBugReportProgress() {
+ return (float) mBugReportProgress.get();
+ }
+
+ /** Sets a bugreport progress listener. The listener is called on a main thread. */
+ public void setBugReportProgressListener(BugReportProgressListener listener) {
+ mBugReportProgressListener = listener;
+ }
+
+ /** Removes the bugreport progress listener. */
+ public void removeBugReportProgressListener() {
+ mBugReportProgressListener = null;
+ }
+
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
- private void sendStatusInformation(@StringRes int resId) {
+ private void showToast(@StringRes int resId) {
// run on ui thread.
mHandler.post(() -> Toast.makeText(this, getText(resId), Toast.LENGTH_LONG).show());
}
@@ -213,7 +269,7 @@
return result;
} catch (IOException | InterruptedException e) {
Log.e(TAG, "screencap process failed: ", e);
- sendStatusInformation(R.string.toast_status_screencap_failed);
+ showToast(R.string.toast_status_screencap_failed);
}
return null;
}
@@ -257,10 +313,17 @@
Log.e(TAG, "Failed to grab dump state", e);
BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_WRITE_FAILED,
MESSAGE_FAILURE_DUMPSTATE);
- sendStatusInformation(R.string.toast_status_dump_state_failed);
+ showToast(R.string.toast_status_dump_state_failed);
}
}
+ private void sendProgressEventToHandler(float progress) {
+ Message message = new Message();
+ message.what = PROGRESS_HANDLER_EVENT_PROGRESS;
+ message.getData().putFloat(PROGRESS_HANDLER_DATA_PROGRESS, progress);
+ mHandler.sendMessage(message);
+ }
+
private void requestBugReport(ParcelFileDescriptor outFd) {
if (DEBUG) {
Log.d(TAG, "Requesting a bug report from CarBugReportManager.");
@@ -269,20 +332,27 @@
@Override
public void onError(int errorCode) {
Log.e(TAG, "Bugreport failed " + errorCode);
- sendStatusInformation(R.string.toast_status_failed);
+ showToast(R.string.toast_status_failed);
// TODO(b/133520419): show this error on Info page or add to zip file.
scheduleZipTask();
+ // We let the UI know that bug reporting is finished, because the next step is to
+ // zip everything and upload.
+ mBugReportProgress.set(MAX_PROGRESS_VALUE);
+ sendProgressEventToHandler(MAX_PROGRESS_VALUE);
}
@Override
- public void onProgress(float progress) {
- Log.d(TAG, "bugreport progress received " + progress);
+ public void onProgress(@FloatRange(from = 0f, to = MAX_PROGRESS_VALUE) float progress) {
+ mBugReportProgress.set(progress);
+ sendProgressEventToHandler(progress);
}
@Override
public void onFinished() {
Log.i(TAG, "Bugreport finished");
scheduleZipTask();
+ mBugReportProgress.set(MAX_PROGRESS_VALUE);
+ sendProgressEventToHandler(MAX_PROGRESS_VALUE);
}
};
mBugreportManager.requestZippedBugreport(outFd, mCallback);
@@ -303,10 +373,10 @@
Log.e(TAG, "Failed to zip files", e);
BugStorageUtils.setBugReportStatus(this, mMetaBugReport, Status.STATUS_WRITE_FAILED,
MESSAGE_FAILURE_ZIP);
- sendStatusInformation(R.string.toast_status_failed);
+ showToast(R.string.toast_status_failed);
}
mIsCollectingBugReport.set(false);
- sendStatusInformation(R.string.toast_status_finished);
+ showToast(R.string.toast_status_finished);
}
@Override