diff options
| author | 2015-06-16 16:59:47 +0000 | |
|---|---|---|
| committer | 2015-06-16 16:59:49 +0000 | |
| commit | a106554c20c72e284d64ea074933554e5dc29da9 (patch) | |
| tree | 4fe25787572b68aa5972f3dc49c9585c99d3bd99 | |
| parent | 7f92f06742fe3b66b9e8049db62ea55e1b41adf5 (diff) | |
| parent | 55beae09e57f987e23f8737d25c611a34fd7fc81 (diff) | |
Merge "Changed BugReportReceiver to send zipped bugreports." into mnc-dev
| -rw-r--r-- | packages/Shell/src/com/android/shell/BugreportReceiver.java | 140 | 
1 files changed, 118 insertions, 22 deletions
diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java index e1bfc4386de3..d299d66eda26 100644 --- a/packages/Shell/src/com/android/shell/BugreportReceiver.java +++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java @@ -33,11 +33,22 @@ 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 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 +84,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 +136,107 @@ 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) { +        byte[] bytes = read(bugreportFile); +        if (bytes == null) { +            // Could not read bugreport, return original. +            return bugreportFile; +        } +        String bugreportPath = bugreportFile.getAbsolutePath(); +        String zippedPath = bugreportPath.replace(".txt", ".zip"); +        Log.v(TAG, "zipping " + bugreportPath + " as " + zippedPath); +        File bugreportZippedFile = new File(zippedPath); +        try (ZipOutputStream zos = new ZipOutputStream( +                new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) { +            ZipEntry entry = new ZipEntry("bugreport.txt"); +            zos.putNextEntry(entry); +            zos.write(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. +        } +    } + +    /** Returns the content of file, or {@code null} in case of error. */ +    private static byte[] read(File file) { +        try (ByteArrayOutputStream output = new ByteArrayOutputStream(); +             InputStream input = new FileInputStream(file)) { +            byte[] buffer = new byte[4096]; +            int read = 0; +            while ((read = input.read(buffer)) != -1) { +              output.write(buffer, 0, read); +            } +            return output.toByteArray(); +        } catch (IOException e) { +            Log.e(TAG, "IOException reading " + file.getAbsolutePath(), e); +            return null; +        } +    } + +    /**       * Find the best matching {@link Account} based on build properties.       */      private static Account findSendToAccount(Context context) {  |