diff options
author | 2020-11-16 18:11:31 -0800 | |
---|---|---|
committer | 2021-11-24 23:45:21 +0000 | |
commit | 5837e4571707081f9247f6c7e9c5578df20f5e3a (patch) | |
tree | 0ea98f31ae223b68f937923f18c189fe415d5224 /packages/Shell/src | |
parent | 36837c894873c60208964737f305ee59df8d04b4 (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.java | 164 | ||||
-rw-r--r-- | packages/Shell/src/com/android/shell/BugreportWarningActivity.java | 12 |
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(); |