summaryrefslogtreecommitdiff
path: root/packages/Shell/src
diff options
context:
space:
mode:
author Yeabkal Wubshit <yeabkal@google.com> 2020-11-16 18:11:31 -0800
committer Haiping Yang <haiping@google.com> 2021-11-24 23:45:21 +0000
commit5837e4571707081f9247f6c7e9c5578df20f5e3a (patch)
tree0ea98f31ae223b68f937923f18c189fe415d5224 /packages/Shell/src
parent36837c894873c60208964737f305ee59df8d04b4 (diff)
Share Wear bugreport right after it is taken
In rvc-wear-dev, bugreports were not shared to phone until user tapped on the bugreport-complete notification. Now, we are sending bugreports to phones immediately after bugreport is taken. We still retain the bugreport-complete notification. The bugreport-complete notification will have an action button that leads the user to a bugreport-warning screen as long as the user has not opted out from seeing the warning. If the user chooses not to see that message again (which they can do in the warning screen), there will not be any action button on the bugreport-complete notification, and the user can just swipe to delete it. Refer to the look of the notification when no warning message is to be displayed (https://screenshot.googleplex.com/JStqotLwCaTXeL9) and when a warning message is to be displayed (https://screenshot.googleplex.com/AdGKWFqbky8Ad8s) Note: this change does NOT affect the functionality of the BugreportProgressService for any other device except Wear devices. Bug: 163083307 Test: the described feature tested with salmon running rvc-wear-dev Change-Id: If6890ef8cada60e454c9232d402bbdb8a1b0315e
Diffstat (limited to 'packages/Shell/src')
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java164
-rw-r--r--packages/Shell/src/com/android/shell/BugreportWarningActivity.java12
2 files changed, 142 insertions, 34 deletions
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 8c7011253c8a..ee9d4301770a 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -150,6 +150,7 @@ public class BugreportProgressService extends Service {
// Internal intents used on notification actions.
static final String INTENT_BUGREPORT_CANCEL = "android.intent.action.BUGREPORT_CANCEL";
static final String INTENT_BUGREPORT_SHARE = "android.intent.action.BUGREPORT_SHARE";
+ static final String INTENT_BUGREPORT_DONE = "android.intent.action.BUGREPORT_DONE";
static final String INTENT_BUGREPORT_INFO_LAUNCH =
"android.intent.action.BUGREPORT_INFO_LAUNCH";
static final String INTENT_BUGREPORT_SCREENSHOT =
@@ -555,6 +556,8 @@ public class BugreportProgressService extends Service {
case INTENT_BUGREPORT_SHARE:
shareBugreport(id, (BugreportInfo) intent.getParcelableExtra(EXTRA_INFO));
break;
+ case INTENT_BUGREPORT_DONE:
+ maybeShowWarningMessageAndCloseNotification(id);
case INTENT_BUGREPORT_CANCEL:
cancel(id);
break;
@@ -809,10 +812,30 @@ public class BugreportProgressService extends Service {
}
/**
- * Finalizes the progress on a given bugreport and cancel its notification.
+ * Creates a {@link PendingIntent} for a notification action used to show warning about the
+ * sensitivity of bugreport data and then close bugreport notification.
+ *
+ * Note that, the warning message may not be shown if the user has chosen not to see the
+ * message anymore.
*/
+ private static PendingIntent newBugreportDoneIntent(Context context, BugreportInfo info) {
+ final Intent intent = new Intent(INTENT_BUGREPORT_DONE);
+ intent.setClass(context, BugreportProgressService.class);
+ intent.putExtra(EXTRA_ID, info.id);
+ return PendingIntent.getService(context, info.id, intent,
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
@GuardedBy("mLock")
private void stopProgressLocked(int id) {
+ stopProgressLocked(id, /* cancelNotification */ true);
+ }
+
+ /**
+ * Finalizes the progress on a given bugreport and cancel its notification.
+ */
+ @GuardedBy("mLock")
+ private void stopProgressLocked(int id, boolean cancelNotification) {
if (mBugreportInfos.indexOfKey(id) < 0) {
Log.w(TAG, "ID not watched: " + id);
} else {
@@ -821,8 +844,13 @@ public class BugreportProgressService extends Service {
}
// Must stop foreground service first, otherwise notif.cancel() will fail below.
stopForegroundWhenDoneLocked(id);
- Log.d(TAG, "stopProgress(" + id + "): cancel notification");
- NotificationManager.from(mContext).cancel(id);
+
+ if (cancelNotification) {
+ Log.d(TAG, "stopProgress(" + id + "): cancel notification");
+ NotificationManager.from(mContext).cancel(id);
+ } else {
+ Log.d(TAG, "stopProgress(" + id + ")");
+ }
stopSelfWhenDoneLocked();
}
@@ -1039,7 +1067,8 @@ public class BugreportProgressService extends Service {
}
/**
- * Wraps up bugreport generation and triggers a notification to share the bugreport.
+ * Wraps up bugreport generation and triggers a notification to either share the bugreport or
+ * just notify the ending of the bugreport generation, according to the device type.
*/
private void onBugreportFinished(BugreportInfo info) {
if (!TextUtils.isEmpty(info.shareTitle)) {
@@ -1054,25 +1083,46 @@ public class BugreportProgressService extends Service {
stopForegroundWhenDoneLocked(info.id);
}
- triggerLocalNotification(mContext, info);
- }
-
- /**
- * Responsible for triggering a notification that allows the user to start a "share" intent with
- * the bugreport. On watches we have other methods to allow the user to start this intent
- * (usually by triggering it on another connected device); we don't need to display the
- * notification in this case.
- */
- private void triggerLocalNotification(final Context context, final BugreportInfo info) {
if (!info.bugreportFile.exists() || !info.bugreportFile.canRead()) {
Log.e(TAG, "Could not read bugreport file " + info.bugreportFile);
- Toast.makeText(context, R.string.bugreport_unreadable_text, Toast.LENGTH_LONG).show();
+ Toast.makeText(mContext, R.string.bugreport_unreadable_text, Toast.LENGTH_LONG).show();
synchronized (mLock) {
stopProgressLocked(info.id);
}
return;
}
+ if (mIsWatch) {
+ // Wear wants to send the notification directly and not wait for the user to tap on the
+ // notification.
+ triggerShareBugreportAndLocalNotification(info);
+ } else {
+ triggerLocalNotification(info);
+ }
+ }
+
+ /**
+ * Responsible for starting the bugerport sharing process and posting a notification which
+ * shows that the bugreport has been taken and that the sharing process has kicked-off.
+ */
+ private void triggerShareBugreportAndLocalNotification(final BugreportInfo info) {
+ boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt");
+ if (!isPlainText) {
+ // Already zipped, share it right away.
+ shareBugreport(info.id, info, /* showWarning */ false,
+ /* cancelNotificationWhenStoppingProgress */ false);
+ sendBugreportNotification(info, mTakingScreenshot);
+ } else {
+ // Asynchronously zip the file first, then share it.
+ shareAndPostNotificationForZippedBugreport(info, mTakingScreenshot);
+ }
+ }
+
+ /**
+ * Responsible for triggering a notification that allows the user to start a "share" intent with
+ * the bugreport.
+ */
+ private void triggerLocalNotification(final BugreportInfo info) {
boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt");
if (!isPlainText) {
// Already zipped, send it right away.
@@ -1083,9 +1133,11 @@ public class BugreportProgressService extends Service {
}
}
- private static Intent buildWarningIntent(Context context, Intent sendIntent) {
+ private static Intent buildWarningIntent(Context context, @Nullable Intent sendIntent) {
final Intent intent = new Intent(context, BugreportWarningActivity.class);
- intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
+ if (sendIntent != null) {
+ intent.putExtra(Intent.EXTRA_INTENT, sendIntent);
+ }
return intent;
}
@@ -1163,11 +1215,30 @@ public class BugreportProgressService extends Service {
return intent;
}
+ private boolean hasUserDecidedNotToGetWarningMessage() {
+ return getWarningState(mContext, STATE_UNKNOWN) == STATE_HIDE;
+ }
+
+ private void maybeShowWarningMessageAndCloseNotification(int id) {
+ if (!hasUserDecidedNotToGetWarningMessage()) {
+ Intent warningIntent = buildWarningIntent(mContext, /* sendIntent */ null);
+ warningIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(warningIntent);
+ }
+ NotificationManager.from(mContext).cancel(id);
+ }
+
+ private void shareBugreport(int id, BugreportInfo sharedInfo) {
+ shareBugreport(id, sharedInfo, !hasUserDecidedNotToGetWarningMessage(),
+ /* cancelNotificationWhenStoppingProgress */ true);
+ }
+
/**
* Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
* intent, but issuing a warning dialog the first time.
*/
- private void shareBugreport(int id, BugreportInfo sharedInfo) {
+ private void shareBugreport(int id, BugreportInfo sharedInfo, boolean showWarning,
+ boolean cancelNotificationWhenStoppingProgress) {
MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE);
BugreportInfo info;
synchronized (mLock) {
@@ -1199,7 +1270,7 @@ public class BugreportProgressService extends Service {
boolean useChooser = true;
// Send through warning dialog by default
- if (getWarningState(mContext, STATE_UNKNOWN) != STATE_HIDE) {
+ if (showWarning) {
notifIntent = buildWarningIntent(mContext, sendIntent);
// No need to show a chooser in this case.
useChooser = false;
@@ -1216,7 +1287,7 @@ public class BugreportProgressService extends Service {
}
synchronized (mLock) {
// ... and stop watching this process.
- stopProgressLocked(id);
+ stopProgressLocked(id, cancelNotificationWhenStoppingProgress);
}
}
@@ -1240,12 +1311,6 @@ public class BugreportProgressService extends Service {
// Since adding the details can take a while, do it before notifying user.
addDetailsToZipFile(info);
- final Intent shareIntent = new Intent(INTENT_BUGREPORT_SHARE);
- shareIntent.setClass(mContext, BugreportProgressService.class);
- shareIntent.setAction(INTENT_BUGREPORT_SHARE);
- shareIntent.putExtra(EXTRA_ID, info.id);
- shareIntent.putExtra(EXTRA_INFO, info);
-
String content;
content = takingScreenshot ?
mContext.getString(R.string.bugreport_finished_pending_screenshot_text)
@@ -1263,11 +1328,32 @@ public class BugreportProgressService extends Service {
final Notification.Builder builder = newBaseNotification(mContext)
.setContentTitle(title)
.setTicker(title)
- .setContentText(content)
- .setContentIntent(PendingIntent.getService(mContext, info.id, shareIntent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
.setOnlyAlertOnce(false)
- .setDeleteIntent(newCancelIntent(mContext, info));
+ .setContentText(content);
+
+ if (!mIsWatch) {
+ final Intent shareIntent = new Intent(INTENT_BUGREPORT_SHARE);
+ shareIntent.setClass(mContext, BugreportProgressService.class);
+ shareIntent.setAction(INTENT_BUGREPORT_SHARE);
+ shareIntent.putExtra(EXTRA_ID, info.id);
+ shareIntent.putExtra(EXTRA_INFO, info);
+
+ builder.setContentIntent(PendingIntent.getService(mContext, info.id, shareIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
+ .setDeleteIntent(newCancelIntent(mContext, info));
+ } else {
+ // Device is a watch.
+ if (hasUserDecidedNotToGetWarningMessage()) {
+ // No action button needed for the notification. User can swipe to dimiss.
+ builder.setActions(new Action[0]);
+ } else {
+ // Add action button to lead user to the warning screen.
+ builder.setActions(
+ new Action.Builder(
+ null, mContext.getString(R.string.bugreport_info_action),
+ newBugreportDoneIntent(mContext, info)).build());
+ }
+ }
if (!TextUtils.isEmpty(info.getName())) {
builder.setSubText(info.getName());
@@ -1327,6 +1413,24 @@ public class BugreportProgressService extends Service {
}
/**
+ * Zips a bugreport, shares it, and sends for it a bugreport notification.
+ */
+ private void shareAndPostNotificationForZippedBugreport(final BugreportInfo info,
+ final boolean takingScreenshot) {
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ Looper.prepare();
+ zipBugreport(info);
+ shareBugreport(info.id, info, /* showWarning */ false,
+ /* cancelNotificationWhenStoppingProgress */ false);
+ sendBugreportNotification(info, mTakingScreenshot);
+ return null;
+ }
+ }.execute();
+ }
+
+ /**
* Zips a bugreport file, returning the path to the new file (or to the
* original in case of failure).
*/
diff --git a/packages/Shell/src/com/android/shell/BugreportWarningActivity.java b/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
index ecd1369817b4..a44e23603f52 100644
--- a/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
+++ b/packages/Shell/src/com/android/shell/BugreportWarningActivity.java
@@ -54,9 +54,11 @@ public class BugreportWarningActivity extends AlertActivity
mSendIntent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
- // We need to touch the extras to unpack them so they get migrated to
- // ClipData correctly.
- mSendIntent.hasExtra(Intent.EXTRA_STREAM);
+ if (mSendIntent != null) {
+ // We need to touch the extras to unpack them so they get migrated to
+ // ClipData correctly.
+ mSendIntent.hasExtra(Intent.EXTRA_STREAM);
+ }
final AlertController.AlertParams ap = mAlertParams;
ap.mView = LayoutInflater.from(this).inflate(R.layout.confirm_repeat, null);
@@ -84,7 +86,9 @@ public class BugreportWarningActivity extends AlertActivity
if (which == AlertDialog.BUTTON_POSITIVE) {
// Remember confirm state, and launch target
setWarningState(this, mConfirmRepeat.isChecked() ? STATE_HIDE : STATE_SHOW);
- sendShareIntent(this, mSendIntent);
+ if (mSendIntent != null) {
+ sendShareIntent(this, mSendIntent);
+ }
}
finish();