diff options
Diffstat (limited to 'packages/Shell/src/com/android/shell')
| -rw-r--r-- | packages/Shell/src/com/android/shell/BugreportReceiver.java | 122 |
1 files changed, 100 insertions, 22 deletions
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java index e1bfc43..13747ed 100644 --- a/packages/Shell/src/com/android/shell/BugreportReceiver.java +++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java @@ -33,11 +33,23 @@ import android.os.FileUtils; import android.os.SystemProperties; import android.support.v4.content.FileProvider; import android.text.format.DateUtils; +import android.util.Log; import android.util.Patterns; import com.google.android.collect.Lists; +import libcore.io.Streams; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import java.util.ArrayList; /** @@ -73,30 +85,14 @@ public class BugreportReceiver extends BroadcastReceiver { final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile); final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile); - Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri); - Intent notifIntent; - - // Send through warning dialog by default - if (getWarningState(context, STATE_SHOW) == STATE_SHOW) { - notifIntent = buildWarningIntent(context, sendIntent); + boolean isPlainText = bugreportFile.getName().toLowerCase().endsWith(".txt"); + if (!isPlainText) { + // Already zipped, send it right away. + sendBugreportNotification(context, bugreportFile, screenshotFile); } else { - notifIntent = sendIntent; + // Asynchronously zip the file first, then send it. + sendZippedBugreportNotification(context, bugreportFile, screenshotFile); } - notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - final Notification.Builder builder = new Notification.Builder(context) - .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) - .setContentTitle(context.getString(R.string.bugreport_finished_title)) - .setTicker(context.getString(R.string.bugreport_finished_title)) - .setContentText(context.getString(R.string.bugreport_finished_text)) - .setContentIntent(PendingIntent.getActivity( - context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT)) - .setAutoCancel(true) - .setLocalOnly(true) - .setColor(context.getColor( - com.android.internal.R.color.system_notification_accent_color)); - - NotificationManager.from(context).notify(TAG, 0, builder.build()); // Clean up older bugreports in background final PendingResult result = goAsync(); @@ -141,6 +137,88 @@ public class BugreportReceiver extends BroadcastReceiver { } /** + * Sends a bugreport notitication. + */ + private static void sendBugreportNotification(Context context, File bugreportFile, + File screenshotFile) { + // Files are kept on private storage, so turn into Uris that we can + // grant temporary permissions for. + final Uri bugreportUri = FileProvider.getUriForFile(context, AUTHORITY, bugreportFile); + final Uri screenshotUri = FileProvider.getUriForFile(context, AUTHORITY, screenshotFile); + + Intent sendIntent = buildSendIntent(context, bugreportUri, screenshotUri); + Intent notifIntent; + + // Send through warning dialog by default + if (getWarningState(context, STATE_SHOW) == STATE_SHOW) { + notifIntent = buildWarningIntent(context, sendIntent); + } else { + notifIntent = sendIntent; + } + notifIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + final Notification.Builder builder = new Notification.Builder(context) + .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) + .setContentTitle(context.getString(R.string.bugreport_finished_title)) + .setTicker(context.getString(R.string.bugreport_finished_title)) + .setContentText(context.getString(R.string.bugreport_finished_text)) + .setContentIntent(PendingIntent.getActivity( + context, 0, notifIntent, PendingIntent.FLAG_CANCEL_CURRENT)) + .setAutoCancel(true) + .setLocalOnly(true) + .setColor(context.getColor( + com.android.internal.R.color.system_notification_accent_color)); + + NotificationManager.from(context).notify(TAG, 0, builder.build()); + } + + /** + * Sends a zipped bugreport notification. + */ + private static void sendZippedBugreportNotification(final Context context, + final File bugreportFile, final File screenshotFile) { + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... params) { + File zippedFile = zipBugreport(bugreportFile); + sendBugreportNotification(context, zippedFile, screenshotFile); + return null; + } + }.execute(); + } + + /** + * Zips a bugreport file, returning the path to the new file (or to the + * original in case of failure). + */ + private static File zipBugreport(File bugreportFile) { + String bugreportPath = bugreportFile.getAbsolutePath(); + String zippedPath = bugreportPath.replace(".txt", ".zip"); + Log.v(TAG, "zipping " + bugreportPath + " as " + zippedPath); + File bugreportZippedFile = new File(zippedPath); + try (InputStream is = new FileInputStream(bugreportFile); + ZipOutputStream zos = new ZipOutputStream( + new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) { + ZipEntry entry = new ZipEntry("bugreport.txt"); + zos.putNextEntry(entry); + int totalBytes = Streams.copy(is, zos); + Log.v(TAG, "size of original bugreport: " + totalBytes + " bytes"); + zos.closeEntry(); + // Delete old file; + boolean deleted = bugreportFile.delete(); + if (deleted) { + Log.v(TAG, "deleted original bugreport (" + bugreportPath + ")"); + } else { + Log.e(TAG, "could not delete original bugreport (" + bugreportPath + ")"); + } + return bugreportZippedFile; + } catch (IOException e) { + Log.e(TAG, "exception zipping file " + zippedPath, e); + return bugreportFile; // Return original. + } + } + + /** * Find the best matching {@link Account} based on build properties. */ private static Account findSendToAccount(Context context) { |
